amuse.git

commit 3387dd3f60a951448edbaa34d1294c0c4a882331

Author: Adam <git@apiote.tk>

skip specials by their codes not by number of them

 db/db.go | 63 +++++++++++++++++++++++++++++++++++++--
 libamuse/account.go | 74 +++++++++++++++++++++++++++++++++++++++-------
 libamuse/serie.go | 9 +++++
 tmdb/serie.go | 51 ++++++++++++++++++++++----------


diff --git a/db/db.go b/db/db.go
index 56174347af8520d35560cd2937cb5534ee90c5b1..5e68a6438645f4c74e84ecf318bc2f2fd5263a9c 100644
--- a/db/db.go
+++ b/db/db.go
@@ -373,7 +373,7 @@
 	return int(insertedRowsNumber - deletedRowsNumber), nil
 }
 
-func SkipSpecials(username, itemId string, episodesNumber int, itemType datastructure.ItemType, datetime time.Time) (int, error) {
+func SkipSpecials(username, itemId string, episodes []string, itemType datastructure.ItemType) (int, error) {
 	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "DB open err\n")
@@ -408,12 +408,11 @@ 	}
 
 	modifiedRows := 0
 
-	for e := 1; e <= episodesNumber; e++ {
-		episodeId := fmt.Sprintf("%s/S00E%02d", itemId, e)
+	for _, episodeId := range episodes {
 		if watched[episodeId] > 0 {
 			continue
 		}
-		_, err = tx.Exec(`insert into experiences values(?, ?, ?, ?)`, username, itemType, episodeId, datetime)
+		_, err = tx.Exec(`insert into experiences values(?, ?, ?, ?)`, username, itemType, episodeId, "0001-01-01 00:00:00+00:00")
 		if err != nil {
 			if err.Error()[:6] != "UNIQUE" {
 				fmt.Fprintf(os.Stderr, "Insert err %v\n", err)
@@ -432,6 +431,62 @@ 		return 0, err
 	}
 
 	return modifiedRows, nil
+}
+
+func ClearSpecials(username, itemId string, episodes []string, itemType datastructure.ItemType) error {
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "DB open err\n")
+		return err
+	}
+	defer db.Close()
+
+	tx, err := db.Begin()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Transaction err %s\n", err)
+		return err
+	}
+	defer tx.Rollback()
+
+	rows, err := tx.Query(`select item_id from experiences where item_type = ? and item_id like ? || '/S00E%' and username = ? and time = "0001-01-01 00:00:00+00:00"`, itemType, itemId, username)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Select err %v\n", err)
+		return err
+	}
+	defer rows.Close()
+
+	watched := []string{}
+	for rows.Next() {
+		var watchedId string
+		err := rows.Scan(&watchedId)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Scan err %v\n", err)
+			return err
+		}
+		watched = append(watched, watchedId)
+	}
+
+	seriesEpisodes := map[string]int{}
+	for _, episode := range episodes {
+		seriesEpisodes[episode]++
+	}
+
+	for _, episode := range watched {
+		if seriesEpisodes[episode] == 0 {
+			_, err = tx.Exec(`delete from experiences where item_type = ? and item_id = ? and username = ?`, itemType, episode, username)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "Delete err %v\n", err)
+				return err
+			}
+		}
+	}
+
+	err = tx.Commit()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Commit err %v\n", err)
+		return err
+	}
+	return nil
 }
 
 func AddToWantList(username, itemId string, itemType datastructure.ItemType) error {




diff --git a/libamuse/account.go b/libamuse/account.go
index bca7dc747063ebecbb74cb9d08878a2262e7ad44..9f4fdd2d7117a2f73aea4ce4e3047ecc00c57a9f 100644
--- a/libamuse/account.go
+++ b/libamuse/account.go
@@ -4,6 +4,7 @@ import (
 	"notabug.org/apiote/amuse/accounts"
 	"notabug.org/apiote/amuse/datastructure"
 	"notabug.org/apiote/amuse/db"
+	"notabug.org/apiote/amuse/tmdb"
 
 	"errors"
 	"fmt"
@@ -80,6 +81,8 @@ 			Finish()
 		if err == nil {
 			args = arg.(gott.Tuple)
 		}
+	default:
+		err = errors.New("Wrong ItemType: " + itemType)
 	}
 	return gott.Tuple(args), err
 }
@@ -112,9 +115,17 @@
 	return err
 }
 
+func splitItemId(args ...interface{}) interface{} {
+	data := args[0].(*RequestData)
+	itemId := args[3].(string)
+	id := strings.Split(itemId, "/")
+	data.id = id[0]
+	return gott.Tuple(args)
+}
+
 func parseExperienceDate(args ...interface{}) (interface{}, error) {
 	result := args[1].(*Result)
-	datetime := args[3].(string)
+	datetime := args[4].(string)
 	var t time.Time
 	var err error = nil
 	if datetime == "" {
@@ -129,34 +140,51 @@ 		}
 		t, err = time.ParseInLocation("2006-01-02T15:04:05", datetime, location)
 	}
 	t = t.In(time.UTC)
-	result.result = t
+	result.result2 = t
+	return gott.Tuple(args), err
+}
+
+func getSpecials(args ...interface{}) (interface{}, error) {
+	itemId := args[3].(string)
+	var err error
+
+	id := strings.Split(itemId, "/")
+	if len(id) > 1 && id[1][3] == 'A' {
+		arg, err := gott.
+			NewResult(gott.Tuple(args)).
+			Bind(getSeason0).
+			Finish()
+		if err == nil {
+			args = arg.(gott.Tuple)
+		}
+	}
 	return gott.Tuple(args), err
 }
 
 func addToExperiences(args ...interface{}) (interface{}, error) {
 	data := args[0].(*RequestData)
 	result := args[1].(*Result)
+	t := result.result2.(time.Time)
 	itemType := args[2].(string)
-	t := result.result.(time.Time)
+	itemId := args[3].(string)
 	var (
 		err  error = nil
 		refs int
 	)
 
-	id := strings.Split(data.id, "/")
+	id := strings.Split(itemId, "/")
 	if len(id) > 1 && id[1][3] == 'A' {
-		var episodesNumber int
-		_, err := fmt.Sscanf(id[1][4:], "%d", &episodesNumber)
-		if err != nil {
-			return gott.Tuple(args), err
+		serie := result.result.(*tmdb.TvSerie)
+		episodes := []string{}
+		for _, episode := range serie.Seasons[0].Episodes {
+			episodes = append(episodes, data.id+"/"+episode.Episode_code)
 		}
-		refs, err = db.SkipSpecials(result.user.Username, id[0], episodesNumber, datastructure.ItemType(itemType), t)
+		refs, err = db.SkipSpecials(result.user.Username, id[0], episodes, datastructure.ItemType(itemType))
 	} else {
 		refs, err = db.AddToExperiences(result.user.Username, data.id, datastructure.ItemType(itemType), t)
 	}
 	result.result2 = refs
 
-	data.id = id[0]
 	if len(id) > 1 {
 		return gott.Tuple(args), errors.New("Skip")
 	}
@@ -164,6 +192,25 @@
 	return gott.Tuple(args), err
 }
 
+func clearSpecials(args ...interface{}) (interface{}, error) {
+	data := args[0].(*RequestData)
+	result := args[1].(*Result)
+	itemType := args[2].(string)
+	itemId := args[3].(string)
+	id := strings.Split(itemId, "/")
+
+	var err error
+	if len(id) > 1 && id[1][3] == 'A' {
+		serie := result.result.(*tmdb.TvSerie)
+		episodes := []string{}
+		for _, episode := range serie.Seasons[0].Episodes {
+			episodes = append(episodes, data.id+"/"+episode.Episode_code)
+		}
+		err = db.ClearSpecials(result.user.Username, id[0], episodes, datastructure.ItemType(itemType))
+	}
+	return gott.Tuple(args), err
+}
+
 func removeFromWantList(args ...interface{}) (interface{}, error) {
 	data := args[0].(*RequestData)
 	result := args[1].(*Result)
@@ -186,13 +233,16 @@
 func AddToExperiences(username string, auth accounts.Authentication, itemId, itemType, datetime, language, mimetype string) error {
 	auth.Necessary = true
 	_, err := gott.
-		NewResult(gott.Tuple{&RequestData{id: itemId, language: language, mimetype: mimetype, auth: auth, username: username}, &Result{}, itemType, datetime}).
+		NewResult(gott.Tuple{&RequestData{language: language, mimetype: mimetype, auth: auth, username: username}, &Result{}, itemType, itemId, datetime}).
+		Map(splitItemId).
 		Bind(parseLanguage).
 		Bind(verifyToken).
 		Bind(verifyUser).
 		Bind(parseExperienceDate).
+		Bind(getItem).
+		Bind(getSpecials).
+		Bind(clearSpecials).
 		Bind(addToExperiences).
-		Bind(getItem).
 		Bind(cacheItem).
 		Bind(removeFromWantList).
 		Bind(removeCacheItem).




diff --git a/libamuse/serie.go b/libamuse/serie.go
index c3e4c9987a26369b2c855a64efdb0fd0d0c93a90..521d830267da953390b8db839e9c2667c9cac83e 100644
--- a/libamuse/serie.go
+++ b/libamuse/serie.go
@@ -37,6 +37,15 @@ 	tvSerie.Seasons = seasons
 	return gott.Tuple(args), err
 }
 
+func getSeason0(args ...interface{}) (interface{}, error) {
+	result := args[1].(*Result)
+	tvSerie := result.result.(*tmdb.TvSerie)
+	languages := result.languages
+	seasons, err := tmdb.GetSeason0(tvSerie, languages[0].String())
+	tvSerie.Seasons = seasons
+	return gott.Tuple(args), err
+}
+
 func mergeCredits(args ...interface{}) (interface{}, error) {
 	result := args[1].(*Result)
 	mergedCast := map[string]tmdb.ShowCastEntry{}




diff --git a/tmdb/serie.go b/tmdb/serie.go
index 6c7528fd31239f054b0ce6baf7e7c1fead11a74e..dc33ebcef5bf1d6d597a06da72c04877119a7203 100644
--- a/tmdb/serie.go
+++ b/tmdb/serie.go
@@ -242,26 +242,45 @@ 		return serie.(gott.Tuple)[1].(*network.Result).Result.(*TvSerie), nil
 	}
 }
 
+func getSeason(serie *TvSerie, language string, seasonNumber int) (Season, error) {
+	seasonNumberS := strconv.FormatInt(int64(seasonNumber), 10)
+	s, err := gott.
+		NewResult(gott.Tuple{&network.Request{Id: serie.Id, Language: language, Subid: seasonNumberS}, &network.Result{}}).
+		Bind(createSeasonRequest).
+		Bind(getCacheEntry).
+		Map(network.AddHeaders).
+		Bind(network.DoRequest).
+		Bind(network.HandleRequestError).
+		Bind(network.ReadResponse).
+		Tee(cleanCache).
+		Tee(saveCacheEntry).
+		Bind(unmarshalSeason).
+		Bind(convertSeasonDates).
+		Finish()
+	season := *s.(gott.Tuple)[1].(*network.Result).Result.(*Season)
+	return season, err
+}
+
+func GetSeason0(serie *TvSerie, language string) ([]Season, error) {
+	seasons := []Season{}
+	var (
+		err    error
+		season Season
+	)
+	if serie.Seasons[0].Season_number == 0 {
+		season, err = getSeason(serie, language, 0)
+		seasons = append(seasons, season)
+	}
+	return seasons, err
+}
+
 func GetSeasons(serie *TvSerie, language string) ([]Season, error) {
 	var err error
 	var seasons []Season
-	for _, season := range serie.Seasons {
-		seasonNumber := strconv.FormatInt(int64(season.Season_number), 10)
-		s, err2 := gott.
-			NewResult(gott.Tuple{&network.Request{Id: serie.Id, Language: language, Subid: seasonNumber}, &network.Result{}}).
-			Bind(createSeasonRequest).
-			Bind(getCacheEntry).
-			Map(network.AddHeaders).
-			Bind(network.DoRequest).
-			Bind(network.HandleRequestError).
-			Bind(network.ReadResponse).
-			Tee(cleanCache).
-			Tee(saveCacheEntry).
-			Bind(unmarshalSeason).
-			Bind(convertSeasonDates).
-			Finish()
+	for _, serieSeason := range serie.Seasons {
+		season, err2 := getSeason(serie, language, serieSeason.Season_number)
 		err = utils.Or(err, err2)
-		seasons = append(seasons, *s.(gott.Tuple)[1].(*network.Result).Result.(*Season))
+		seasons = append(seasons, season)
 	}
 	return seasons, err
 }