// GetAlbum returns a pointer to Album // // Notice: Once getting special albums' titles such as "Bảng Xếp Hạng Bài Hát Hàn Quốc ...", // the albums will be discarded because album.Nsongs and album.Songids.Length() do not match. func GetAlbum(id dna.Int) (*Album, error) { var album *Album = NewAlbum() album.Id = id album.Key = GetKey(id) c := make(chan bool, 2) go func() { c <- <-getAlbumFromMainPage(album) }() go func() { c <- <-getAlbumFromAPI(album) }() for i := 0; i < 2; i++ { <-c } if album.Nsongs != album.Songids.Length() { return nil, errors.New(dna.Sprintf("Zing - Album %v: Songids and Nsongs do not match", album.Id).String()) } else if album.Nsongs == 0 && album.Songids.Length() == 0 { return nil, errors.New(dna.Sprintf("Zing - Album %v: No song found", album.Id).String()) } else { album.Checktime = time.Now() return album, nil } }
// GetVideo returns a video or an error // // Direct link: // curl 'http://hcm.nhac.vui.vn/ajax/nghe_bai_hat/download_320k/472092' -H 'Cookie: pageCookie=13; ACCOUNT_ID=965257; token=3f363de2c081a3a3a685b1033e6f03b1%7C52ab4c37;' -v func GetVideo(id dna.Int) (*Video, error) { var video *Video = NewVideo() video.Id = id c := make(chan bool, 2) go func() { c <- <-getVideoXML(video) }() go func() { c <- <-getVideoFromMainPage(video) }() for i := 0; i < 2; i++ { <-c } // Check how many bits in ResolutionFlags have value 1 var count uint32 = 0 for i := uint32(0); i < 5; i++ { if (int(video.ResolutionFlags)>>i)&1 == 1 { count += 1 } } if video.Links.Length() == 0 { return nil, errors.New(dna.Sprintf("Chacha - Video %v: Link not found", video.Id).String()) } else if dna.Int(count) != video.Links.Length() { return nil, errors.New(dna.Sprintf("Chacha - Video %v: Video Resolution flags and links do not match", video.Id).String()) } else { video.Checktime = time.Now() return video, nil } }
func (song *Song) CSVRecord() []string { return []string{ song.Id.ToString().String(), song.Key.String(), song.Title.String(), dna.Sprintf("%#v", song.Artists).Replace("dna.StringArray", "").String(), dna.Sprintf("%#v", song.Topics).Replace("dna.StringArray", "").String(), song.LinkKey.String(), song.Type.String(), song.Bitrate.ToString().String(), song.Official.String(), song.Likes.ToString().String(), song.Plays.ToString().String(), song.LinkShare.String(), song.StreamUrl.String(), song.Image.String(), song.Coverart.String(), song.Duration.ToString().String(), song.Linkdown.String(), song.LinkdownHQ.String(), song.Lyricid.ToString().String(), song.HasLyric.String(), song.Lyric.String(), song.LyricStatus.ToString().String(), song.HasLrc.String(), song.Lrc.String(), song.LrcUrl.String(), song.UsernameCreated.String(), song.Checktime.Format("2006-01-02 15:04:05"), } }
// GetEpisole returns an episole URL of a series. func (urlb *URLBuilder) GetEpisole(movieid, ep dna.Int) dna.String { str := dna.Sprintf("movieid=%v&accesstokenkey=%v&ep=%v", movieid, ACCESS_TOKEN_KEY, ep) data := []byte(str.String()) strBase64 := base64.StdEncoding.EncodeToString(data) sign := getMD5(dna.String(strBase64) + SECRET_KEY) return dna.Sprintf("%vmovieid=%v&accesstokenkey=%v&ep=%v&sign=%v", BASE_URL, movieid, ACCESS_TOKEN_KEY, ep, sign) }
// GetAlbum returns a album or an error // * id: A unique id of a album // * Returns a found album or an error func GetAlbum(id dna.Int) (*Album, error) { var album *Album = NewAlbum() album.Id = id c := make(chan bool, 1) go func() { c <- <-getAPIAlbumC(album) }() for i := 0; i < 1; i++ { <-c } if album.Coverart != "" { <-getAlbumFromMainPage(album) } switch { case album.Id == 0: return nil, errors.New(dna.Sprintf("NCT - Album ID: %v not found", id).String()) case album.Coverart == "": return nil, errors.New(dna.Sprintf("NCT - Album ID: %v, Key: %v coverart not found", id, album.Key).String()) case album.Nsongs == 0: return nil, errors.New(dna.Sprintf("NCT - Album ID: %v, Key: %v songs not found", id, album.Key).String()) default: return album, nil } }
//CSVRecord returns a record to write csv format. // //psql -c "COPY sfsongs (id,track_group_id,amg,title,albumid,artistids,artists,url_slug,is_instrumental,viewable,duration,lyricid,has_lrc,has_lyric,track_number,disc_number,rating,lrc,link,lyric,copyright,writer,submitted_lyric,checktime) FROM '/Users/daonguyenanbinh/Box Documents/Sites/golang/sfsongs.csv' DELIMITER ',' CSV" func (song *Song) CSVRecord() []string { return []string{ song.Id.ToString().String(), song.TrackGroupId.ToString().String(), song.AMG.ToString().String(), song.Title.String(), song.Albumid.ToString().String(), dna.Sprintf("%#v", song.Artistids).Replace("dna.IntArray", "").String(), dna.Sprintf("%#v", song.Artists).Replace("dna.StringArray", "").String(), song.UrlSlug.String(), song.IsInstrumental.String(), song.Viewable.String(), song.Duration.ToString().String(), song.Lyricid.ToString().String(), song.HasLrc.String(), song.HasLyric.String(), song.TrackNumber.ToString().String(), song.DiscNumber.ToString().String(), dna.Sprintf("%#v", song.Rating).Replace("dna.IntArray", "").String(), song.Lrc.String(), song.Link.String(), song.Lyric.String(), song.Copyright.String(), song.Writer.String(), song.SubmittedLyric.String(), song.Checktime.Format("2006-01-02 15:04:05"), } }
// GetChannel returns TV channel URL. func (urlb *URLBuilder) GetChannel(channelid dna.Int) dna.String { str := dna.Sprintf("channelid=%v&accesstokenkey=%v", channelid, ACCESS_TOKEN_KEY) data := []byte(str.String()) strBase64 := base64.StdEncoding.EncodeToString(data) sign := getMD5(dna.String(strBase64) + SECRET_KEY) return dna.Sprintf("%vchannelid=%v&accesstokenkey=%v&sign=%v", CHANNEL_BASE_URL, channelid, ACCESS_TOKEN_KEY, sign) }
func (hg *HourGlass) Show(message dna.String) { hg.lastLapDuration += hg.lap() if hg.lastLapDuration >= time.Second/2 { fmtClock := dna.Sprintf("%v", hg.GetRemainingTime()/time.Millisecond*time.Millisecond) format := dna.Sprintf("%v %v", message, fmtClock) hg.console.Erase(Line).Column(0) hg.console.Write(format) hg.lastLapDuration = 0 } }
// Show displays a message if lap is greater than 500 milliseconds func (sw *StopWatch) Show(message dna.String) { sw.lastLapDuration += sw.Lap() if sw.lastLapDuration >= time.Second/2 { fmtClock := dna.Sprintf("%v", sw.Tick()/time.Millisecond*time.Millisecond) format := dna.Sprintf("%v %v", message, fmtClock) sw.console.Erase(Line).Column(0) sw.console.Write(format).HideCursor() sw.lastLapDuration = 0 } }
func (c Counter) String() string { c.mu.RLock() if c.Total > 0 { format := dna.String("%v✘ | %v✔") return string(dna.Sprintf(format, c.Fail, c.Pass)) } else { format := dna.String("t:%v|n:%v|f:%v✘|p:%v✔|v:%v") return string(dna.Sprintf(format, getTimeFmt(c.ElapsedTime), c.Count, c.Fail, c.Pass, c.Speed)) } c.mu.RUnlock() return "" }
func (song *Song) CSVRecord() []string { return []string{ song.Id.ToString().String(), song.Title.String(), dna.Sprintf("%#v", song.Artistids).Replace("dna.IntArray", "").String(), dna.Sprintf("%#v", song.Artists).Replace("dna.StringArray", "").String(), song.Albumid.ToString().String(), dna.Sprintf("%#v", song.Composerids).Replace("dna.IntArray", "").String(), dna.Sprintf("%#v", song.Composers).Replace("dna.StringArray", "").String(), song.Duration.ToString().String(), } }
//CSVRecord returns a record to write csv format. // //psql -c "COPY sfartists (id,amg,name,genres,url_slug,image,rating,bio,checktime) FROM '/Users/daonguyenanbinh/Box Documents/Sites/golang/sfartists.csv' DELIMITER ',' CSV" func (artist *Artist) CSVRecord() []string { return []string{ artist.Id.ToString().String(), artist.AMG.ToString().String(), artist.Name.String(), dna.Sprintf("%#v", artist.Genres).Replace("dna.StringArray", "").String(), artist.UrlSlug.String(), artist.Image.String(), dna.Sprintf("%#v", artist.Rating).Replace("dna.IntArray", "").String(), artist.Bio.String(), artist.Checktime.Format("2006-01-02 15:04:05"), } }
func (award *Award) CSVRecord() []string { return []string{ award.Id.ToString().String(), award.Title.String(), award.Albumid.ToString().String(), award.Section.String(), award.Year.ToString().String(), award.Chart.String(), award.Peak.ToString().String(), award.Type.ToString().String(), award.Prize.String(), dna.Sprintf("%#v", award.Winnerids).Replace("dna.IntArray", "").String(), dna.Sprintf("%#v", award.Winners).Replace("dna.StringArray", "").String(), } }
// getSongPlays returns song plays func getSongPlays(song *Song, body dna.String) { // POST METHOD // link := "http://www.nhaccuatui.com/interaction/api/hit-counter?jsoncallback=nct" // http.DefaulHeader.Set("Content-Type", "application/x-www-form-urlencoded ") // result, err := http.Post(dna.String(link), body) // // Log(link) // if err == nil { // data := &result.Data // tpl := dna.String(`{"counter":([0-9]+)}`) // playsArr := data.FindAllStringSubmatch(tpl, -1) // if len(playsArr) > 0 { // song.Plays = playsArr[0][1].ToInt() // } // } // GET METHOD link := "http://www.nhaccuatui.com/interaction/api/counter?jsoncallback=nct&listSongIds=" + song.Id.ToString() result, err := http.Get(link) if err == nil { data := &result.Data tpl := dna.Sprintf(`{"%v":([0-9]+)}`, song.Id) // dna.Log(data) playsArr := data.FindAllStringSubmatch(tpl, -1) if len(playsArr) > 0 { song.Plays = playsArr[0][1].ToInt() } } }
// GetSong returns a song or an error // // Direct link: // curl 'http://hcm.nhac.vui.vn/ajax/nghe_bai_hat/download_320k/472092' -H 'Cookie: pageCookie=13; ACCOUNT_ID=965257; token=3f363de2c081a3a3a685b1033e6f03b1%7C52ab4c37;' -v func GetSong(id dna.Int) (*Song, error) { var song *Song = NewSong() song.Id = id c := make(chan bool, 2) go func() { c <- <-getSongXML(song) }() go func() { c <- <-getSongFromMainPage(song) }() for i := 0; i < 2; i++ { <-c } if song.Type == "video" { song.Link = "" FoundVideos.Push(song.Id) } if song.Link == "" { return nil, errors.New(dna.Sprintf("Nhacvui - Song %v: Mp3 link not found", song.Id).String()) } else { song.Checktime = time.Now() return song, nil } }
// GetSong returns a song or an error from a song id. func GetSong(id dna.Int) (*Song, error) { var song *Song = NewSong() song.Id = id c := make(chan bool, 2) go func() { c <- <-getAPISongC(song) }() go func() { c <- <-getAPISongLyricC(song) }() for i := 0; i < 2; i++ { <-c } if song.Key != "" { <-getSongFromMainPage(song) } // getSongPlays(song) if song.Id == 0 { return nil, errors.New(dna.Sprintf("NCT - Song ID %v not found!", id).String()) } else { return song, nil } }
// UpdateSongFreaks gets lastest songs,albums,artists and videos from songfreaks.com // The update process goes through 4 steps: // Step 1: Initalizing db connection, loading site config and state handler. // Step 2: Finding new songs, insert new albums,artists and videos if found. // Step 3: Updating found new albums in Step 2. // Step 4: Recovering failed sql statements in Step 2. func UpdateSongFreaks() { db, err := sqlpg.Connect(sqlpg.NewSQLConfig(SqlConfigPath)) dna.PanicError(err) siteConf, err := LoadSiteConfig("sf", SiteConfigPath) siteConf.NConcurrent = 20 dna.PanicError(err) // Update new songs state := NewStateHandler(new(sf.APISongFreaksTrack), siteConf, db) state.TableName = "sfsongs" Update(state) // Update "ratings", "songids", "review_author", "review" of song ids := &[]dna.Int{} query := dna.Sprintf("SELECT id FROM sfalbums where checktime > '%v' AND array_length(songids, 1) is NULL", time.Now().Format("2006-01-02")) // dna.Log(query) err = db.Select(ids, query) if err != nil { dna.PanicError(err) } idsSlice := dna.IntArray(*ids) if idsSlice.Length() > 0 { state = NewStateHandlerWithExtSlice(new(sf.APISongFreaksAlbum), &idsSlice, siteConf, db) Update(state) } else { dna.Log("No new albums found") } // Recover failed sql statements RecoverErrorQueries(SqlErrorLogPath, db) CountDown(3*time.Second, QuittingMessage, EndingMessage) db.Close() }
// Update updates statement from GetUpdateStatment and returns error if available // // * structValue : A struct-typed value being scanned. Its fields have to be dna basic type or time.Time. // * conditionColumn : A snake-case column name in the condition, usually it's an id // * columns : A list of args of column names in the table being updated. // * Returns an update statement. // The error format is: // Error description - $$$error$$$SQL_QUERY$$$error$$$ // Sql query is enclosed by `$$$error$$$` func (db *DB) Update(structValue interface{}, conditionColumn dna.String, columns ...dna.String) error { tbName := GetTableName(structValue) updateQuery, err0 := GetUpdateStatement(tbName, structValue, conditionColumn, columns...) if err0 != nil { str := dna.Sprintf("%s - $$$error$$$%v$$$error$$$", err0.Error(), updateQuery).String() return errors.New(str) } else { _, err := db.Exec(updateQuery.String()) if err != nil { str := dna.Sprintf("%s - $$$error$$$%v$$$error$$$", err.Error(), updateQuery).String() return errors.New(str) } else { return nil } } }
// GetSong returns a song or an error func GetSong(id dna.Int) (*Song, error) { var song *Song = NewSong() song.Id = id song.Key = GetKey(id) c := make(chan bool, 3) go func() { c <- <-getSongLyricFromApi(song) }() go func() { c <- <-getSongFromXML(song) }() go func() { // Note: in the case the API is deprecated, // please use func getSongFromMainPage() to get info directly from main page. c <- <-getSongFromApi(song) }() for i := 0; i < 3; i++ { <-c } if song.Link == "" { return nil, errors.New(dna.Sprintf("Zing - Song %v: Mp3 link not found", song.Id).String()) } else { song.Checktime = time.Now() return song, nil } }
// GetAPIAlbum returns an album or an error from API using POST method. // // The SOAP data has the following format: // // <?xml version="1.0" encoding="utf-8"?> // <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> // <soap:Header/> // <soap:Body> // <tem:getAlbum_v2 xmlns=" http://tempuri.org/ "> // <tem:token></tem:token> // <tem:id>86682</tem:id> // <tem:identify></tem:identify> // </tem:getAlbum_v2> // </soap:Body> // </soap:Envelope> func GetAPIAlbum(id dna.Int) (*APIAlbum, error) { if id == 0 { return nil, errors.New("Id is zero") } var dat dna.String = dna.Sprintf(`<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"><soap:Header/><soap:Body> <tem:getAlbum_v2 xmlns=" http://tempuri.org/ "><tem:token></tem:token><tem:id>%v</tem:id><tem:identify></tem:identify></tem:getAlbum_v2></soap:Body> </soap:Envelope>`, id) header := Header header.Set("SOAPAction", "http://tempuri.org/getAlbum_v2") ret, err := Post("http://service.keeng.vn/appwebservice/Service.asmx?wsdl", header, dat) if err != nil { return nil, err } else { var apiStatusAlbum APIStatusAlbum dataArr := ret.Data.FindAllStringSubmatch(`<return>(.+)</return>`, -1) if len(dataArr) > 0 { // dna.Log(data) err := json.Unmarshal([]byte(dataArr[0][1].DecodeHTML()), &apiStatusAlbum) if err != nil { return nil, err } else { return &apiStatusAlbum.Data, nil } } else { return nil, errors.New("No return value") } } }
// GetAPIArtistVideos returns a list of albums of an artist or an error from API using POST method. // // The SOAP data has the following format: // // <?xml version="1.0" encoding="utf-8"?> // <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> // <soap:Header/> // <soap:Body> // <tem:getSinger_Detail_moi xmlns=" http://tempuri.org/ "> // <tem:token></tem:token> // <tem:singerid>1394</tem:singerid> // <tem:page>1</tem:page> // <tem:num>10</tem:num> // <tem:type>3</tem:type> // </tem:getSinger_Detail_moi> // </soap:Body> // </soap:Envelope> // // The params: // // *singerid : an artist id // *type : 3 // *page : current page for pagination // *num : the number of items per page // *token : empty func GetAPIArtistVideos(id, page, num dna.Int) (*APIArtistVideos, error) { if id == 0 { return nil, errors.New("Id is zero") } var dat dna.String = dna.Sprintf(`<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"><soap:Header/><soap:Body> <tem:getSinger_Detail_moi xmlns=" http://tempuri.org/ "><tem:token></tem:token><tem:singerid>%v</tem:singerid><tem:page>%v</tem:page><tem:num>%v</tem:num><tem:type>3</tem:type></tem:getSinger_Detail_moi></soap:Body> </soap:Envelope>`, id, page, num) header := Header header.Set("SOAPAction", "http://tempuri.org/getSinger_Detail_moi") ret, err := Post("http://service.keeng.vn/appwebservice/Service.asmx?wsdl", header, dat) if err != nil { return nil, err } else { var apiArtistVideos APIArtistVideos data := ret.Data.FindAllStringSubmatch(`<return>(.+)</return>`, -1)[0][1].DecodeHTML() // dna.Log(data) err := json.Unmarshal([]byte(data), &apiArtistVideos) if err != nil { return nil, err } else { return &apiArtistVideos, nil } } }
// GetAPILyric returns a lyric or an error from API using POST method. // // The SOAP data has the following format: // // <?xml version="1.0" encoding="utf-8"?> // <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> // <soap:Header/> // <soap:Body> // <tem:getLyric xmlns=" http://tempuri.org/ "> // <tem:token></tem:token> // <tem:id>1944090</tem:id> // </tem:getLyric> // </soap:Body> // </soap:Envelope> func GetAPILyric(id dna.Int) (*APILyric, error) { if id == 0 { return nil, errors.New("Id is zero") } var dat dna.String = dna.Sprintf(`<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"><soap:Header/><soap:Body> <tem:getLyric xmlns=" http://tempuri.org/ "><tem:token></tem:token><tem:id>%v</tem:id></tem:getLyric></soap:Body> </soap:Envelope>`, id) header := Header header.Set("SOAPAction", "http://tempuri.org/getLyric") ret, err := Post("http://service.keeng.vn/appwebservice/Service.asmx?wsdl", header, dat) if err != nil { return nil, err } else { var lyric APILyric data := ret.Data.FindAllStringSubmatch(`<return>(.+)</return>`, -1)[0][1].DecodeHTML() err := json.Unmarshal([]byte(data), &lyric) if err != nil { return nil, err } else { lyric.Data = lyric.Data.DecodeHTML() return &lyric, nil } } }
// GetMovie returns a movie or an error. func GetMovie(id dna.Int) (*Movie, error) { var movie *Movie = NewMovie() movie.Id = id c := make(chan bool, 1) go func() { c <- <-getMovieFromPage(movie) }() for i := 0; i < 1; i++ { <-c } if movie.Title == "" && movie.AnotherTitle == "" { return nil, errors.New(dna.Sprintf("Hdviet - Movie %v: Not available", movie.Id).String()) } else { // Generating EpisodeKeyList if movie.IsSeries == false { EpisodeKeyList.Push(movie.Id * 1000) } else { for i := dna.Int(1); i <= movie.CurrentEps; i++ { EpisodeKeyList.Push(ToEpisodeKey(movie.Id, i)) } } return movie, nil } // if movie.Link == "" || movie.Link == "/" { // return nil, errors.New(fmt.Sprintf("Nhacso - Movie %v: Mp3 link not found", movie.Id)) // } else { // movie.Checktime = time.Now() // return movie, nil // } }
func (episode *Episode) Save(db *sqlpg.DB) error { insertStmt := getInsertStmt(episode, dna.Sprintf("WHERE NOT EXISTS (SELECT 1 FROM %v WHERE movie_id=%v and ep_id=%v)", getTableName(episode), episode.MovieId, episode.EpId)) _, err := db.Exec(insertStmt.String()) if err != nil { err = errors.New(err.Error() + " $$$error$$$" + insertStmt.String() + "$$$error$$$") } return err }
func (movie *Movie) Save(db *sqlpg.DB) error { insertStmt := getInsertStmt(movie, dna.Sprintf("WHERE NOT EXISTS (SELECT 1 FROM %v WHERE id=%v)", getTableName(movie), movie.Id)) _, err := db.Exec(insertStmt.String()) if err != nil { err = errors.New(err.Error() + " $$$error$$$" + insertStmt.String() + "$$$error$$$") } return err }
//GetAlbumFromAPI gets a album from API. It does not get content from main site. func GetAlbumFromAPI(id dna.Int) (*Album, error) { var album *Album = NewAlbum() album.Id = id apialbum, err := GetAPIAlbum(id) if err != nil { return nil, err } else { if apialbum.Response.MsgCode == 1 { if GetKey(apialbum.Id) != GetKey(album.Id) { errMes := dna.Sprintf("Resulted key and computed key are not match. %v =/= %v , id: %v =/= %v", GetKey(apialbum.Id), GetKey(album.Id), id, apialbum.Id) panic(errMes.String()) } album.Title = apialbum.Title album.Artists = dna.StringArray(apialbum.Artists.Split(" , ").Map(func(val dna.String, idx dna.Int) dna.String { return val.Trim() }).([]dna.String)).SplitWithRegexp(",").Filter(func(v dna.String, i dna.Int) dna.Bool { if v != "" { return true } else { return false } }) album.Topics = dna.StringArray(apialbum.Topics.Split(", ").Map(func(val dna.String, idx dna.Int) dna.String { return val.Trim() }).([]dna.String)).SplitWithRegexp(" / ").Unique().Filter(func(v dna.String, i dna.Int) dna.Bool { if v != "" { return true } else { return false } }) album.Plays = apialbum.Plays // album.Songids // album.Nsongs // album.EncodedKey // album.Coverart // album.DateCreated album.YearReleased = apialbum.YearReleased album.Description = apialbum.Description.RemoveHtmlTags("") album.ArtistIds = apialbum.ArtistIds.Split(",").ToIntArray() album.IsAlbum = apialbum.IsAlbum album.IsHit = apialbum.IsHit album.IsOfficial = apialbum.IsOfficial album.Likes = apialbum.Likes album.StatusId = apialbum.StatusId album.Comments = apialbum.Comments album.Checktime = time.Now() return album, nil } else { return nil, errors.New("Message code invalid " + apialbum.Response.MsgCode.ToString().String()) } } }
// ExecQueriesInTransaction executes queries in a transaction. // If one statement fails, the whole queries cannot commit. // // The returned error is nil if there is no error. // If an error occurs, each statement will be enclosed in // format $$$error$$$. // $$$error$$$ Your Custom Query $$$error$$$ // // This function is seen in songfreaks and allmusic sites. func ExecQueriesInTransaction(db *DB, queries *dna.StringArray) error { var err error globalSqlTransactoNo += 1 // tx, err := db.Begin() // if err != nil { // dna.Log("Transaction No:" + dna.Sprintf("%v", globalSqlTransactoNo).String() + err.Error() + " Could not create transaction\n") // } for idx, query := range *queries { _, err = db.Exec(query.String()) // _, err = tx.Exec(query.String()) if err != nil { dna.Log(dna.Sprintf("DNAError: Query series No: %v - %v - %v - %v\n", dna.Sprintf("%v", globalSqlTransactoNo), idx, err.Error(), "Could not execute the statement")) } // stmt, err := tx.Prepare(query.String()) // if err != nil { // dna.Log(dna.Sprintf("DNAError Transaction No: %v - %v - %v - %v \n", dna.Sprintf("%v", globalSqlTransactoNo), idx, err.Error(), "Could not prepare")) // } else { // _, err = stmt.Exec() // if err != nil { // dna.Log(dna.Sprintf("DNAError: Transaction No: %v - %v - %v - %v\n", dna.Sprintf("%v", globalSqlTransactoNo), idx, err.Error(), "Could not execute the prepared statement")) // } // err = stmt.Close() // if err != nil { // dna.Log("Transaction No:" + dna.Sprintf("%v", globalSqlTransactoNo).String() + err.Error() + " Could not close\n") // } // } } // err = tx.Commit() // if err != nil { // dna.Log("Transaction No:" + dna.Sprintf("%v", globalSqlTransactoNo).String() + err.Error() + " Could not commit transaction\n") // } if err != nil { errQueries := dna.StringArray(queries.Map(func(val dna.String, idx dna.Int) dna.String { return "Transaction No:" + dna.Sprintf("%v", globalSqlTransactoNo) + " $$$error$$$" + val + "$$$error$$$" }).([]dna.String)) return errors.New(err.Error() + errQueries.Join("\n").String()) } else { return nil } }
//CSVRecord returns a record to write csv format. // //psql -c "COPY sfalbums (id,amg,title,artistid,artists,url_slug,year,coverart,coverart_large,ratings,link,songids,review_author,review,checktime) FROM '/Users/daonguyenanbinh/Box Documents/Sites/golang/sfalbums.csv' DELIMITER ',' CSV" func (album *Album) CSVRecord() []string { return []string{ album.Id.ToString().String(), album.AMG.ToString().String(), album.Title.String(), album.Artistid.ToString().String(), dna.Sprintf("%#v", album.Artists).Replace("dna.StringArray", "").String(), album.UrlSlug.String(), album.Year.ToString().String(), album.Coverart.String(), album.CoverartLarge.String(), dna.Sprintf("%#v", album.Ratings).Replace("dna.IntArray", "").String(), album.Link.String(), dna.Sprintf("%#v", album.Songids).Replace("dna.IntArray", "").String(), album.ReviewAuthor.String(), album.Review.String(), album.Checktime.Format("2006-01-02 15:04:05"), } }
// GetMoviesCurrentEps returns a map of MovideId and CurrentEps // if CurrentEps is less than MaxEp. // it returns an error if available. // // This function is used when we need to find all possible movie ids // to update. func GetMoviesCurrentEps(db *sqlpg.DB, tblName dna.String) (map[dna.Int]dna.Int, error) { var movieCurrentEps = make(map[dna.Int]dna.Int) ids := &[]dna.Int{} currentEps := &[]dna.Int{} err := db.Select(ids, dna.Sprintf(`SELECT id from %v where current_eps < max_ep order by id DESC`, tblName)) if err != nil { return nil, err } err = db.Select(currentEps, dna.Sprintf(`SELECT current_eps from %v where current_eps < max_ep order by id DESC`, tblName)) if err != nil { return nil, err } if len(*currentEps) != len(*ids) { return nil, errors.New("Length of IDs and CurrentEps is not correspondent") } for idx, movieid := range *ids { movieCurrentEps[movieid] = (*currentEps)[idx] } return movieCurrentEps, nil }
// GetArtist returns a artist or an error func GetArtist(id dna.Int) (*Artist, error) { artist, err := GetArtistFromAPI(id) if err == nil { if artist.Name == "" { return nil, errors.New(dna.Sprintf("Zing - Artist %v: Artist not found", artist.Id).String()) } else { return artist, nil } } else { return nil, err } }