+ Tag Search : + vocaloid
+ + + Live(0) / + User(28) + + + + + + +






diff --git a/config.yaml b/config.yaml index 1e031f8..bf7f89d 100644 --- a/config.yaml +++ b/config.yaml @@ -1,3 +1,3 @@ database: - source_uri: "root:@tcp(127.0.0.1:4000)/intimate_source?parseTime=true&loc=Local" - extractor_uri: "root:@tcp(127.0.0.1:4000)/intimate_extractor?parseTime=true&loc=Local" \ No newline at end of file + source_uri: "root:@tcp(127.0.0.1:4000)/intimate_source?parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci" + extractor_uri: "root:@tcp(127.0.0.1:4000)/intimate_extractor?parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci" \ No newline at end of file diff --git a/extractor/openrec_extractor/openrec_extractor.go b/extractor/openrec_extractor/openrec_extractor.go index 3b689ad..41cf76d 100644 --- a/extractor/openrec_extractor/openrec_extractor.go +++ b/extractor/openrec_extractor/openrec_extractor.go @@ -87,7 +87,7 @@ func (oe *OpenrecExtractor) Execute() { streamer.UpdateTime = source.UpdateTime streamer.Tags = clog.Tags - clog.Platform = string(intimate.Popenrec) + clog.Platform = intimate.Popenrec clog.UserId = userId clog.UpdateTime = source.UpdateTime diff --git a/extractor/twitcasting_extractor/.gitignore b/extractor/twitcasting_extractor/.gitignore new file mode 100644 index 0000000..dea3a6c --- /dev/null +++ b/extractor/twitcasting_extractor/.gitignore @@ -0,0 +1,4 @@ +*.html +log +screenlog.* +twitcasting_extractor \ No newline at end of file diff --git a/extractor/twitcasting_extractor/twitcasting_extractor.go b/extractor/twitcasting_extractor/twitcasting_extractor.go new file mode 100644 index 0000000..0550e6a --- /dev/null +++ b/extractor/twitcasting_extractor/twitcasting_extractor.go @@ -0,0 +1,149 @@ +package main + +import ( + "database/sql" + "intimate" + "log" + "regexp" + "strconv" + "strings" + "time" + + "github.com/474420502/extractor" + "github.com/474420502/requests" +) + +// sstore 源存储实例, 为存储源数据的实现. 表格具体参考sql/intimate_source.sql +var sstore *intimate.StoreSource = intimate.NewStoreSource(string(intimate.STOpenrec)) + +// estore 解析存储连接实例 +var estore *intimate.StoreExtractor = intimate.NewStoreExtractor() + +type LiveData struct { + UserName string `exp:"//span[@class='tw-live-author__info-username']" method:"Text"` + Follower string `exp:"(//span[@class='tw-user-nav-list-count'])[2]" method:"Text"` + MaxViews string `exp:"//span[@id='max_viewer_count']" method:"Text"` + LiveTitle string `exp:"//meta[@property='og:title']" method:"AttributeValue,content"` + LiveStart string `exp:"//time[@data-kind='relative']" method:"AttributeValue,datetime"` + LiveDuration string `exp:"//span[@id='updatetimer']" method:"AttributeValue,data-duration"` + Tags []string `exp:"//div[@class='tw-live-author__commandbox--tags']//a[@class='tag tag-info']" method:"Text"` +} + +func main() { + + ps := intimate.NewPerfectShutdown() + ses := requests.NewSession() + + for !ps.IsClose() { + + streamer, err := estore.Pop(intimate.Ptwitcasting) + if err != nil { + log.Println(err, streamer.UserId) + } + + streamer.LiveUrl = sql.NullString{String: "https://twitcasting.tv/" + streamer.UserId, Valid: true} + resp, err := ses.Get(streamer.LiveUrl.String).Execute() + if err != nil { + estore.UpdateError(streamer, err) + log.Println(err, streamer.UserId) + continue + } + var ldata *LiveData + etor := extractor.ExtractXml(resp.Content()) + ldata = etor.GetObjectByTag(LiveData{}).(*LiveData) + ldata.MaxViews = regexp.MustCompile("\\d+").FindString(ldata.MaxViews) + coincount := 0 + + for i := 0; ; i++ { + + giverurl := streamer.LiveUrl.String + "/backers/" + strconv.Itoa(i) + resp, err = ses.Get(giverurl).Execute() + if err != nil { + log.Panic(err) + } + etor := extractor.ExtractXml(resp.Content()) + xp, err := etor.XPaths("//td[@class='tw-memorial-table-recent-point']") + if err != nil { + log.Panic(err) + } + + coins := xp.GetTexts() + for _, cointxt := range coins { + scointxt := strings.Split(cointxt, "/") + if len(scointxt) == 2 { + coin := strings.Trim(scointxt[1], " ") + c, err := strconv.Atoi(coin) + if err == nil { + coincount += c + } + // log.Println(coin, coincount) + } else { + log.Println("coin error: ", cointxt) + } + } + + if len(coins) < 20 { + break + } + } + + streamer.Platform = intimate.Ptwitcasting + streamer.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true} + streamer.UserName = sql.NullString{String: ldata.UserName, Valid: true} + streamer.Operator = 10 + // streamer.UpdateInterval = 60 + clog := &intimate.CollectLog{} + clog.UserId = streamer.UserId + clog.Gratuity = sql.NullInt64{Int64: int64(coincount), Valid: true} + clog.Platform = streamer.Platform + clog.UpdateTime = streamer.UpdateTime + clog.LiveTitle = sql.NullString{String: ldata.LiveTitle, Valid: true} + fl, err := intimate.ParseNumberEx(ldata.Follower) + if err == nil { + clog.Followers = sql.NullInt64{Int64: int64(fl), Valid: true} + switch { + case fl <= 100: + streamer.UpdateInterval = 360 + case fl <= 1000: + streamer.UpdateInterval = 240 + case fl <= 100: + streamer.UpdateInterval = 120 + default: + streamer.UpdateInterval = 60 + } + } else { + log.Println(err) + } + + views, err := strconv.Atoi(ldata.MaxViews) + if err == nil { + clog.Views = sql.NullInt64{Int64: int64(views), Valid: true} + } else { + clog.Views = sql.NullInt64{Int64: int64(0), Valid: true} + // log.Println(err, streamer.UserId) + } + + // st, err := strconv.Atoi(ldata.LiveStart) + st, err := time.Parse("Mon, 02 Jan 2006 15:04:05 -0700", ldata.LiveStart) + if err == nil { + startTime := st + clog.LiveStartTime = sql.NullTime{Time: startTime, Valid: true} + dt, err := strconv.Atoi(ldata.LiveDuration) + if time.Now().Sub(startTime) >= time.Hour*24*90 { + streamer.Operator = 5 + } + + if err == nil { + endTime := startTime.Add((time.Duration)(dt) * time.Millisecond) + clog.LiveEndTime = sql.NullTime{Time: endTime, Valid: true} + } else { + log.Println(err, streamer.UserId) + } + } else { + log.Println(err, streamer.UserId) + } + + streamer.LatestLogUid = estore.InsertClog(clog) + estore.UpdateStreamer(streamer) + } +} diff --git a/extractor/twitcasting_extractor/twitcasting_extractor_test.go b/extractor/twitcasting_extractor/twitcasting_extractor_test.go new file mode 100644 index 0000000..811b2d3 --- /dev/null +++ b/extractor/twitcasting_extractor/twitcasting_extractor_test.go @@ -0,0 +1,23 @@ +package main + +import ( + "testing" + "time" +) + +// type LiveData struct { +// UserName string `exp:".//span[@class='tw-live-author__info-username']" method:"Text"` +// Follower string `exp:".//span[@class='tw-user-nav-list-count']" method:"Text"` +// } + +func TestMain(t *testing.T) { + main() +} + +func TestDateFormat(t *testing.T) { + df := "Sat, 09 Sep 2017 18:19:17 +0900" + + if _, err := time.Parse("Mon, 02 Jan 2006 15:04:05 -0700", df); err != nil { + t.Error(err) + } +} diff --git a/extractor/twitch_extractor/tiwtch_extractor.go b/extractor/twitch_extractor/tiwtch_extractor.go index bd2c6cf..187ae3e 100644 --- a/extractor/twitch_extractor/tiwtch_extractor.go +++ b/extractor/twitch_extractor/tiwtch_extractor.go @@ -6,6 +6,7 @@ import ( "intimate" "log" "regexp" + "strings" "time" "github.com/tebeka/selenium" @@ -48,6 +49,7 @@ func main() { var updateUrl map[string]string json.Unmarshal(streamer.UpdateUrl.([]byte), &updateUrl) liveUrl := updateUrl["live"] + liveUrl = strings.Replace(liveUrl, "/watchparty", "", -1) log.Println(liveUrl) // err = wd.Get("https://www.twitch.tv/zoe_0601" + "/about") @@ -67,6 +69,13 @@ func main() { time.Sleep(time.Millisecond * 500) err = extractUserName(wd, streamer) if err != nil { + _, err = wd.FindElement(selenium.ByXPATH, "//a[@data-a-target='browse-channels-button']") + if err == nil { + log.Println(streamer.UserId, "may be cancell") + streamer.Operator = 5 + streamer.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true} + estore.UpdateStreamer(streamer) + } continue } err = extractFollowers(wd, clog) @@ -94,7 +103,7 @@ func main() { } streamer.Platform = intimate.Ptwitch - clog.Platform = string(streamer.Platform) + clog.Platform = streamer.Platform clog.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true} lastClogId := estore.InsertClog(clog) diff --git a/extractor_field.go b/extractor_field.go index ad5ef30..2977941 100644 --- a/extractor_field.go +++ b/extractor_field.go @@ -3,6 +3,7 @@ package intimate import ( "database/sql" "reflect" + "time" "github.com/474420502/hunter" "github.com/tidwall/gjson" @@ -11,6 +12,34 @@ import ( type GetSet struct { } +type StreamerList struct { + UrlHash []byte // + Platform Platform // + Url string // + + Label sql.NullString // + + Serialize interface{} + + UpdateInterval int32 + UpdateTime time.Time // + + ErrorMsg sql.NullString + Operator int32 + + LastOperator int32 +} + +// Get Simple Value +func (sl *StreamerList) Get(field string) interface{} { + return reflect.ValueOf(sl).Elem().FieldByName(field).Interface() +} + +// Set Simple Value +func (sl *StreamerList) Set(field string, value interface{}) { + reflect.ValueOf(sl).Elem().FieldByName(field).Set(reflect.ValueOf(value)) +} + type Streamer struct { Uid int64 // Platform Platform // @@ -49,7 +78,7 @@ type CollectLog struct { LogUid int64 // 日志id StreamerUid int64 // StreamerId 表id与 - Platform string // + Platform Platform // UserId string // 平台的UserId IsLiveStreaming bool // IsError bool // diff --git a/go.mod b/go.mod index d8b824d..35e0665 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module intimate go 1.14 require ( + github.com/474420502/extractor v0.5.2 github.com/474420502/focus v0.12.0 github.com/474420502/gcurl v0.1.2 github.com/474420502/hunter v0.3.4 diff --git a/go.sum b/go.sum index a556617..32dceb6 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,16 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= +github.com/474420502/extractor v0.5.1 h1:A1heJJSYbV9nEaUHfl3/1HYXcsBQfsTzAHikgwg2IF0= +github.com/474420502/extractor v0.5.1/go.mod h1:vkqsbi7wXPqyi5Q5dchcGjiaWHbgOJOAEcwonBiAs/E= +github.com/474420502/extractor v0.5.2 h1:ndgrAkxJjQg0Nrbq3AX2/xAnmIJNxSHRFGQ78wEtWj4= +github.com/474420502/extractor v0.5.2/go.mod h1:vkqsbi7wXPqyi5Q5dchcGjiaWHbgOJOAEcwonBiAs/E= github.com/474420502/focus v0.12.0 h1:+icbmj7IEOefvTegHt5EpcHt6WFbe2miIrceUJx2Evo= github.com/474420502/focus v0.12.0/go.mod h1:d0PMjtMxFz1a9HIhwyFPkWa+JF+0LgOrEUfd8iZka6s= github.com/474420502/gcurl v0.1.2 h1:ON9Yz3IgAdtDlFlHfkAJ3aIEBDxH0RiViPE5ST5ohKg= github.com/474420502/gcurl v0.1.2/go.mod h1:hws5q/Ao64bXLLDnldz9VyTQUndTWc/i5DzdEazFfoM= +github.com/474420502/htmlquery v1.2.4-0.20200810165859-a0e2c521c7c2 h1:4F1tpJ+sEkb3N+XD+Wb9MFiQmOMm3bHp8QUP+BQvkVk= +github.com/474420502/htmlquery v1.2.4-0.20200810165859-a0e2c521c7c2/go.mod h1:AoSN890esHwNKecV0tCs+W0ele1xgFL1Jqk6UcrdxgU= github.com/474420502/hunter v0.3.4 h1:fyLAgI84jWe3IcqsISC53j1w3CXI1FERxX//Potns0M= github.com/474420502/hunter v0.3.4/go.mod h1:pe4Xr/I+2agvq339vS/OZV+EiHAWtpXQs75rioSW9oA= github.com/474420502/requests v1.6.0 h1:f4h4j40eT0P5whhg9LdkotD8CaKjtuDu/vz9iSUkCgY= @@ -20,6 +26,8 @@ github.com/Pallinder/go-randomdata v1.1.0 h1:gUubB1IEUliFmzjqjhf+bgkg1o6uoFIkRsP github.com/Pallinder/go-randomdata v1.1.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y= github.com/Pallinder/go-randomdata v1.2.0 h1:DZ41wBchNRb/0GfsePLiSwb0PHZmT67XY00lCDlaYPg= github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y= +github.com/antchfx/xpath v1.1.6 h1:6sVh6hB5T6phw1pFpHRQ+C4bd8sNI+O58flqtg7h0R0= +github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -36,6 +44,8 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -66,6 +76,8 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tebeka/selenium v0.9.9 h1:cNziB+etNgyH/7KlNI7RMC1ua5aH1+5wUlFQyzeMh+w= github.com/tebeka/selenium v0.9.9/go.mod h1:5Fr8+pUvU6B1OiPfkdCKdXZyr5znvVkxuPd0NOdZCQc= github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -103,6 +115,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -162,6 +175,8 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= diff --git a/platform_list.go b/platform_list.go index 0bdefc0..246e991 100644 --- a/platform_list.go +++ b/platform_list.go @@ -9,4 +9,7 @@ const ( // Ptwitch twitch 平台 Ptwitch Platform = "twitch" + + // Ptwitcasting twitcasting 平台 + Ptwitcasting Platform = "twitcasting" ) diff --git a/sql/intimate_extractor.sql b/sql/intimate_extractor.sql index 91d3e3b..e8ccc1c 100644 --- a/sql/intimate_extractor.sql +++ b/sql/intimate_extractor.sql @@ -1,6 +1,25 @@ create database if not exists `intimate_extractor`; use intimate_extractor; +CREATE TABLE IF NOT EXISTS `streamer_list` ( + `urlhash` varchar(32) NOT NULL COMMENT '平台', + `url` text COMMENT 'url获取streamer列表的url', + `platform` varchar(255) NOT NULL COMMENT '平台', + `label` varchar(255) DEFAULT NULL COMMENT '必须的时候打上标签', + `serialize` blob DEFAULT NULL COMMENT '保存进程的必要计算数据', + + `update_interval` int DEFAULT 120 COMMENT '分钟单位, 默认120分钟, 下次更新的时间间隔', + `update_time` Timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + `error_msg` text DEFAULT NULL COMMENT '错误信息', + `operator` int DEFAULT 0 COMMENT '操作标志位, 根据不同解析方法有不同标志', + + PRIMARY KEY (`urlhash`), + KEY `platform_idx` (`platform`), + KEY `update_time_idx` (`update_time`), + KEY `operator_idx` (`operator`) +) + CREATE TABLE IF NOT EXISTS `streamer` ( `uid` bigint AUTO_INCREMENT COMMENT '自增UID, 便于查询定位', `platform` varchar(255) NOT NULL COMMENT '平台', diff --git a/store.go b/store.go index cbdbbfc..da79aa2 100644 --- a/store.go +++ b/store.go @@ -1,8 +1,11 @@ package intimate import ( + "crypto/md5" "database/sql" + "fmt" "log" + "strings" "time" _ "github.com/go-sql-driver/mysql" @@ -182,6 +185,9 @@ const StreamerTable string = "streamer" // CollectLogTable 采集日志表 const CollectLogTable string = "collect_log" +// StreamerListTable 主播表名称 +const StreamerListTable string = "streamer_list" + type StoreExtractor struct { db *sql.DB @@ -267,6 +273,48 @@ func (store *StoreExtractor) Pop(platform Platform, operators ...int32) (*Stream return s, nil } +// UpdateStreamerList streamerlist表, 更新数据 +func (store *StoreExtractor) UpdateStreamerList(streamer IGet, fieldvalues ...interface{}) { + updateSQL := "UPDATE " + StreamerListTable + " SET " + var values []interface{} + for i := 0; i < len(fieldvalues); i += 2 { + field := fieldvalues[i] + values = append(values, fieldvalues[i+1]) + updateSQL += field.(string) + " = ? " + } + updateSQL += "WHERE urlhash = ?" + values = append(values, streamer.Get("UrlHash")) + _, err := store.db.Exec(updateSQL, values...) + if err != nil { + panic(err) + } +} + +// InsertStreamer streamerlist表, 插入数据 +func (store *StoreExtractor) InsertStreamerList(streamerlist IGet) (isExists bool) { + urlstr := streamerlist.Get("Url").(string) + + _, err := store.db.Exec("insert into streamer_list(urlhash, url, platform, label, serialize, update_interval, error_msg, operator) values(?,?,?,?,?,?,?,?)", + fmt.Sprintf("%x", md5.Sum([]byte(urlstr))), + urlstr, + streamerlist.Get("Platform"), + streamerlist.Get("Label"), + streamerlist.Get("Serialize"), + streamerlist.Get("UpdateInterval"), + streamerlist.Get("ErrorMsg"), + streamerlist.Get("Operator"), + ) + + if err != nil { + if !strings.HasPrefix(err.Error(), "Error 1062") { + log.Println(err) + } + return true + } + + return false +} + // InsertStreamer Streamer表, 插入数据 func (store *StoreExtractor) InsertStreamer(streamer IGet) (isExists bool) { // select uid from table where platform = ? and user_id = ? @@ -298,7 +346,7 @@ func (store *StoreExtractor) InsertStreamer(streamer IGet) (isExists bool) { return true } - _, err = tx.Exec("INSERT INTO "+StreamerTable+"(platform, user_id, update_url, update_time) VALUES(?,?,?,?);", streamer.Get("Platform"), streamer.Get("UserId"), streamer.Get("UpdateUrl"), time.Now().Add(-time.Minute*60)) + _, err = tx.Exec("INSERT INTO "+StreamerTable+"(platform, user_id, update_url, tags, update_time) VALUES(?,?,?,?,?);", streamer.Get("Platform"), streamer.Get("UserId"), streamer.Get("UpdateUrl"), streamer.Get("Tags"), time.Now().Add(-time.Hour*100000)) if err != nil { panic(err) } diff --git a/table_list.go b/table_list.go index 04002dc..cb12c70 100644 --- a/table_list.go +++ b/table_list.go @@ -9,4 +9,7 @@ const ( // STTwitch twitch源table名称 STTwitch SourceTable = "source_twitch" + + // STTwitcasting STTwitcasting源table名称 + STTwitcasting SourceTable = "source_twitcasting" ) diff --git a/tasks/twitcasting/twitcasting_task1/.gitignore b/tasks/twitcasting/twitcasting_task1/.gitignore new file mode 100644 index 0000000..de4f65a --- /dev/null +++ b/tasks/twitcasting/twitcasting_task1/.gitignore @@ -0,0 +1,2 @@ +twitcasting_task1 +log \ No newline at end of file diff --git a/tasks/twitcasting/twitcasting_task1/error.html b/tasks/twitcasting/twitcasting_task1/error.html new file mode 100755 index 0000000..3a41b64 --- /dev/null +++ b/tasks/twitcasting/twitcasting_task1/error.html @@ -0,0 +1,991 @@ + + +
+