Beispiel #1
0
        /// <summary>
        /// Sends metadata information about the TV show into lab.rolisoft.net cache.
        /// </summary>
        /// <param name="tv">The TV show.</param>
        public static void UpdateRemoteCache(TVShow tv)
        {
            new Thread(() =>
                {
                    try
                    {
                        var info = new Remote.Objects.ShowInfo
                            {
                                Title       = tv.Title,
                                Description = tv.Description,
                                Genre       = tv.Genre,
                                Cover       = tv.Cover,
                                Started     = (long)tv.Episodes[0].Airdate.ToUnixTimestamp(),
                                Airing      = tv.Airing,
                                AirTime     = tv.AirTime,
                                AirDay      = tv.AirDay,
                                Network     = tv.Network,
                                Runtime     = tv.Runtime,
                                Seasons     = tv.Episodes.Last().Season,
                                Episodes    = tv.Episodes.Count,
                                Source      = tv.Source,
                                SourceID    = tv.SourceID
                            };

                        var hash = BitConverter.ToString(new HMACSHA256(Encoding.ASCII.GetBytes(Utils.GetUUID() + "\0" + Signature.Version)).ComputeHash(Encoding.UTF8.GetBytes(
                            info.Title + info.Description + string.Join(string.Empty, info.Genre) + info.Cover + info.Started + (info.Airing ? "true" : "false") + info.AirTime + info.AirDay + info.Network + info.Runtime + info.Seasons + info.Episodes + info.Source + info.SourceID
                        ))).ToLower().Replace("-", string.Empty);

                        API.SetShowInfo(info, hash);
                    } catch { }
                }).Start();
        }
        /// <summary>
        /// Generates a regular expression for matching the show's name.
        /// </summary>
        /// <param name="show">The show's name.</param>
        /// <param name="db">The database entry, if any.</param>
        /// <returns>
        /// Regular expression which matches to the show's name.
        /// </returns>
        public static Regex GenerateTitleRegex(string show = null, TVShow db = null)
        {
            if (show == null)
            {
                show = db.Title;
            }

            // see if the show has a different name
            show = show.Trim();
            if (db != null && !string.IsNullOrWhiteSpace(db.Data.Get("scene")))
            {
                show = db.Data["scene"];
            }
            else if (Regexes.Exclusions.ContainsKey(show))
            {
                show = Regexes.Exclusions[show];
            }

            // see if the show already has a hand-written regex
            if (Regexes.Pregenerated.ContainsKey(show))
            {
                return new Regex(Regexes.Pregenerated[show], RegexOptions.IgnoreCase);
            }

            // the CLR is optimized for uppercase string matching
            show = show.ToUpper();

            // replace apostrophes which occur in contractions to a null placeholder
            show = Regexes.Contractions.Replace(show, "\0");

            // replace "&" to "and"
            show = Regexes.Ampersand.Replace(show, "AND");

            // remove special characters
            show = Regexes.SpecialChars.Replace(show, " ").Trim();

            // remove parentheses
            //show = show.Replace("(", string.Empty).Replace(")", string.Empty);

            // make year optional
            show = Regexes.Year.Replace(show, m => "(?:" + m.Groups[1].Value + ")?");

            // make common words and single characters optional
            show = Regexes.Common.Replace(show, m => "(?:" + m.Groups[1].Value + ")?");
            show = Regexes.OneChar.Replace(show, m => "(?:" + m.Groups[1].Value + ")?");

            // replace null placeholder for apostrophes
            show = show.Replace("\0", @"(?:\\?['`’\._])?");

            // replace whitespace to non-letter matcher
            show = Regexes.Whitespace.Replace(show.Trim(), "[^A-Z0-9]+");

            // quick fix for ending optional tags
            show = show.Replace("[^A-Z0-9]+(?:", "[^A-Z0-9]*(?:").Replace(")?(?:", ")?[^A-Z0-9]*(?:");

            // add boundary restrictions
            show = @"(?:\b|_)" + show + @"(?:\b|_)";

            return new Regex(show, RegexOptions.IgnoreCase);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FileSearch"/> class.
        /// </summary>
        /// <param name="paths">The paths where to start the search.</param>
        /// <param name="show">The show to search for.</param>
        public FileSearch(IEnumerable<string> paths, TVShow show)
        {
            _checkFile    = StandardCheckFile;
            _titleRegex   = new[] { show.GenerateRegex() };
            _episodeRegex = new[] { default(Regex) };

            InitStartPaths(paths);
        }
Beispiel #4
0
        /// <summary>
        /// Loads an object from the stream.
        /// </summary>
        /// <param name="show">The show associated with the episode.</param>
        /// <param name="inbr">The source reader for episode listing.</param>
        /// <returns>
        /// Deserialized object.
        /// </returns>
        internal static Episode Load(TVShow show, BinaryReader inbr)
        {
            var ep = new Episode();

            ep.Show   = show;
            ep.Season = inbr.ReadByte();
            ep.Number = inbr.ReadByte();
            ep.ID     = ep.Number + (ep.Season * 1000) + (ep.Show.ID * 1000 * 1000);

            if (ep.Number == 255)
            {
                ep.Number += inbr.ReadByte();
            }

            ep.Airdate = ((double)inbr.ReadInt32()).GetUnixTimestamp();
            ep.Title   = inbr.ReadString();
            ep.Summary = inbr.ReadString();
            ep.Picture = inbr.ReadString();
            ep.URL     = inbr.ReadString();

            return(ep);
        }
 /// <summary>
 /// Modifies one or more properties of an existing TV show.
 /// </summary>
 /// <param name="show">The TV show in the database.</param>
 /// <param name="modification">The array of modified parameters.</param>
 public abstract void ModifyShow(TVShow show, params string[] modification);
 /// <summary>
 /// Removes an existing TV show.
 /// </summary>
 /// <param name="show">The TV show to be removed.</param>
 public abstract void RemoveShow(TVShow show);
Beispiel #7
0
        /// <summary>
        /// Updates the specified TV show in the database.
        /// </summary>
        /// <param name="show">The TV show to update.</param>
        /// <param name="callback">The status callback.</param>
        /// <returns>
        /// Updated TV show or <c>null</c>.
        /// </returns>
        public static TVShow Update(TVShow show, Action<int, string> callback = null)
        {
            Log.Info("Updating " + show.Title + "...");

            var st = DateTime.Now;

            if (callback != null)
            {
                callback(0, "Updating " + show.Title + "...");
            }

            Guide guide;
            try
            {
                guide = Updater.CreateGuide(show.Source);
            }
            catch (Exception ex)
            {
                Log.Error("Error while creating guide object for " + show.Title + ".", ex);

                if (callback != null)
                {
                    callback(-1, "Could not get guide object of type " + show.Source + " for " + show.Title + ".");
                }

                return null;
            }

            TVShow tv;
            try
            {
                tv = guide.GetData(show.SourceID, show.Language);
            }
            catch (Exception ex)
            {
                Log.Error("Error while downloading data from guide for " + show.Title + ".", ex);

                if (callback != null)
                {
                    callback(-1, "Could not get guide data for " + show.Source + "#" + show.SourceID + ".");
                }

                return null;
            }

            tv.ID          = show.ID;
            tv.Data        = show.Data;
            tv.Directory   = show.Directory;
            tv.EpisodeByID = new Dictionary<int, Episode>();

            if (tv.Title != show.Title)
            {
                tv.Title = show.Title;
            }

            foreach (var ep in tv.Episodes)
            {
                ep.Show = tv;
                ep.ID   = ep.Number + (ep.Season * 1000) + (tv.ID * 1000 * 1000);

                tv.EpisodeByID[ep.Number + (ep.Season * 1000)] = ep;

                Episode op;
                if (show.EpisodeByID.TryGetValue(ep.Number + (ep.Season * 1000), out op) && op.Watched)
                {
                    ep.Watched = true;
                }

                if (!string.IsNullOrWhiteSpace(tv.AirTime) && ep.Airdate != Utils.UnixEpoch)
                {
                    ep.Airdate = DateTime.Parse(ep.Airdate.ToString("yyyy-MM-dd ") + tv.AirTime).ToLocalTimeZone(tv.TimeZone);
                }
            }

            try
            {
                tv.Save();
            }
            catch (Exception ex)
            {
                Log.Error("Error while saving updated database for " + show.Title + ".", ex);

                if (callback != null)
                {
                    callback(-1, "Could not save database for " + show.Title + ".");
                }

                return null;
            }

            TVShows[tv.ID] = tv;
            DataChange = DateTime.Now;

            if (callback != null)
            {
                callback(1, "Updated " + show.Title + ".");
            }

            Log.Debug("Successfully updated " + show.Title + " in " + (DateTime.Now - st).TotalSeconds + "s.");

            return tv;
        }
 /// <summary>
 /// Adds a new TV show.
 /// </summary>
 /// <param name="show">The newly added TV show.</param>
 public abstract void AddShow(TVShow show);
        /// <summary>
        /// Loads an object from the directory.
        /// </summary>
        /// <param name="dir">The source directory.</param>
        /// <returns>
        /// Deserialized object.
        /// </returns>
        public static TVShow Load(string dir)
        {
            var show = new TVShow { Directory = dir };

            using (var info = File.OpenRead(Path.Combine(dir, "info")))
            using (var conf = File.OpenRead(Path.Combine(dir, "conf")))
            using (var seen = File.OpenRead(Path.Combine(dir, "seen")))
            using (var inbr = new BinaryReader(info))
            using (var cobr = new BinaryReader(conf))
            using (var sebr = new BinaryReader(seen))
            {
                int epnr;

                var sver = inbr.ReadByte();
                var supd = inbr.ReadUInt32();

                show.Title       = inbr.ReadString();
                show.Source      = inbr.ReadString();
                show.SourceID    = inbr.ReadString();
                show.Description = inbr.ReadString();
                show.Genre       = inbr.ReadString();
                show.Cover       = inbr.ReadString();
                show.Airing      = inbr.ReadBoolean();
                show.AirTime     = inbr.ReadString();
                show.AirDay      = inbr.ReadString();
                show.Network     = inbr.ReadString();
                show.Runtime     = inbr.ReadByte();
                show.TimeZone    = inbr.ReadString();
                show.Language    = inbr.ReadString();
                show.URL         = inbr.ReadString();

                epnr = inbr.ReadUInt16();

                var dver = cobr.ReadByte();
                var dupd = cobr.ReadUInt32();
                var dcnt = cobr.ReadUInt16();

                show.Data = new Dictionary<string, string>();

                for (var i = 0; i < dcnt; i++)
                {
                    show.Data[cobr.ReadString()] = cobr.ReadString();
                }

                show.ID     = int.Parse(show.Data["showid"]);
                show._rowId = int.Parse(show.Data["rowid"]);

                string ctitle;
                if (show.Data.TryGetValue("title", out ctitle))
                {
                    show._title = ctitle;
                }

                show.Episodes    = new List<Episode>(epnr);
                show.EpisodeByID = new Dictionary<int, Episode>();

                for (var i = 0; i < epnr; i++)
                {
                    var ep = Episode.Load(show, inbr);
                    show.Episodes.Add(ep);
                    show.EpisodeByID[ep.Season * 1000 + ep.Number] = ep;
                }

                var tver = sebr.ReadByte();
                var tupd = sebr.ReadUInt32();
                var tcnt = sebr.ReadUInt16();

                for (var i = 0; i < tcnt; i++)
                {
                    var sn = sebr.ReadByte();
                    var en = sebr.ReadByte();

                    if (en == 255)
                    {
                        en += sebr.ReadByte();
                    }

                    try { show.EpisodeByID[sn * 1000 + en].Watched = true; } catch (KeyNotFoundException) { }
                }
            }

            return show;
        }
Beispiel #10
0
        /// <summary>
        /// Removes the specified TV show from the database.
        /// </summary>
        /// <param name="show">The TV show to remove.</param>
        /// <param name="callback">The status callback.</param>
        /// <returns>
        ///   <c>true</c> on success; otherwise, <c>false</c>.
        /// </returns>
        public static bool Remove(TVShow show, Action<int, string> callback = null)
        {
            Log.Info("Removing " + show.Title + "...");

            if (callback != null)
            {
                callback(0, "Removing " + show.Title + "...");
            }

            try
            {
                Directory.Delete(show.Directory, true);
            }
            catch (Exception ex)
            {
                Log.Error("Error while removing " + show.Title + ".", ex);

                if (callback != null)
                {
                    callback(-1, "Could not remove database for " + show.Title + ".");
                }

                return false;
            }

            TVShows.Remove(show.ID);
            DataChange = DateTime.Now;

            if (Library.Files != null && Library.Files.Count != 0)
            {
                foreach (var ep in Library.Files)
                {
                    if (Math.Floor((double)ep.Key / 1000 / 1000) == show.ID)
                    {
                        ep.Value.Clear();
                    }
                }

                Library.SaveList();
            }

            if (callback != null)
            {
                callback(1, "Removed " + show.Title + ".");
            }

            return true;
        }
 /// <summary>
 /// Unmarks one or more episodes.
 /// </summary>
 /// <param name="show">The TV show in the database.</param>
 /// <param name="episodes">The list of episode ranges. A range consists of two numbers from the same season.</param>
 public override void UnmarkEpisodes(TVShow show, params int[][] episodes)
 {
     Log.Debug("Queued change: unmark " + show.Title + " episodes " + episodes.Aggregate(string.Empty, (c, i) => c + ", " + string.Join(", ", i)).TrimStart(", ".ToCharArray()));
     _changes.Enqueue(new Change(show, ChangeType.UnmarkEpisode, episodes));
     _timer.Start();
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ShowFile" /> class.
        /// </summary>
        /// <param name="name">The name of the original file.</param>
        /// <param name="show">The name of the show.</param>
        /// <param name="ep">The parsed season and episode.</param>
        /// <param name="title">The title of the episode.</param>
        /// <param name="quality">The quality of the file.</param>
        /// <param name="group">The group.</param>
        /// <param name="airdate">The airdate of the episode.</param>
        /// <param name="dbtvshow">The TV show in the local database.</param>
        /// <param name="dbepisode">The episode in the local database.</param>
        /// <param name="success">if set to <c>true</c> the file was successfully parsed.</param>
        public ShowFile(string name, string show, ShowEpisode ep, string title, string quality, string group, DateTime airdate, TVShow dbtvshow = null, Episode dbepisode = null, bool success = true)
        {
            Name          = name;
            Extension     = Path.GetExtension(Name);
            Show          = show;
            Episode       = ep;
            Title         = title;
            Quality       = quality;
            Group         = group;
            Airdate       = airdate;
            Success       = success;
            DbTVShow      = dbtvshow;
            DbEpisode     = dbepisode;

            if (DbTVShow != null || DbEpisode != null)
            {
                Local = true;
            }
        }
 /// <summary>
 /// Unmarks one or more episodes.
 /// </summary>
 /// <param name="show">The TV show in the database.</param>
 /// <param name="episodes">The list of episode ranges. A range consists of two numbers from the same season.</param>
 public abstract void UnmarkEpisodes(TVShow show, params int[][] episodes);
Beispiel #14
0
        /// <summary>
        /// Loads an object from the stream.
        /// </summary>
        /// <param name="show">The show associated with the episode.</param>
        /// <param name="inbr">The source reader for episode listing.</param>
        /// <returns>
        /// Deserialized object.
        /// </returns>
        internal static Episode Load(TVShow show, BinaryReader inbr)
        {
            var ep = new Episode();

            ep.Show   = show;
            ep.Season = inbr.ReadByte();
            ep.Number = inbr.ReadByte();
            ep.ID     = ep.Number + (ep.Season * 1000) + (ep.Show.ID * 1000 * 1000);

            if (ep.Number == 255)
            {
                ep.Number += inbr.ReadByte();
            }

            ep.Airdate = ((double)inbr.ReadUInt32()).GetUnixTimestamp();
            ep.Title   = inbr.ReadString();
            ep.Summary = inbr.ReadString();
            ep.Picture = inbr.ReadString();
            ep.URL     = inbr.ReadString();

            return ep;
        }
        /// <summary>
        /// Serializes the list of marked episodes for the specified TV show.
        /// </summary>
        /// <param name="show">The TV show in the database.</param>
        /// <param name="range">if set to <c>true</c> sequential episode numbering will be turned into ranges.</param>
        /// <returns>
        /// List of marked episode ranges.
        /// </returns>
        public static object SerializeMarkedEpisodes(TVShow show, bool range = true)
        {
            var eps = show.Episodes.Where(e => e.Watched).OrderBy(e => e.ID).Select(e => e.ID - e.Show.ID * 1000000);

            if (!range)
            {
                return eps;
            }

            var list  = new List<object>();
            var start = 0;
            var prev  = 0;

            foreach (var ep in eps)
            {
                if (prev == ep - 1)
                {
                    prev = ep;
                }
                else
                {
                    if (start != 0 && prev != 0)
                    {
                        list.Add(start == prev ? start : (object)new[] { start, prev });
                    }

                    start = prev = ep;
                }
            }

            if ((list.Count == 0 && start != 0 && prev != 0) || (list.Count != 0 && list.Last() != new[] { start, prev }))
            {
                list.Add(start == prev ? start : (object)new[] { start, prev });
            }

            return list;
        }
            /// <summary>
            /// Initializes a new instance of the <see cref="Change" /> class.
            /// </summary>
            /// <param name="show">The show.</param>
            /// <param name="type">The type.</param>
            /// <param name="data">The data.</param>
            public Change(TVShow show, ChangeType type, object data = null)
            {
                Time = (DateTime.UtcNow.Ticks - 621355968000000000d) / 10000000d;

                Title    = show.Title;
                ShowID   = show.ID;
                Source   = show.Source;
                SourceID = show.SourceID;
                Language = show.Language;

                Type = type;
                Data = data ?? string.Empty;
            }
 /// <summary>
 /// Removes an existing TV show.
 /// </summary>
 /// <param name="show">The TV show to be removed.</param>
 public override void RemoveShow(TVShow show)
 {
     Log.Debug("Queued change: remove " + show.Title);
     _changes.Enqueue(new Change(show, ChangeType.RemoveShow));
     _timer.Start();
 }
 /// <summary>
 /// Modifies one or more properties of an existing TV show.
 /// </summary>
 /// <param name="show">The TV show in the database.</param>
 /// <param name="modification">The array of modified parameters.</param>
 public override void ModifyShow(TVShow show, params string[] modification)
 {
     Log.Debug("Queued change: modify " + show.Title);
     _changes.Enqueue(new Change(show, ChangeType.ModifyShow, new Dictionary<string, string>(show.Data)));
     _timer.Start();
 }
 /// <summary>
 /// Adds a new TV show.
 /// </summary>
 /// <param name="show">The newly added TV show.</param>
 public override void AddShow(TVShow show)
 {
     Log.Debug("Queued change: add " + show.Title);
     _changes.Enqueue(new Change(show, ChangeType.AddShow, new Dictionary<string, string>(show.Data)));
     _timer.Start();
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="GuideDropDownTVShowItem"/> class.
 /// </summary>
 /// <param name="tvShow">The TV show.</param>
 public GuideDropDownTVShowItem(TVShow tvShow)
 {
     Show = tvShow;
 }
 /// <summary>
 /// Selects the show.
 /// </summary>
 /// <param name="show">The TV show.</param>
 public void SelectShow(TVShow show)
 {
     for (var i = 0; i < comboBox.Items.Count; i++)
     {
         if (comboBox.Items[i] is GuideDropDownTVShowItem && ((GuideDropDownTVShowItem)comboBox.Items[i]).Show == show)
         {
             comboBox.SelectedIndex = i;
             break;
         }
     }
 }
        /// <summary>
        /// Loads an object from the directory.
        /// </summary>
        /// <param name="dir">The source directory.</param>
        /// <returns>
        /// Deserialized object.
        /// </returns>
        public static TVShow Load(string dir)
        {
            var show = new TVShow {
                Directory = dir
            };

            using (var info = File.OpenRead(Path.Combine(dir, "info")))
                using (var conf = File.OpenRead(Path.Combine(dir, "conf")))
                    using (var seen = File.OpenRead(Path.Combine(dir, "seen")))
                        using (var inbr = new BinaryReader(info))
                            using (var cobr = new BinaryReader(conf))
                                using (var sebr = new BinaryReader(seen))
                                {
                                    int epnr;

                                    var sver = inbr.ReadByte();
                                    var supd = inbr.ReadUInt32();

                                    show.Title       = inbr.ReadString();
                                    show.Source      = inbr.ReadString();
                                    show.SourceID    = inbr.ReadString();
                                    show.Description = inbr.ReadString();
                                    show.Genre       = inbr.ReadString();
                                    show.Cover       = inbr.ReadString();
                                    show.Airing      = inbr.ReadBoolean();
                                    show.AirTime     = inbr.ReadString();
                                    show.AirDay      = inbr.ReadString();
                                    show.Network     = inbr.ReadString();
                                    show.Runtime     = inbr.ReadByte();
                                    show.TimeZone    = inbr.ReadString();
                                    show.Language    = inbr.ReadString();
                                    show.URL         = inbr.ReadString();

                                    epnr = inbr.ReadUInt16();

                                    var dver = cobr.ReadByte();
                                    var dupd = cobr.ReadUInt32();
                                    var dcnt = cobr.ReadUInt16();

                                    show.Data = new Dictionary <string, string>();

                                    for (var i = 0; i < dcnt; i++)
                                    {
                                        show.Data[cobr.ReadString()] = cobr.ReadString();
                                    }

                                    show.ID     = int.Parse(show.Data["showid"]);
                                    show._rowId = int.Parse(show.Data["rowid"]);

                                    string ctitle;
                                    if (show.Data.TryGetValue("title", out ctitle))
                                    {
                                        show._title = ctitle;
                                    }

                                    show.Episodes    = new List <Episode>(epnr);
                                    show.EpisodeByID = new Dictionary <int, Episode>();

                                    for (var i = 0; i < epnr; i++)
                                    {
                                        var ep = Episode.Load(show, inbr);
                                        show.Episodes.Add(ep);
                                        show.EpisodeByID[ep.Season * 1000 + ep.Number] = ep;
                                    }

                                    var tver = sebr.ReadByte();
                                    var tupd = sebr.ReadUInt32();
                                    var tcnt = sebr.ReadUInt16();

                                    for (var i = 0; i < tcnt; i++)
                                    {
                                        var sn = sebr.ReadByte();
                                        var en = sebr.ReadByte();

                                        if (en == 255)
                                        {
                                            en += sebr.ReadByte();
                                        }

                                        try { show.EpisodeByID[sn * 1000 + en].Watched = true; } catch (KeyNotFoundException) { }
                                    }
                                }

            return(show);
        }
 /// <summary>
 /// Unmarks one or more episodes.
 /// </summary>
 /// <param name="show">The TV show in the database.</param>
 /// <param name="episodes">The list of episodes.</param>
 public override void UnmarkEpisodes(TVShow show, params int[] episodes)
 {
     Log.Debug("Queued change: unmark " + show.Title + " episodes " + string.Join(", ", episodes));
     _changes.Enqueue(new Change(show, ChangeType.UnmarkEpisode, episodes));
     _timer.Start();
 }