Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- [shows](#shows)
- [seasons](#seasons)
- [episodes](#episodes)
- [sync](#sync)
- [users](#users)
- [watchlist](#watchlist)

Expand Down Expand Up @@ -967,6 +968,119 @@ $ ./trakt-sync episodes -a watching -i the-sopranos -season 1 -episode 1
$ ./trakt-sync episodes -a videos -i the-sopranos -season 1 -episode 1
```

#### sync:

##### Last activities
```console
$ ./trakt-sync sync -a last_activities
```
##### Playback progress from last 60 days
```console
$ ./trakt-sync sync -a playback
```
##### Playback progress from last 60 days (movies or episodes)
```console
$ ./trakt-sync sync -a playback -t movies
```
##### Playback progress from 7 days
```console
$ ./trakt-sync sync -a playback -start_at 2025-06-01 -end_at 2025-06-07
```
##### Remove playback
```console
$ ./trakt-sync sync -a remove_playback -playback_id 12345
```
##### Get collection - movies
```console
$ ./trakt-sync sync -a get_collection -t movies -ex metadata
```
##### Get collection - shows
```console
$ ./trakt-sync sync -a get_collection -t shows -ex metadata
```
##### Get collection - episodes
```console
$ ./trakt-sync sync -a get_collection -t episodes -ex metadata
```
##### Get collection - seasons
```console
$ ./trakt-sync sync -a get_collection -t seasons -ex metadata
```

##### Add to collection - via -collection_items flag
```console
$ ./trakt-sync sync -a add_to_collection -collection_items export_sync_collection_movies.json
```
```console
$ ./trakt-sync sync -a add_to_collection -collection_items export_sync_collection_shows.json
```
```console
$ ./trakt-sync sync -a add_to_collection -collection_items export_sync_collection_episodes.json
```
```console
$ ./trakt-sync sync -a add_to_collection -collection_items export_sync_collection_seasons.json
```
##### Add to collection - via stdin
```console
$ cat export_sync_collection_movies.json | ./trakt-sync sync -a add_to_collection
```
```console
$ cat export_sync_collection_shows.json | ./trakt-sync sync -a add_to_collection
```
```console
$ cat export_sync_collection_episodes.json | ./trakt-sync sync -a add_to_collection
```
```console
$ cat export_sync_collection_seasons.json | ./trakt-sync sync -a add_to_collection
```

##### Remove from collection - via -collection_items flag
```console
$ ./trakt-sync sync -a remove_from_collection -collection_items export_sync_collection_movies.json
```
```console
```
##### Remove from collection - via stdin
```console
$ cat export_sync_collection_movies.json | ./trakt-sync sync -a remove_from_collection
```
```console
```

##### Get watched - movies
```console
$ ./trakt-sync sync -a get_watched -t movies
```
##### Get watched - shows
```console
$ ./trakt-sync sync -a get_watched -t shows
```
##### Get watched - shows - noseasons
```console
$ ./trakt-sync sync -a get_watched -t shows -ex noseasons
```
##### Get watched - episodes
```console
$ ./trakt-sync sync -a get_watched -t episodes
```

##### Get history - movies
```console
$ ./trakt-sync sync -a get_history -t movies -start_at 2025-07-01 -end_at 2025-07-06
```
##### Get history - shows - with trakt_id
```console
$ ./trakt-sync sync -a get_history -t shows -i 1388
```
##### Get history - shows
```console
$ ./trakt-sync sync -a get_history -t shows
```
##### Get history - episodes
```console
$ ./trakt-sync sync -a get_history -t episodes
```

#### users:

##### Export movies or shows or episodes from user lists:
Expand Down
1 change: 0 additions & 1 deletion Todo.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
- add filters where they used
- optimize multiple flag usage
- use local time
3 changes: 3 additions & 0 deletions cfg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Config struct {
CountSpecials string `toml:"count_specials"`
Days int `toml:"days"`
Delete bool `toml:"delete"`
EndAt string `toml:"end_at"`
Episode int `toml:"episode"`
EpisodeAbs int `toml:"episode_abs"`
EpisodeCode string `toml:"episode_code"`
Expand Down Expand Up @@ -60,6 +61,7 @@ type Config struct {
NotesID int `toml:"notes_id"`
Output string `toml:"output"`
PagesLimit int `toml:"pages_limit"`
PlaybackID int `toml:"playback_id"`
PerPage int `toml:"per_page"`
Privacy string `toml:"privacy"`
Progress float64 `toml:"progress"`
Expand All @@ -82,6 +84,7 @@ type Config struct {
Sort string `toml:"sort"`
Specials string `toml:"specials"`
Spoiler bool `toml:"spoiler"`
StartAt string `toml:"start_at"`
Timezone string `toml:"timezone"`
TokenPath string `toml:"token_path"`
TraktID int `toml:"trakt_id"`
Expand Down
34 changes: 34 additions & 0 deletions cfg/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ var ModuleActionConfig = map[string]OptionsConfig{
Type: []string{"all", "personal", "official", "watchlists", "favorites"},
Sort: []string{"popular", "likes", "comments", "items", "added", "updated"},
},
"sync:playback": {
Type: []string{"movies", "episodes"},
Sort: []string{},
},
"sync:get_watched": {
Type: []string{"movies", "shows", "episodes"},
Sort: []string{},
},
"sync:get_history": {
Type: []string{"movies", "shows", "seasons", "episodes"},
Sort: []string{},
},
}

// ModuleConfig represents the configuration options for all modules
Expand Down Expand Up @@ -232,6 +244,10 @@ var ModuleConfig = map[string]OptionsConfig{
"notes": {
Privacy: []string{"private", "friends", "public"},
},

"sync": {
Type: []string{"all", "movies", "shows"},
},
}

// ValidateConfig validates if the provided configuration is allowed for the given module
Expand Down Expand Up @@ -500,6 +516,7 @@ func GetOutputForModule(options *str.Options) string {
consts.Networks: getOutputForModuleNetworks(options),
consts.Notes: getOutputForModuleNotes(options),
consts.Recommendations: getOutputForModuleRecommendations(options),
consts.Sync: getOutputForModuleSync(options),
}

if output, found := allOutputs[options.Module]; found {
Expand All @@ -508,6 +525,23 @@ func GetOutputForModule(options *str.Options) string {
return fmt.Sprintf(consts.DefaultOutputFormat3, options.Module, options.Type, options.Format)
}

func getOutputForModuleSync(options *str.Options) string {
switch options.Action {
case consts.GetHistory:
options.Output = fmt.Sprintf(consts.DefaultOutputFormat3, options.Module, consts.History, options.Type)
case consts.GetWatched:
options.Output = fmt.Sprintf(consts.DefaultOutputFormat3, options.Module, consts.Watched, options.Type)
case consts.GetCollection:
options.Output = fmt.Sprintf(consts.DefaultOutputFormat3, options.Module, consts.Collection, options.Type)
case consts.LastActivities, consts.Playback, consts.AddToCollection, consts.RemoveFromCollection:
options.Output = fmt.Sprintf(consts.DefaultOutputFormat2, options.Module, options.Action)
default:
options.Output = fmt.Sprintf(consts.DefaultOutputFormat2, options.Module, options.Type)
}

return options.Output
}

func getOutputForModuleRecommendations(options *str.Options) string {
switch options.Action {
case consts.Movies, consts.Shows:
Expand Down
54 changes: 50 additions & 4 deletions cmds/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var Avflags = map[string]bool{
"certifications": true,
"checkin": true,
"collection": true,
"collection_items": true,
"comment": true,
"comment_id": true,
"comment_type": true,
Expand All @@ -51,10 +52,11 @@ var Avflags = map[string]bool{
"country": true,
"days": true,
"delete": true,
"end_at": true,
"episode": true,
"episode_abs": true,
"episode_code": true,
"episodes": true,
"episode": true,
"ex": true,
"f": true,
"field": true,
Expand All @@ -81,6 +83,7 @@ var Avflags = map[string]bool{
"pause": true,
"people": true,
"period": true,
"playback_id": true,
"privacy": true,
"progress": true,
"q": true,
Expand All @@ -92,20 +95,22 @@ var Avflags = map[string]bool{
"s": true,
"scrobble": true,
"search": true,
"seasons": true,
"season": true,
"seasons": true,
"shows": true,
"specials": true,
"spoiler": true,
"start": true,
"start_at": true,
"start_date": true,
"stop": true,
"sync": true,
"t": true,
"trakt_id": true,
"translations": true,
"u": true,
"users": true,
"undo": true,
"users": true,
"v": true,
"version": true,
"watchlist": true,
Expand Down Expand Up @@ -189,6 +194,11 @@ func (*Command) UpdateShowFlagsValues() {
}
}

// UpdateSyncFlagsValues update sync flags values only in command
func (*Command) UpdateSyncFlagsValues() {

}

// UpdateSeasonFlagsValues update season flags values only in command
func (*Command) UpdateSeasonFlagsValues() {
if *_seasonsSort == "" {
Expand Down Expand Up @@ -715,7 +725,7 @@ func (c *Command) UpdateOptionsWithCommandFlags(options *str.Options) *str.Optio
options = UpdateOptionsWithCommandShowsFlags(c, options)
options = UpdateOptionsWithCommandRecommendationsFlags(options)
options = UpdateOptionsWithCommandScrobbleFlags(options)

options = UpdateOptionsWithCommandSyncFlags(c, options)
return options
}

Expand All @@ -731,6 +741,42 @@ func UpdateOptionsWithCommandScrobbleFlags(options *str.Options) *str.Options {
return options
}

// UpdateOptionsWithCommandSyncFlags update options depends on scrobble command flags
func UpdateOptionsWithCommandSyncFlags(c *Command, options *str.Options) *str.Options {
if len(*_syncAction) > consts.ZeroValue {
options.Action = *_syncAction
}
options.Output = cfg.GetOutputForModule(options)

options.FullHour = true
if len(*_syncStartAt) > consts.ZeroValue {
options.StartDate = c.common.ConvertDateString(*_syncStartAt, consts.DefaultStartDateFormat, options.Timezone, options.FullHour)
} else {
options.StartDate = c.common.DateLastDays(consts.DefaultStartAtDays, options.Timezone, options.FullHour)
}

if len(*_syncEndAt) > consts.ZeroValue {
options.EndDate = c.common.ConvertDateString(*_syncEndAt, consts.DefaultStartDateFormat, options.Timezone, options.FullHour)
} else {
options.EndDate = c.common.CurrentDateString(options.Timezone, options.FullHour)
}

options.FullHour = true

if *_syncPlaybackID > consts.ZeroValue {
options.PlaybackID = *_syncPlaybackID
}

if len(*_syncCollectionItems) > consts.ZeroValue {
options.CollectionItems = *_syncCollectionItems
}

if *_syncID > consts.ZeroValue {
options.TraktID = *_syncID
}
return options
}

// UpdateOptionsWithCommandRecommendationsFlags update options depends on recommendations command flags
func UpdateOptionsWithCommandRecommendationsFlags(options *str.Options) *str.Options {
if len(*_recommendationsIgnoreCollected) > consts.ZeroValue {
Expand Down
36 changes: 1 addition & 35 deletions cmds/command_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"time"

"github.com/mfederowicz/trakt-sync/cfg"
"github.com/mfederowicz/trakt-sync/consts"
"github.com/mfederowicz/trakt-sync/internal"
"github.com/mfederowicz/trakt-sync/printer"
"github.com/mfederowicz/trakt-sync/str"
"github.com/mfederowicz/trakt-sync/uri"
"github.com/mfederowicz/trakt-sync/writer"
)

Expand All @@ -31,7 +28,7 @@ func historyFunc(cmd *Command, _ ...string) error {

printer.Println("fetch history lists for:" + options.UserName)

historyLists, err := fetchHistoryList(client, options, consts.DefaultPage)
historyLists, err := cmd.common.FetchHistoryList(client, options, consts.DefaultPage)
if err != nil {
return fmt.Errorf("fetch history list error:%w", err)
}
Expand Down Expand Up @@ -65,34 +62,3 @@ var (
func init() {
HistoryCmd.Run = historyFunc
}

func fetchHistoryList(client *internal.Client, options *str.Options, page int) ([]*str.ExportlistItem, error) {
opts := uri.ListOptions{Page: page, Limit: options.PerPage, Extended: options.ExtendedInfo}

list, resp, err := client.Sync.GetWatchedHistory(
client.BuildCtxFromOptions(options),
&options.Type,
&opts,
)

if err != nil {
return nil, err
}

// Check if there are more pages
if client.HavePages(page, resp, options.PagesLimit) {
time.Sleep(time.Duration(consts.SleepNumberOfSeconds) * time.Second)

// Fetch items from the next page
nextPage := page + consts.NextPageStep
nextPageItems, err := fetchHistoryList(client, options, nextPage)
if err != nil {
return nil, err
}

// Append items from the next page to the current page
list = append(list, nextPageItems...)
}

return list, nil
}
Loading