You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
6.2 KiB
261 lines
6.2 KiB
package service |
|
|
|
import ( |
|
"bytes" |
|
"context" |
|
"encoding/csv" |
|
"fmt" |
|
"io/ioutil" |
|
"math/big" |
|
"net" |
|
"net/http" |
|
"regexp" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/admin/main/dm/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
"go-common/library/xstr" |
|
) |
|
|
|
var ( |
|
_csvTaskTitle = []string{"dmid", "oid", "mid", "state", "msg", "ip", "ctime"} |
|
) |
|
|
|
// TaskList . |
|
func (s *Service) TaskList(c context.Context, v *model.TaskListArg) (res *model.TaskList, err error) { |
|
taskSQL := make([]string, 0) |
|
if v.Creator != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("creator LIKE %q", "%"+v.Creator+"%")) |
|
} |
|
if v.Reviewer != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("reviewer LIKE %q", "%"+v.Reviewer+"%")) |
|
} |
|
if v.State >= 0 { |
|
taskSQL = append(taskSQL, fmt.Sprintf("state=%d", v.State)) |
|
} |
|
if v.Title != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("title LIKE %q", "%"+v.Title+"%")) |
|
} |
|
if v.Ctime != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("ctime>=%q", v.Ctime)) |
|
} |
|
tasks, total, err := s.dao.TaskList(c, taskSQL, v.Pn, v.Ps) |
|
if err != nil { |
|
return |
|
} |
|
res = &model.TaskList{ |
|
Result: tasks, |
|
Page: &model.PageInfo{ |
|
Num: v.Pn, |
|
Size: v.Ps, |
|
Total: total, |
|
}, |
|
} |
|
return |
|
} |
|
|
|
// AddTask . |
|
func (s *Service) AddTask(c context.Context, v *model.AddTaskArg) (err error) { |
|
var taskID int64 |
|
var sub int32 |
|
tx, err := s.dao.BeginBiliDMTrans(c) |
|
if err != nil { |
|
log.Error("tx.BeginBiliDMTrans error(%v)", err) |
|
return |
|
} |
|
defer func() { |
|
if err != nil { |
|
if err1 := tx.Rollback(); err1 != nil { |
|
log.Error("tx.Rollback() error(%v)", err1) |
|
} |
|
return |
|
} |
|
if err = tx.Commit(); err != nil { |
|
log.Error("tx.Commit() error(%v)", err) |
|
} |
|
}() |
|
if v.Regex != "" { |
|
if len([]rune(v.Regex)) > model.TaskRegexLen { |
|
err = ecode.DMTaskRegexTooLong |
|
return |
|
} |
|
if _, err = regexp.Compile(v.Regex); err != nil { |
|
log.Error("regexp.Compile(v.Regex:%s) error(%v)", v.Regex, err) |
|
err = ecode.DMTaskRegexIllegal |
|
return |
|
} |
|
} |
|
if v.Operation >= 0 { |
|
sub = 1 |
|
} |
|
if taskID, err = s.dao.AddTask(tx, v, sub); err != nil { |
|
return |
|
} |
|
if sub > 0 { |
|
_, err = s.dao.AddSubTask(tx, taskID, v.Operation, v.OpTime, v.OpRate) |
|
} |
|
return |
|
} |
|
|
|
// ReviewTask . |
|
func (s *Service) ReviewTask(c context.Context, v *model.ReviewTaskArg) (err error) { |
|
if v.State == model.TaskReviewPass { |
|
var ( |
|
task *model.TaskView |
|
sTime, eTime time.Time |
|
) |
|
if task, err = s.dao.TaskView(c, v.ID); err != nil { |
|
return |
|
} |
|
taskSQL := make([]string, 0) |
|
if task.Regex != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.msg regexp %q", task.Regex)) |
|
} |
|
if task.KeyWords != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.msg like %q", "%"+task.KeyWords+"%")) |
|
} |
|
if task.IPs != "" { |
|
ips := xstr.JoinInts(ipsToInts(task.IPs)) |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.ip in (%s)", ips)) |
|
} |
|
if task.Mids != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("index.mid in (%s)", task.Mids)) |
|
} |
|
if task.Cids != "" { |
|
taskSQL = append(taskSQL, fmt.Sprintf("index.oid in (%s)", task.Cids)) |
|
} |
|
if task.Start != "" { |
|
if sTime, err = time.ParseInLocation("2006-01-02 15:04:05", task.Start, time.Local); err != nil { |
|
return |
|
} |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.log_date>=%s", sTime.Format("20060102"))) |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.ctime>=%q", task.Start)) |
|
} |
|
if task.End != "" { |
|
if eTime, err = time.ParseInLocation("2006-01-02 15:04:05", task.End, time.Local); err != nil { |
|
return |
|
} |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.log_date<=%s", eTime.Format("20060102"))) |
|
taskSQL = append(taskSQL, fmt.Sprintf("content.ctime<=%q", task.End)) |
|
} |
|
if v.Topic, err = s.dao.SendTask(c, taskSQL); err != nil { |
|
// err = nil |
|
// v.State = model.TaskStateFailed |
|
return |
|
} |
|
} |
|
_, err = s.dao.ReviewTask(c, v) |
|
return |
|
} |
|
|
|
// EditTaskState . |
|
func (s *Service) EditTaskState(c context.Context, v *model.EditTasksStateArg) (err error) { |
|
if _, err = s.dao.EditTaskState(c, v); err != nil { |
|
return |
|
} |
|
if v.State == model.TaskStateRun { |
|
_, err = s.dao.EditTaskPriority(c, v.IDs, time.Now().Unix()) |
|
} |
|
return |
|
} |
|
|
|
// TaskView . |
|
func (s *Service) TaskView(c context.Context, v *model.TaskViewArg) (task *model.TaskView, err error) { |
|
if task, err = s.dao.TaskView(c, v.ID); err != nil || task == nil { |
|
return |
|
} |
|
if task.SubTask, err = s.dao.SubTask(c, task.ID); err != nil || task.SubTask == nil { |
|
return |
|
} |
|
task.Tcount = task.SubTask.Tcount |
|
return |
|
} |
|
|
|
// TaskCsv . |
|
func (s *Service) TaskCsv(c context.Context, id int64) (bs []byte, err error) { |
|
var ( |
|
task *model.TaskView |
|
buf *bytes.Buffer |
|
csvWriter *csv.Writer |
|
) |
|
if task, err = s.dao.TaskView(c, id); err != nil { |
|
return |
|
} |
|
if task == nil || len(task.Result) == 0 { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
res, err := http.Get(task.Result) |
|
if err != nil { |
|
log.Error("s.HttpGet(%s) error(%v)", task.Result, err) |
|
return |
|
} |
|
defer res.Body.Close() |
|
if res.StatusCode != http.StatusOK { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
resp, err := ioutil.ReadAll(res.Body) |
|
if err != nil { |
|
log.Error("s.ioutilRead error(%v)", err) |
|
return |
|
} |
|
buf = &bytes.Buffer{} |
|
csvWriter = csv.NewWriter(buf) |
|
if err = csvWriter.Write(_csvTaskTitle); err != nil { |
|
log.Error("csvWriter.Write(%v) erorr(%v)", _csvTaskTitle, err) |
|
return |
|
} |
|
lines := bytes.Split(resp, []byte("\n")) |
|
if len(lines) == 0 { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
for _, line := range lines { |
|
var ( |
|
items []string |
|
) |
|
fields := bytes.Split(line, []byte("\001")) |
|
if len(fields) < 7 { |
|
log.Error("fields lenth too small:%d", len(fields)) |
|
continue |
|
} |
|
for _, field := range fields { |
|
items = append(items, string(field)) |
|
} |
|
if err = csvWriter.Write(items); err != nil { |
|
log.Error("csvWriter.Write(%v) erorr(%v)", items, err) |
|
return |
|
} |
|
} |
|
csvWriter.Flush() |
|
if err = csvWriter.Error(); err != nil { |
|
log.Error("csvWriter.Error(%v)", err) |
|
return |
|
} |
|
bs = buf.Bytes() |
|
if len(bs) == 0 { |
|
err = ecode.NothingFound |
|
} |
|
return |
|
} |
|
|
|
func ipsToInts(ips string) (ipInts []int64) { |
|
ipStrs := strings.Split(ips, ",") |
|
ipInts = make([]int64, 0, len(ipStrs)) |
|
for _, ipStr := range ipStrs { |
|
ipInts = append(ipInts, ipToInt(ipStr)) |
|
} |
|
return |
|
} |
|
|
|
func ipToInt(ip string) (ipInt int64) { |
|
ret := big.NewInt(0) |
|
if net.ParseIP(ip) == nil { |
|
return |
|
} |
|
ret.SetBytes(net.ParseIP(ip).To4()) |
|
return ret.Int64() |
|
}
|
|
|