diff --git a/Export.cs b/Export.cs index 292cce0..61cd5f7 100644 --- a/Export.cs +++ b/Export.cs @@ -536,6 +536,108 @@ public static void CreatePausedMoviesCsv() } } + public static void CreateCustomListsCsv() + { + if (Cancel) return; + + // First get the users custom lists + + UIUtils.UpdateStatus("Getting custom lists from trakt.tv"); + var customLists = TraktAPI.TraktAPI.GetCustomLists(); + if (customLists != null) + { + var lists = new List(); + foreach (var item in customLists) + { + lists.Add(new + { + TraktId = item.Ids.Trakt, + Slug = item.Ids.Slug, + Name = item.Name, + Description = item.Description, + Privacy = item.Privacy, + DisplayNumbers = item.DisplayNumbers, + AllowComments = item.AllowComments, + SortBy = item.SortBy, + SortHow = item.SortHow, + ItemCount = item.ItemCount, + CommentCount = item.Comments, + Likes = item.Likes, + CreatedAt = item.CreatedAt, + UpdatedAt = item.UpdatedAt + }); + } + + UIUtils.UpdateStatus("Creating custom lists csv file"); + WriteToCsv(Path.Combine(AppSettings.CsvExportPath, "custom_lists.csv"), lists); + } + else + { + UIUtils.UpdateStatus("Failed to get current custom lists from trakt.tv", true); + Thread.Sleep(2000); + return; + } + + // Next get the items for each custom list + + foreach(var list in customLists) + { + UIUtils.UpdateStatus($"Getting custom list items for '{list.Name}' from trakt.tv"); + var customListItems = TraktAPI.TraktAPI.GetCustomListItems(list.Ids.Trakt.ToString()); + if (customListItems != null) + { + var listItems = new List(); + foreach (var item in customListItems) + { + // important to check for null as an item may be of a different type + // NB: the season object does not return for episodes, so get season number from episode object + listItems.Add(new + { + Rank = item.Rank, + Id = item.Id, + Type = item.Type, + ListedAt = item.ListedAt, + MovieTitle = item.Movie?.Title, + MovieYear = item.Movie?.Year, + MovieTraktId = item.Movie?.Ids.Trakt, + MovieImdbId = item.Movie?.Ids.ImdbId, + MovieTmdbId = item.Movie?.Ids.TmdbId, + MovieSlug = item.Movie?.Ids.Slug, + ShowTitle = item.Show?.Title, + ShowYear = item.Show?.Year, + ShowTraktId = item.Show?.Ids.Trakt, + ShowTvdbId = item.Show?.Ids.TvdbId, + ShowTmdbId = item.Show?.Ids.TmdbId, + ShowSlug = item.Show?.Ids.Slug, + SeasonTvdbId = item.Season?.Ids.TvdbId, + SeasonTmdbId = item.Season?.Ids.TmdbId, + SeasonNumber = item.Season?.Number.ToString() ?? item.Episode?.Season.ToString(), + EpisodeNumber = item.Episode?.Number, + EpisodeTraktId = item.Episode?.Ids.Trakt, + EpisodeTvdbId = item.Episode?.Ids.TvdbId, + EpisodeTmdbId = item.Episode?.Ids.TmdbId, + EpisodeImdbId = item.Episode?.Ids.ImdbId, + PersonName = item.Person?.Name, + PersonTraktId = item.Person?.Ids.Trakt, + PersonImdbId = item.Person?.Ids.ImdbId, + PersonTmdbId = item.Person?.Ids.TmdbId, + PersonSlug = item.Person?.Ids.Slug + }); + } + + UIUtils.UpdateStatus($"Creating custom list '{list.Name}' csv file"); + // using the slug for the filename should be file system friendly + WriteToCsv(Path.Combine(AppSettings.CsvExportPath, $"custom_list_{list.Ids.Slug}.csv"), listItems); + } + else + { + UIUtils.UpdateStatus($"Failed to get current custom list items for '{list.Name}' from trakt.tv", true); + Thread.Sleep(2000); + } + + } + } + private static void WriteToCsv(string filename, List records) { string directory = Path.GetDirectoryName(filename); diff --git a/Settings/ExportItems.cs b/Settings/ExportItems.cs index 0b6de49..8f4f817 100644 --- a/Settings/ExportItems.cs +++ b/Settings/ExportItems.cs @@ -16,5 +16,6 @@ public class ExportItems public bool WatchlistMovies { get; set; } public bool PausedEpisodes { get; set; } public bool PausedMovies { get; set; } + public bool CustomLists { get; set; } } } diff --git a/TraktAPI/DataStructures/TraktList.cs b/TraktAPI/DataStructures/TraktList.cs index 09dc895..add24e9 100644 --- a/TraktAPI/DataStructures/TraktList.cs +++ b/TraktAPI/DataStructures/TraktList.cs @@ -19,5 +19,11 @@ public class TraktList [DataMember(Name = "allow_comments")] public bool AllowComments { get; set; } + + [DataMember(Name = "sort_by")] + public string SortBy { get; set; } + + [DataMember(Name = "sort_how")] + public string SortHow { get; set; } } } diff --git a/TraktAPI/DataStructures/TraktListDetail.cs b/TraktAPI/DataStructures/TraktListDetail.cs index e17ddf5..4ce5a4c 100644 --- a/TraktAPI/DataStructures/TraktListDetail.cs +++ b/TraktAPI/DataStructures/TraktListDetail.cs @@ -5,6 +5,9 @@ [DataContract] public class TraktListDetail : TraktList { + [DataMember(Name = "created_at")] + public string CreatedAt { get; set; } + [DataMember(Name = "updated_at")] public string UpdatedAt { get; set; } diff --git a/TraktAPI/DataStructures/TraktListItem.cs b/TraktAPI/DataStructures/TraktListItem.cs index 991477e..70f5740 100644 --- a/TraktAPI/DataStructures/TraktListItem.cs +++ b/TraktAPI/DataStructures/TraktListItem.cs @@ -5,6 +5,12 @@ [DataContract] public class TraktListItem { + [DataMember(Name = "rank")] + public int Rank { get; set; } + + [DataMember(Name = "id")] + public int Id { get; set; } + [DataMember(Name = "listed_at")] public string ListedAt { get; set; } @@ -18,10 +24,10 @@ public class TraktListItem public TraktShow Show { get; set; } [DataMember(Name = "season")] - public TraktSeason Season { get; set; } + public TraktSeasonEx Season { get; set; } [DataMember(Name = "episode")] - public TraktEpisode Episode { get; set; } + public TraktEpisodeSummary Episode { get; set; } [DataMember(Name = "person")] public TraktPerson Person { get; set; } diff --git a/TraktAPI/DataStructures/TraktSeasonEx.cs b/TraktAPI/DataStructures/TraktSeasonEx.cs new file mode 100644 index 0000000..10a8445 --- /dev/null +++ b/TraktAPI/DataStructures/TraktSeasonEx.cs @@ -0,0 +1,11 @@ +using System.Runtime.Serialization; + +namespace TraktRater.TraktAPI.DataStructures +{ + [DataContract] + public class TraktSeasonEx : TraktSeason + { + [DataMember(Name = "ids")] + public TraktSeasonId Ids { get; set; } + } +} diff --git a/TraktRater.cs b/TraktRater.cs index 7c8c300..2aec3ce 100644 --- a/TraktRater.cs +++ b/TraktRater.cs @@ -846,6 +846,10 @@ private void StartExport(ExportItems items) { Export.CreatePausedMoviesCsv(); } + if (AppSettings.CsvExportItems.CustomLists) + { + Export.CreateCustomListsCsv(); + } // finished SetControlState(true); diff --git a/TraktRater.csproj b/TraktRater.csproj index a6097f4..cf88ede 100644 --- a/TraktRater.csproj +++ b/TraktRater.csproj @@ -146,6 +146,7 @@ + diff --git a/UI/ExportDialog.Designer.cs b/UI/ExportDialog.Designer.cs index 4f301de..8a91ff2 100644 --- a/UI/ExportDialog.Designer.cs +++ b/UI/ExportDialog.Designer.cs @@ -51,13 +51,14 @@ private void InitializeComponent() this.btnBrowsePath = new System.Windows.Forms.Button(); this.txtExportPath = new System.Windows.Forms.TextBox(); this.fbdExportPath = new System.Windows.Forms.FolderBrowserDialog(); + this.chkCustomLists = new System.Windows.Forms.CheckBox(); this.grbExport.SuspendLayout(); this.grbPath.SuspendLayout(); this.SuspendLayout(); // // btnExport // - this.btnExport.Location = new System.Drawing.Point(462, 513); + this.btnExport.Location = new System.Drawing.Point(461, 643); this.btnExport.Name = "btnExport"; this.btnExport.Size = new System.Drawing.Size(176, 36); this.btnExport.TabIndex = 1; @@ -67,7 +68,7 @@ private void InitializeComponent() // // btnCancel // - this.btnCancel.Location = new System.Drawing.Point(280, 513); + this.btnCancel.Location = new System.Drawing.Point(279, 643); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(176, 36); this.btnCancel.TabIndex = 2; @@ -77,6 +78,7 @@ private void InitializeComponent() // // grbExport // + this.grbExport.Controls.Add(this.chkCustomLists); this.grbExport.Controls.Add(this.chkMoviePausedStates); this.grbExport.Controls.Add(this.chkEpisodePausedStates); this.grbExport.Controls.Add(this.chkMovieWatchlist); @@ -96,14 +98,14 @@ private void InitializeComponent() this.grbExport.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.grbExport.Name = "grbExport"; this.grbExport.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); - this.grbExport.Size = new System.Drawing.Size(628, 376); + this.grbExport.Size = new System.Drawing.Size(628, 507); this.grbExport.TabIndex = 3; this.grbExport.TabStop = false; // // chkMoviePausedStates // this.chkMoviePausedStates.AutoSize = true; - this.chkMoviePausedStates.Location = new System.Drawing.Point(340, 258); + this.chkMoviePausedStates.Location = new System.Drawing.Point(342, 143); this.chkMoviePausedStates.Name = "chkMoviePausedStates"; this.chkMoviePausedStates.Size = new System.Drawing.Size(185, 24); this.chkMoviePausedStates.TabIndex = 14; @@ -114,7 +116,7 @@ private void InitializeComponent() // chkEpisodePausedStates // this.chkEpisodePausedStates.AutoSize = true; - this.chkEpisodePausedStates.Location = new System.Drawing.Point(340, 219); + this.chkEpisodePausedStates.Location = new System.Drawing.Point(342, 104); this.chkEpisodePausedStates.Name = "chkEpisodePausedStates"; this.chkEpisodePausedStates.Size = new System.Drawing.Size(202, 24); this.chkEpisodePausedStates.TabIndex = 13; @@ -168,7 +170,7 @@ private void InitializeComponent() // // chkMovieRatings // - this.chkMovieRatings.Location = new System.Drawing.Point(340, 180); + this.chkMovieRatings.Location = new System.Drawing.Point(342, 65); this.chkMovieRatings.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.chkMovieRatings.Name = "chkMovieRatings"; this.chkMovieRatings.Size = new System.Drawing.Size(219, 26); @@ -179,7 +181,7 @@ private void InitializeComponent() // // chkSeasonRatings // - this.chkSeasonRatings.Location = new System.Drawing.Point(340, 142); + this.chkSeasonRatings.Location = new System.Drawing.Point(13, 447); this.chkSeasonRatings.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.chkSeasonRatings.Name = "chkSeasonRatings"; this.chkSeasonRatings.Size = new System.Drawing.Size(219, 26); @@ -190,7 +192,7 @@ private void InitializeComponent() // // chkShowRatings // - this.chkShowRatings.Location = new System.Drawing.Point(340, 103); + this.chkShowRatings.Location = new System.Drawing.Point(13, 408); this.chkShowRatings.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.chkShowRatings.Name = "chkShowRatings"; this.chkShowRatings.Size = new System.Drawing.Size(219, 26); @@ -201,7 +203,7 @@ private void InitializeComponent() // // chkEpisodeRatings // - this.chkEpisodeRatings.Location = new System.Drawing.Point(340, 65); + this.chkEpisodeRatings.Location = new System.Drawing.Point(13, 370); this.chkEpisodeRatings.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.chkEpisodeRatings.Name = "chkEpisodeRatings"; this.chkEpisodeRatings.Size = new System.Drawing.Size(219, 26); @@ -267,7 +269,7 @@ private void InitializeComponent() // this.grbPath.Controls.Add(this.btnBrowsePath); this.grbPath.Controls.Add(this.txtExportPath); - this.grbPath.Location = new System.Drawing.Point(13, 399); + this.grbPath.Location = new System.Drawing.Point(12, 529); this.grbPath.Name = "grbPath"; this.grbPath.Size = new System.Drawing.Size(625, 92); this.grbPath.TabIndex = 4; @@ -296,11 +298,22 @@ private void InitializeComponent() // this.fbdExportPath.Description = "Select folder to create CSV files in:"; // + // chkCustomLists + // + this.chkCustomLists.AutoSize = true; + this.chkCustomLists.Location = new System.Drawing.Point(342, 181); + this.chkCustomLists.Name = "chkCustomLists"; + this.chkCustomLists.Size = new System.Drawing.Size(127, 24); + this.chkCustomLists.TabIndex = 15; + this.chkCustomLists.Text = "Custom Lists"; + this.chkCustomLists.UseVisualStyleBackColor = true; + this.chkCustomLists.Click += new System.EventHandler(this.chkCustomLists_Click); + // // ExportDialog // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(650, 563); + this.ClientSize = new System.Drawing.Size(652, 693); this.Controls.Add(this.grbPath); this.Controls.Add(this.grbExport); this.Controls.Add(this.btnCancel); @@ -342,5 +355,6 @@ private void InitializeComponent() private System.Windows.Forms.Button btnBrowsePath; private System.Windows.Forms.TextBox txtExportPath; private System.Windows.Forms.FolderBrowserDialog fbdExportPath; + private System.Windows.Forms.CheckBox chkCustomLists; } } \ No newline at end of file diff --git a/UI/ExportDialog.cs b/UI/ExportDialog.cs index 24bca1e..14eeff1 100644 --- a/UI/ExportDialog.cs +++ b/UI/ExportDialog.cs @@ -34,6 +34,7 @@ public ExportDialog(string path, ExportItems items) chkEpisodeCollection.Checked = ItemsToExport.CollectedEpisodes; chkMovieWatchedHistory.Checked = ItemsToExport.WatchedHistoryMovies; chkEpisodeWatchedHistory.Checked = ItemsToExport.WatchedHistoryEpisodes; + chkCustomLists.Checked = ItemsToExport.CustomLists; txtExportPath.Text = ExportPath; #endregion @@ -133,6 +134,12 @@ private void chkMoviePausedStates_Click(object sender, EventArgs e) { ItemsToExport.PausedMovies = chkMoviePausedStates.Checked; } + + private void chkCustomLists_Click(object sender, EventArgs e) + { + ItemsToExport.CustomLists = chkCustomLists.Checked; + } #endregion + } }