예제 #1
0
        /// <summary>
        /// syncs the watched state locally from trakt.tv
        /// </summary>
        public static void SyncTraktWatchedState()
        {
            if (string.IsNullOrEmpty(TraktAPI.Username) || string.IsNullOrEmpty(TraktAPI.Password))
            {
                return;
            }

            // Get all local unwatched episodes
            SQLCondition     conditions = new SQLCondition(new DBOnlineEpisode(), DBOnlineEpisode.cWatched, false, SQLConditionType.Equal);
            List <DBEpisode> episodes   = DBEpisode.Get(conditions, false);

            var watchedItems = TraktAPI.GetUserWatched(TraktAPI.Username);

            MPTVSeriesLog.Write("Trakt: Syncronizing Watched/Seen from trakt.tv");

            // go through all unwatched episodes and check if watched online
            foreach (DBEpisode episode in episodes)
            {
                // if the episode exists on server response
                // then we mark as watched locally
                if (HasEpisode(watchedItems, episode))
                {
                    MPTVSeriesLog.Write("Trakt: Marking '{0}' as watched", episode.ToString());
                    episode[DBOnlineEpisode.cWatched]   = true;
                    episode[DBOnlineEpisode.cTraktSeen] = true;
                    episode.Commit();
                }
            }

            MPTVSeriesLog.Write("Finished Syncronizing Watched/Seen state from trakt.tv");
        }
예제 #2
0
        /// <summary>
        /// Create PlayListItem from TvSeries episode id
        /// </summary>
        /// <param name="compositeId">Composite id of episode</param>
        /// <returns>PlayListItem item</returns>
        internal static MediaPortal.Playlists.PlayListItem CreatePlaylistItemFromEpisode(String compositeId)
        {
            var episodes = DBEpisode.Get(new SQLCondition(new DBTable("online_episodes"), "CompositeID", new DBValue(compositeId), SQLConditionType.Equal));
            var episode  = episodes.FirstOrDefault(e => !string.IsNullOrEmpty(e[DBEpisode.cFilename]));

            return(CreatePlaylistItemFromEpisode(episode));
        }
예제 #3
0
        public List <DBEpisode> getEpisodeItems(int stepIndex, string[] currentStepSelection)
        {
            MPTVSeriesLog.Write("View: Get Episodes", MPTVSeriesLog.LogLevel.Debug);
            SQLCondition conditions = null;

            if (stepIndex >= m_steps.Count)
            {
                return(null);                            // wrong index specified!!
            }
            addHierarchyConditions(ref stepIndex, ref currentStepSelection, ref conditions);

            MPTVSeriesLog.Write("View: Get Episodes: Executing SQL", MPTVSeriesLog.LogLevel.Debug);
            List <DBEpisode> eps = DBEpisode.Get(conditions);

            // WARNING: this naturally only works if the ordering is by season/episodeOrder
            // inline the special episodes to there relevant positions (Season == 0 by airsbefore_episode)
            MPTVSeriesLog.Write("View: Sorting Episodes", MPTVSeriesLog.LogLevel.Debug);
            if (m_steps[stepIndex].inLineSpecials && currentStepSelection[currentStepSelection.Length - 1] != "0")
            {
                if (m_steps[stepIndex].inLineSpecialsAsc)
                {
                    eps = Helper.inverseList <DBEpisode>(eps);
                }
                eps.Sort();
            }
            return(eps);
        }
예제 #4
0
        void MarkEpisodeAsWatched(DBEpisode episode)
        {
            // Could be a double episode, so mark both as watched
            SQLCondition condition = new SQLCondition();

            condition.Add(new DBEpisode(), DBEpisode.cFilename, episode[DBEpisode.cFilename], SQLConditionType.Equal);
            List <DBEpisode> episodes = DBEpisode.Get(condition, false);

            foreach (DBEpisode ep in episodes)
            {
                string date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                ep[DBOnlineEpisode.cWatched]         = 1;
                ep[DBOnlineEpisode.cPlayCount]       = ep[DBOnlineEpisode.cPlayCount] + 1;
                ep[DBEpisode.cDateWatched]           = date;
                ep[DBOnlineEpisode.cLastWatchedDate] = date;
                if (string.IsNullOrEmpty(ep[DBOnlineEpisode.cFirstWatchedDate]))
                {
                    ep[DBOnlineEpisode.cFirstWatchedDate] = date;
                }
                ep.Commit();
            }
            // Update Episode Counts
            DBSeries series = Helper.getCorrespondingSeries(m_currentEpisode[DBEpisode.cSeriesID]);
            DBSeason season = Helper.getCorrespondingSeason(episode[DBEpisode.cSeriesID], episode[DBEpisode.cSeasonIndex]);

            DBSeason.UpdateEpisodeCounts(series, season);
        }
예제 #5
0
        /// <summary>
        /// Playback the first unwatched episode for a series using TVSeries internal Video Handler
        /// If no Unwatched episodes exists, play the Most Recently Aired
        ///
        /// Taken from Trakt-for-MediaPortal:
        /// https://github.com/Technicolour/Trakt-for-Mediaportal/blob/master/TraktPlugin/TraktHandlers/TVSeries.cs
        /// </summary>
        /// <param name="seriesid">series id of episode</param>
        /// <param name="resume">Resume from last stop?</param>
        public static void PlayFirstUnwatchedEpisode(int seriesid, bool resume)
        {
            var episodes = DBEpisode.Get(seriesid);

            if (episodes == null || episodes.Count == 0)
            {
                return;
            }

            // filter out anything we can't play
            episodes.RemoveAll(e => string.IsNullOrEmpty(e[DBEpisode.cFilename]));
            if (episodes.Count == 0)
            {
                return;
            }

            // sort episodes using DBEpisode sort comparer
            // this takes into consideration Aired/DVD order and Specials in-line sorting
            episodes.Sort();

            // get first episode unwatched, otherwise get most recently aired
            var episode = episodes.Where(e => e[DBOnlineEpisode.cWatched] == 0).FirstOrDefault();

            if (episode == null)
            {
                WifiRemote.LogMessage("No Unwatched episodes found, Playing most recent episode", WifiRemote.LogType.Info);
                episode = episodes.LastOrDefault();
            }

            if (episode != null)
            {
                PlayEpisode(episode, resume);
            }
        }
예제 #6
0
        /// <summary>
        /// Play an episode of a specific series and season
        ///
        /// Thanks to Trakt-for-MediaPortal:
        /// https://github.com/Technicolour/Trakt-for-Mediaportal/blob/master/TraktPlugin/TraktHandlers/TVSeries.cs
        /// </summary>
        /// <param name="compositeId">Composite id of the episode</param>
        /// <paraparam name="resume">Resume from last stop?</paraparam>
        /// <param name="startPosition">Position from which the video should start in seconds (e.g. StartPosition=180 will start the episode 3 minutes into the video). Will be ignored if AskToResume is true.</param>
        public static void PlayEpisode(String compositeId, bool resume, int startPosition)
        {
            var episodes = DBEpisode.Get(new SQLCondition(new DBTable("online_episodes"), "CompositeID", new DBValue(compositeId), SQLConditionType.Equal));
            var episode  = episodes.FirstOrDefault(e => !string.IsNullOrEmpty(e[DBEpisode.cFilename]));

            if (episode == null)
            {
                return;
            }

            PlayEpisode(episode, resume, startPosition);;
        }
예제 #7
0
        /// <summary>
        /// Play an episode of a specific series and season
        ///
        /// Thanks to Trakt-for-MediaPortal:
        /// https://github.com/Technicolour/Trakt-for-Mediaportal/blob/master/TraktPlugin/TraktHandlers/TVSeries.cs
        /// </summary>
        /// <param name="seriesId">ID of the series</param>
        /// <param name="seasonNumber">Number of the season</param>
        /// <param name="episodeNumber">Number of the episode</param>
        /// <paraparam name="resume">Resume from last stop?</paraparam>
        /// <param name="startPosition">Position from which the video should start in seconds (e.g. StartPosition=180 will start the episode 3 minutes into the video). Will be ignored if AskToResume is true.</param>
        public static void Play(int seriesId, int seasonNumer, int episodeNumber, bool resume, int startPosition = 0)
        {
            var episodes = DBEpisode.Get(seriesId, seasonNumer);
            var episode  = episodes.FirstOrDefault(e => (e[DBEpisode.cEpisodeIndex] == episodeNumber || e[DBEpisode.cEpisodeIndex2] == episodeNumber) && !string.IsNullOrEmpty(e[DBEpisode.cFilename]));

            if (episode == null)
            {
                return;
            }

            PlayEpisode(episode, resume, startPosition);
        }
예제 #8
0
        /// <summary>
        /// Create PlayListItem from TvSeries show
        /// </summary>
        /// <param name="seriesId">Id of show</param>
        /// <returns>PlayListItem item</returns>
        internal static List <MediaPortal.Playlists.PlayListItem> CreatePlaylistItemsFromShow(int seriesId)
        {
            List <MediaPortal.Playlists.PlayListItem> returnList = new List <MediaPortal.Playlists.PlayListItem>();
            var episodes = DBEpisode.Get(seriesId);

            foreach (DBEpisode e in episodes)
            {
                returnList.Add(CreatePlaylistItemFromEpisode(e));
            }

            return(returnList);
        }
예제 #9
0
        private bool AddItem(string episodeID)
        {
            SQLCondition condition = new SQLCondition();

            condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cID, episodeID, SQLConditionType.Equal);

            List <DBEpisode> ep = DBEpisode.Get(condition, false);

            if (ep.Count > 0)
            {
                PlayListItem newItem = new PlayListItem(ep[0]);
                playlist.Add(newItem);
            }
            return(true);
        }
예제 #10
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="filename">Filename of the currently played episode</param>
        public NowPlayingSeries(string filename)
        {
            try
            {
                SQLCondition     query    = new SQLCondition(new DBEpisode(), DBEpisode.cFilename, filename, SQLConditionType.Equal);
                List <DBEpisode> episodes = DBEpisode.Get(query);

                if (episodes.Count > 0)
                {
                    episodeFound = true;

                    SeriesId    = episodes[0].onlineEpisode[DBOnlineEpisode.cSeriesID];
                    SeasonId    = episodes[0].onlineEpisode[DBOnlineEpisode.cSeasonID];
                    EpisodeId   = episodes[0].onlineEpisode[DBOnlineEpisode.cID];
                    CompositeId = episodes[0].fullItem[DBEpisode.cCompositeID];

                    Episode     = episodes[0].onlineEpisode[DBOnlineEpisode.cEpisodeIndex];
                    Season      = episodes[0].onlineEpisode[DBOnlineEpisode.cSeasonIndex];
                    Plot        = episodes[0].onlineEpisode[DBOnlineEpisode.cEpisodeSummary];
                    Title       = episodes[0].onlineEpisode[DBOnlineEpisode.cEpisodeName];
                    Director    = episodes[0].onlineEpisode[DBOnlineEpisode.cDirector];
                    Writer      = episodes[0].onlineEpisode[DBOnlineEpisode.cWriter];
                    Rating      = episodes[0].onlineEpisode[DBOnlineEpisode.cRating];
                    MyRating    = episodes[0].onlineEpisode[DBOnlineEpisode.cMyRating];
                    RatingCount = episodes[0].onlineEpisode[DBOnlineEpisode.cRatingCount];
                    AirDate     = episodes[0].onlineEpisode[DBOnlineEpisode.cFirstAired];

                    DBSeries s = Helper.getCorrespondingSeries(episodes[0].onlineEpisode[DBOnlineEpisode.cSeriesID]);
                    Series = s[DBOnlineSeries.cPrettyName];
                    Status = s[DBOnlineSeries.cStatus];
                    Genre  = s[DBOnlineSeries.cGenre];

                    // Get season poster path
                    DBSeason season = DBSeason.getRaw(SeriesId, episodes[0].onlineEpisode[DBOnlineEpisode.cSeasonIndex]);
                    ImageName = ImageAllocator.GetSeasonBannerAsFilename(season);

                    // Fall back to series poster if no season poster is available
                    if (String.IsNullOrEmpty(ImageName))
                    {
                        ImageName = ImageAllocator.GetSeriesPosterAsFilename(s);
                    }
                }
            }
            catch (Exception e)
            {
                WifiRemote.LogMessage("Error getting now playing tvseries: " + e.Message, WifiRemote.LogType.Error);
            }
        }
예제 #11
0
        public static LatestMediaHandler.MQTTItem CheckDB(string SearchFile)
        {
            LatestMediaHandler.MQTTItem item = new LatestMediaHandler.MQTTItem();
            if (MQTTPlugin.DebugMode)
            {
                Logger.Debug("Check to see if video is in MP-TVSeries database.");
            }

            if (Utils.IsAssemblyAvailable("MP-TVSeries", new Version(2, 6, 3, 1242)))
            {
                if (MQTTPlugin.DebugMode)
                {
                    Logger.Debug("MP-TVSeries found, searching Database for: " + SearchFile);
                }
                try
                {
                    SQLCondition     query    = new SQLCondition(new DBEpisode(), DBEpisode.cFilename, SearchFile, SQLConditionType.Equal);
                    List <DBEpisode> episodes = DBEpisode.Get(query);
                    if (MQTTPlugin.DebugMode)
                    {
                        Logger.Debug("Found: " + episodes.Count.ToString() + " episodes.");
                    }
                    if (episodes.Count > 0)
                    {
                        DBSeries s = Helper.getCorrespondingSeries(episodes[0].onlineEpisode[DBOnlineEpisode.cSeriesID]);
                        if (MQTTPlugin.DebugMode)
                        {
                            Logger.Debug("Video is in MP-TVSeries database.");
                        }

                        item.Id       = episodes[0][DBEpisode.cSeriesID];
                        item.Title    = s.ToString() + " - " + episodes[0][DBEpisode.cEpisodeName];
                        item.Filename = SearchFile;
                        item.Genres   = s[DBOnlineSeries.cGenre];
                        item.GetArtwork("tv");
                    }
                }
                catch (Exception e)
                {
                    Logger.Error("Error getting info from TVSeries Database: " + e.Message);
                }
            }
            return(item);
        }
예제 #12
0
        public static List <DBEpisode> GetEpisodesToSync(DBSeries series, TraktSyncModes mode)
        {
            List <DBEpisode> episodes = new List <DBEpisode>();

            SQLCondition conditions = new SQLCondition();

            if (series == null)
            {
                // Get episodes for every series
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, 0, SQLConditionType.GreaterThan);
            }
            else
            {
                // Get episodes for a single series
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, series[DBSeries.cID], SQLConditionType.Equal);
            }

            switch (mode)
            {
            case TraktSyncModes.library:
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cTraktLibrary, 0, SQLConditionType.Equal);
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cHidden, 0, SQLConditionType.Equal);
                conditions.Add(new DBEpisode(), DBEpisode.cFilename, string.Empty, SQLConditionType.NotEqual);
                episodes = DBEpisode.Get(conditions, false);
                break;

            case TraktSyncModes.seen:
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cHidden, 0, SQLConditionType.Equal);
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cWatched, 1, SQLConditionType.Equal);
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 0, SQLConditionType.Equal);
                episodes = DBEpisode.Get(conditions, false);
                break;

            case TraktSyncModes.unseen:
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cHidden, 0, SQLConditionType.Equal);
                conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cTraktSeen, 2, SQLConditionType.Equal);
                episodes = DBEpisode.Get(conditions, false);
                break;
            }

            return(episodes);
        }
예제 #13
0
        public void HideSeason(bool hide)
        {
            MPTVSeriesLog.Write(string.Format("{0} series {1}, season {2} from view", (hide ? "Hiding" : "UnHiding"), Helper.getCorrespondingSeries(this[DBSeason.cSeriesID]), this[DBSeason.cIndex]));

            // respect 'Show Local Files Only' setting
            List <DBEpisode> episodes = DBEpisode.Get(int.Parse(this[DBSeason.cSeriesID]), int.Parse((this[DBSeason.cIndex])));

            if (episodes != null)
            {
                foreach (DBEpisode episode in episodes)
                {
                    // Hide Episodes
                    episode.HideEpisode(hide);
                }
            }

            // Hide Season
            this[DBSeason.cHidden] = hide;
            this.Commit();
        }
예제 #14
0
        /// <summary>
        /// Play a random episode of a series
        /// </summary>
        /// <param name="seriesId">ID of a series</param>
        /// <param name="resume">Resume from last stop?</param>
        public static void PlayRandomEpisode(int seriesId, bool resume)
        {
            List <DBEpisode> episodes = DBEpisode.Get(seriesId);

            if (episodes == null || episodes.Count == 0)
            {
                return;
            }

            // filter out anything we can't play
            episodes.RemoveAll(e => string.IsNullOrEmpty(e[DBEpisode.cFilename]));
            if (episodes.Count == 0)
            {
                return;
            }


            DBEpisode episode = episodes.GetRandomElement <DBEpisode>();

            if (episode != null)
            {
                PlayEpisode(episode, resume);
            }
        }
예제 #15
0
        public List <string> deleteSeason(TVSeriesPlugin.DeleteMenuItems type)
        {
            List <string> resultMsg = new List <string>();

            // Always delete from Local episode table if deleting from disk or database
            SQLCondition condition = new SQLCondition();

            condition.Add(new DBEpisode(), DBEpisode.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
            condition.Add(new DBEpisode(), DBEpisode.cSeasonIndex, this[DBSeason.cIndex], SQLConditionType.Equal);

            /* TODO will include hidden episodes as hidden attribute is only in onlineepisodes. maybe we should include it in localepisodes also..
             * if hidden episodes are excluded then the if (resultMsg.Count is wrong and should do another select to get proper count
             * if (!DBOption.GetOptions(DBOption.cShowHiddenItems))
             * {
             *  //don't include hidden seasons unless the ShowHiddenItems option is set
             *  condition.Add(new DBEpisode(), idden, 0, SQLConditionType.Equal);
             * }
             */

            List <DBEpisode> episodes = DBEpisode.Get(condition, false);

            if (episodes != null)
            {
                bool hasLocalEpisodesToDelete = episodes.Exists(e => !string.IsNullOrEmpty(e[DBEpisode.cFilename]));
                hasLocalEpisodesToDelete &= (type == TVSeriesPlugin.DeleteMenuItems.disk || type == TVSeriesPlugin.DeleteMenuItems.diskdatabase);

                DBSeries series     = Helper.getCorrespondingSeries(this[DBSeason.cSeriesID]);
                string   seriesName = series == null ? this[DBSeason.cSeriesID].ToString() : series.ToString();

                // show progress dialog as this can be a long process esp for network drives
                // will show new progress for each season if deleting from the series level
                GUIDialogProgress progressDialog = null;
                if (!Settings.isConfig)
                {
                    progressDialog = (GUIDialogProgress)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_PROGRESS);
                    progressDialog.Reset();
                    progressDialog.DisplayProgressBar = true;
                    progressDialog.ShowWaitCursor     = false;
                    progressDialog.DisableCancel(true);
                    progressDialog.SetHeading(Translation.Delete);
                    progressDialog.Percentage = 0;
                    progressDialog.SetLine(1, string.Format("{0} {1} {2}", seriesName, Translation.Season, this[DBSeason.cIndex]));
                    progressDialog.SetLine(2, string.Empty);

                    // only show progress dialog if we have local files in season
                    if (hasLocalEpisodesToDelete)
                    {
                        progressDialog.StartModal(GUIWindowManager.ActiveWindow);
                    }
                }

                int counter = 0;

                foreach (DBEpisode episode in episodes)
                {
                    string episodeName = string.Format("{0}x{1} - {2}", episode[DBOnlineEpisode.cSeasonIndex], episode[DBOnlineEpisode.cEpisodeIndex], episode[DBOnlineEpisode.cEpisodeName]);
                    if (!Settings.isConfig)
                    {
                        progressDialog.SetLine(2, episodeName);
                    }
                    if (!Settings.isConfig)
                    {
                        GUIWindowManager.Process();
                    }

                    resultMsg.AddRange(episode.deleteEpisode(type, true));

                    if (!Settings.isConfig)
                    {
                        progressDialog.Percentage = Convert.ToInt32(((double)++counter / (double)episodes.Count) * 100.0);
                    }
                    if (!Settings.isConfig)
                    {
                        GUIWindowManager.Process();
                    }
                }

                // close progress dialog
                if (!Settings.isConfig)
                {
                    progressDialog.Close();
                }

                // if we have removed all episodes in season without error, cleanup the online table
                if (resultMsg.Count == 0 && type != TVSeriesPlugin.DeleteMenuItems.disk)
                {
                    condition = new SQLCondition();
                    condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                    condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeasonIndex, this[DBSeason.cIndex], SQLConditionType.Equal);
                    DBOnlineEpisode.Clear(condition);
                }
            }

            #region Facade Remote Color
            // if we were successful at deleting all episodes of season from disk, set HasLocalFiles to false
            // note: we only do this if the database entries still exist
            if (resultMsg.Count == 0 && type == TVSeriesPlugin.DeleteMenuItems.disk)
            {
                this[cHasLocalFiles] = false;
                this.Commit();
            }

            // if we were successful at deleting all episodes of season from disk,
            // also check if any local episodes exist on disk for series and set HasLocalFiles to false
            if (resultMsg.Count == 0 && type != TVSeriesPlugin.DeleteMenuItems.database)
            {
                // Check Series for Local Files
                SQLCondition episodeConditions = new SQLCondition();
                episodeConditions.Add(new DBEpisode(), DBEpisode.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                List <DBEpisode> localEpisodes = DBEpisode.Get(episodeConditions);
                if (localEpisodes.Count == 0 && !DBSeries.IsSeriesRemoved)
                {
                    DBSeries series = DBSeries.Get(this[DBSeason.cSeriesID]);
                    if (series != null)
                    {
                        series[DBOnlineSeries.cHasLocalFiles] = false;
                        series.Commit();
                    }
                }
            }
            #endregion

            #region Cleanup

            // if there are no error messages and if we need to delete from db
            if (resultMsg.Count == 0 && type != TVSeriesPlugin.DeleteMenuItems.disk)
            {
                condition = new SQLCondition();
                condition.Add(new DBSeason(), DBSeason.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                condition.Add(new DBSeason(), DBSeason.cIndex, this[DBSeason.cIndex], SQLConditionType.Equal);
                DBSeason.Clear(condition);
            }

            DBSeries.IsSeriesRemoved = false;
            if (type != TVSeriesPlugin.DeleteMenuItems.disk)
            {
                // If local/online episode count is zero then delete the series and all seasons
                condition = new SQLCondition();
                condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                episodes = DBEpisode.Get(condition, false);
                if (episodes.Count == 0)
                {
                    // Delete Seasons
                    condition = new SQLCondition();
                    condition.Add(new DBSeason(), DBSeason.cSeriesID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                    DBSeason.Clear(condition);

                    // Delete Local Series
                    condition = new SQLCondition();
                    condition.Add(new DBSeries(), DBSeries.cID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                    DBSeries.Clear(condition);

                    // Delete Online Series
                    condition = new SQLCondition();
                    condition.Add(new DBOnlineSeries(), DBOnlineSeries.cID, this[DBSeason.cSeriesID], SQLConditionType.Equal);
                    DBOnlineSeries.Clear(condition);

                    DBSeries.IsSeriesRemoved = true;
                }
            }
            #endregion

            return(resultMsg);
        }
예제 #16
0
        public bool ResumeOrPlay(DBEpisode episode)
        {
            try
            {
                MPTVSeriesLog.Write("Attempting to play: ", episode[DBEpisode.cFilename].ToString(), MPTVSeriesLog.LogLevel.Debug);
                // don't have this file !
                if (episode[DBEpisode.cFilename].ToString().Length == 0)
                {
                    return(false);
                }

                // check that we are not playing an episode out of episode if unwatched
                // ignore specials as they can be pretty out of wack!
                #region PlayBack Order

                // check sort order so our check is accurate
                var  series       = Helper.getCorrespondingSeries(episode[DBOnlineEpisode.cSeriesID]);
                bool dvdSortOrder = series[DBOnlineSeries.cEpisodeSortOrder] == "DVD";

                string seasonField  = dvdSortOrder ? DBOnlineEpisode.cCombinedSeason : DBOnlineEpisode.cSeasonIndex;
                string episodeField = dvdSortOrder ? DBOnlineEpisode.cCombinedEpisodeNumber : DBOnlineEpisode.cEpisodeIndex;

                if (DBOption.GetOptions(DBOption.cCheckPlayOutOfOrder) && !episode[DBOnlineEpisode.cWatched] && episode[seasonField] > 0 && episode[episodeField] > 1)
                {
                    // first get the next unwatched episode from previously played
                    // we are only interested in current season (could be multi-user watching multiple seasons)
                    // API for GetNextUnwatched is not desirable as that works from Date Watched, we only care about watched here
                    var conditions = new SQLCondition();
                    conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, episode[DBOnlineSeries.cSeriesID], SQLConditionType.Equal);
                    conditions.Add(new DBOnlineEpisode(), seasonField, episode[seasonField], SQLConditionType.Equal);
                    conditions.Add(new DBOnlineEpisode(), episodeField, episode[episodeField], SQLConditionType.LessThan);
                    conditions.Add(new DBOnlineEpisode(), episodeField, 0, SQLConditionType.GreaterThan);
                    var episodes = DBEpisode.Get(conditions, false);

                    if (episodes != null && episodes.Count > 0)
                    {
                        // set logical playback order based on sort order
                        episodes.Sort();

                        // if the previous found episode is not watched then we are playing out of order
                        // if we have a gap in episode collection then assume it has not been watched (this check is needed when user does not download all episode info)
                        if (!episodes.Last()[DBOnlineEpisode.cWatched] || (episode[episodeField] - episodes.Last()[episodeField]) > 1)
                        {
                            GUIDialogYesNo dlgYesNo = (GUIDialogYesNo)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_YES_NO);
                            dlgYesNo.SetHeading(Translation.Warning);
                            dlgYesNo.SetLine(1, Translation.PlaybackOutOfOrderLine1);
                            dlgYesNo.SetLine(2, string.Format("{0} - {1}x{2}", series.ToString(), episode[seasonField], episode[episodeField] - 1));
                            dlgYesNo.SetLine(3, Translation.PlaybackOutOfOrderLine2);
                            dlgYesNo.DoModal(GUIWindowManager.ActiveWindow);
                            if (!dlgYesNo.IsConfirmed)
                            {
                                return(false);
                            }
                        }
                    }
                }
                #endregion

                m_previousEpisode = m_currentEpisode;
                m_currentEpisode  = episode;
                int timeMovieStopped = m_currentEpisode[DBEpisode.cStopTime];

                // Check if file is an Image e.g. ISO
                string filename = m_currentEpisode[DBEpisode.cFilename];
                m_bIsImageFile = Helper.IsImageFile(filename);

                #region Invoke Before Playback
                // see if we have an invokeOption set up
                string invoke = (string)DBOption.GetOptions(DBOption.cInvokeExtBeforePlayback);
                if (!string.IsNullOrEmpty(invoke))
                {
                    string invokeArgs = (string)DBOption.GetOptions(DBOption.cInvokeExtBeforePlaybackArgs);
                    try
                    {
                        // replace any placeholders in the arguments for the script if any have been supplied.
                        if (!string.IsNullOrEmpty(invokeArgs))
                        {
                            invokeArgs = FieldGetter.resolveDynString(invokeArgs, m_currentEpisode, true);
                        }
                        invoke = FieldGetter.resolveDynString(invoke, m_currentEpisode, true);

                        // use ProcessStartInfo instead of Process.Start(string) as latter produces a "cannot find file"
                        // error if you pass in command line arguments.
                        // also allows us to run the script hidden, preventing, for example, a command prompt popping up.
                        ProcessStartInfo psi = new ProcessStartInfo(invoke, invokeArgs);
                        psi.WindowStyle = ProcessWindowStyle.Hidden;
                        Process proc = System.Diagnostics.Process.Start(psi);
                        MPTVSeriesLog.Write(string.Format("Sucessfully Invoked BeforeFilePlay Command: '{0}' '{1}'", invoke, invokeArgs));

                        // if not present in database this evaluates to false. If present and not a valid bool then
                        // it evaluates to true
                        bool waitForExit = (bool)DBOption.GetOptions(DBOption.cInvokeExtBeforePlaybackWaitForExit);

                        // if true this thread will wait for the external user script to complete before continuing.
                        if (waitForExit)
                        {
                            proc.WaitForExit();
                        }
                    }
                    catch (Exception e)
                    {
                        MPTVSeriesLog.Write(string.Format("Unable to Invoke BeforeFilePlay Command: '{0}' '{1}'", invoke, invokeArgs));
                        MPTVSeriesLog.Write(e.Message);
                    }
                }
                #endregion

                #region Removable Media Handling
                if (!File.Exists(m_currentEpisode[DBEpisode.cFilename]))
                {
                    string episodeVolumeLabel = m_currentEpisode[DBEpisode.cVolumeLabel].ToString();

                    if (string.IsNullOrEmpty(episodeVolumeLabel))
                    {
                        episodeVolumeLabel = LocalParse.getImportPath(m_currentEpisode[DBEpisode.cFilename]);
                    }

                    // ask the user to input cd/dvd, usb disk or confirm network drive is connected
                    GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
                    if (null == dlgOK)
                    {
                        return(false);
                    }
                    dlgOK.SetHeading(Translation.insertDisk);
                    dlgOK.SetLine(1, Translation.InsertDiskMessage1);
                    dlgOK.SetLine(2, Translation.InsertDiskMessage2);
                    dlgOK.SetLine(3, Translation.InsertDiskMessage3);
                    dlgOK.SetLine(4, string.Format(Translation.InsertDiskMessage4, episodeVolumeLabel));
                    dlgOK.DoModal(GUIWindowManager.ActiveWindow);

                    if (!File.Exists(m_currentEpisode[DBEpisode.cFilename]))
                    {
                        return(false); // still not found, return to list
                    }
                }
                #endregion

                #region Ask user to Resume

                // skip this if we are using an External Player
                bool bExternalPlayer = m_bIsImageFile ? m_bIsExternalDVDPlayer : m_bIsExternalPlayer;

                if (timeMovieStopped > 0 && !bExternalPlayer)
                {
                    MPTVSeriesLog.Write("Asking user to resume episode from: " + Utils.SecondsToHMSString(timeMovieStopped));
                    GUIDialogYesNo dlgYesNo = (GUIDialogYesNo)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_YES_NO);

                    if (null != dlgYesNo)
                    {
                        dlgYesNo.SetHeading(Translation.ResumeEpisode);
                        dlgYesNo.SetLine(1, m_currentEpisode.onlineEpisode.CompleteTitle);
                        dlgYesNo.SetLine(2, GUILocalizeStrings.Get(936) + " " + Utils.SecondsToHMSString(timeMovieStopped));
                        dlgYesNo.SetDefaultToYes(true);
                        dlgYesNo.DoModal(GUIWindowManager.ActiveWindow);
                        // reset resume data in DB
                        if (!dlgYesNo.IsConfirmed)
                        {
                            timeMovieStopped = 0;
                            m_currentEpisode[DBEpisode.cStopTime] = timeMovieStopped;
                            m_currentEpisode.Commit();
                            MPTVSeriesLog.Write("User selected to start episode from beginning", MPTVSeriesLog.LogLevel.Debug);
                        }
                        else
                        {
                            MPTVSeriesLog.Write("User selected to resume episode", MPTVSeriesLog.LogLevel.Debug);

                            // dont scrobble first of double episode if resuming past halfway
                            double duration = m_currentEpisode[DBEpisode.cLocalPlaytime];
                        }
                    }
                }

                #endregion

                Play(timeMovieStopped);
                return(true);
            }
            catch (Exception e)
            {
                MPTVSeriesLog.Write("TVSeriesPlugin.VideoHandler.ResumeOrPlay()\r\n" + e.ToString());
                return(false);
            }
        }
예제 #17
0
        /// <summary>
        /// Play all episodes of a series
        /// </summary>
        /// <param name="seriesId">ID of a series</param>
        /// <param name="onlyUnwatched">Play only unwatched episodes</param>
        /// <param name="autostart">If yes, automatically starts playback with the first episode</param>
        /// <param name="startIndex">Index of the item with which playback should start</param>
        /// <param name="switchToPlaylistView">If yes the playlistview will be shown</param>
        public static void PlaySeries(int seriesId, bool autostart, int startIndex, bool onlyUnwatched, bool switchToPlaylistView)
        {
            if (GUIGraphicsContext.form.InvokeRequired)
            {
                PlaySeriesAsyncDelegate d = new PlaySeriesAsyncDelegate(PlaySeries);
                GUIGraphicsContext.form.Invoke(d, new object[] { seriesId, autostart, startIndex, onlyUnwatched, switchToPlaylistView });
                return;
            }

            List <DBEpisode> episodes = DBEpisode.Get(seriesId);

            if (episodes == null || episodes.Count == 0)
            {
                return;
            }

            // filter out anything we can't play
            episodes.RemoveAll(e => string.IsNullOrEmpty(e[DBEpisode.cFilename]));

            // filter out watched episodes
            if (onlyUnwatched)
            {
                episodes.RemoveAll(e => e[DBOnlineEpisode.cWatched] != 0);
            }
            if (episodes.Count == 0)
            {
                return;
            }

            // Sort episodes and add them to the MP-TVSeries playlist player
            // Setup playlist player
            if (playlistPlayer == null)
            {
                playlistPlayer = PlayListPlayer.SingletonPlayer;
                playlistPlayer.PlaylistAutoPlay = true;
                playlistPlayer.RepeatPlaylist   = DBOption.GetOptions(DBOption.cRepeatPlaylist);
            }

            playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_TVSERIES).Clear();
            episodes.Sort();

            foreach (DBEpisode episode in episodes)
            {
                PlayListItem playlistItem = new PlayListItem(episode);
                playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_TVSERIES).Add(playlistItem);
            }

            //automatically start playing the playlist
            if (autostart)
            {
                // and activate the playlist window if its not activated yet
                if (switchToPlaylistView)
                {
                    GUIWindowManager.ActivateWindow(GUITVSeriesPlayList.GetWindowID);
                }

                playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_TVSERIES;
                playlistPlayer.Reset();
                playlistPlayer.Play(0);
            }
        }
예제 #18
0
        public GetUpdates(OnlineAPI.UpdateType type)
        {
            if (type != OnlineAPI.UpdateType.all)
            {
                MPTVSeriesLog.Write(string.Format("Downloading updates from the last {0}", type.ToString()));
            }
            else
            {
                MPTVSeriesLog.Write("Downloading all updates");
            }

            XmlNode updates = OnlineAPI.Updates(type);

            series   = new Dictionary <DBValue, long>();
            episodes = new Dictionary <DBValue, long>();
            banners  = new Dictionary <DBValue, long>();
            fanart   = new Dictionary <DBValue, long>();

            // if updates via zip fails, try xml
            if (updates == null)
            {
                MPTVSeriesLog.Write("Failed to get updates from 'zip' file, trying 'xml'...");
                updates = OnlineAPI.Updates(type, OnlineAPI.Format.Xml);

                // if we're still failing to get updates...
                if (updates == null)
                {
                    // manually define what series need updating basis whether the series is continuing and has local episodes
                    SQLCondition condition = new SQLCondition();
                    condition.Add(new DBOnlineSeries(), DBOnlineSeries.cID, 0, SQLConditionType.GreaterThan);
                    condition.Add(new DBOnlineSeries(), DBOnlineSeries.cHasLocalFiles, 1, SQLConditionType.Equal);
                    condition.Add(new DBOnlineSeries(), DBOnlineSeries.cStatus, "Ended", SQLConditionType.NotEqual);
                    condition.Add(new DBSeries(), DBSeries.cScanIgnore, 0, SQLConditionType.Equal);
                    condition.Add(new DBSeries(), DBSeries.cDuplicateLocalName, 0, SQLConditionType.Equal);

                    var lContinuingSeries = DBSeries.Get(condition, false, false);
                    MPTVSeriesLog.Write($"Failed to get updates from online, manually defining series and images for updates. Database contains '{lContinuingSeries.Count}' continuing series with local files");

                    // force our local download cache to expire after a 12hrs
                    timestamp = DateTime.UtcNow.Subtract(new TimeSpan(0, 12, 0, 0)).ToEpoch();
                    foreach (var lSeries in lContinuingSeries)
                    {
                        string lSeriesId = lSeries[DBOnlineSeries.cID];

                        series.Add(lSeriesId, timestamp);
                        banners.Add(lSeriesId, timestamp);
                        fanart.Add(lSeriesId, timestamp);

                        // get the most recent season as that is the one that is most likely recently updated
                        // NB: specials could also be recently updated
                        var lSeasons = DBSeason.Get(int.Parse(lSeriesId));
                        if (lSeasons != null && lSeasons.Count > 0)
                        {
                            int lSeasonIndex = lSeasons.Max(s => ( int )s[DBSeason.cIndex]);

                            var lEpisodes = DBEpisode.Get(int.Parse(lSeriesId), lSeasonIndex);
                            lEpisodes.AddRange(DBEpisode.Get(int.Parse(lSeriesId), 0));

                            foreach (var episode in lEpisodes)
                            {
                                episodes.Add(episode[DBOnlineEpisode.cID], timestamp);
                            }
                        }
                    }
                }
                else
                {
                    long.TryParse(updates.Attributes["time"].Value, out timestamp);

                    // get all available series in database, there is not point processing updates from online if not needed
                    var lAvailableSeriesInDb = DBSeries.Get(new SQLCondition()).Select(field => (string)field[DBOnlineSeries.cID]).ToList();

                    // NB: updates from xml only includes series (no episodes or artwork!)
                    foreach (XmlNode node in updates.SelectNodes("/Data/Series"))
                    {
                        long.TryParse(node.SelectSingleNode("time").InnerText, out long lTime);
                        string lSeriesId = node.SelectSingleNode("id").InnerText;

                        // check if we're interested in this series
                        if (!lAvailableSeriesInDb.Contains(lSeriesId))
                        {
                            continue;
                        }

                        series.Add(lSeriesId, lTime);
                        banners.Add(lSeriesId, lTime);
                        fanart.Add(lSeriesId, lTime);

                        // get the most recent season as that is the one that is most likely recently updated
                        // NB: specials could also be recently updated
                        if (Helper.getCorrespondingSeries(int.Parse(lSeriesId)) != null)
                        {
                            var lSeasons = DBSeason.Get(int.Parse(lSeriesId));
                            if (lSeasons != null && lSeasons.Count > 0)
                            {
                                int lSeasonIndex = lSeasons.Max(s => ( int )s[DBSeason.cIndex]);

                                var lEpisodes = DBEpisode.Get(int.Parse(lSeriesId), lSeasonIndex);
                                lEpisodes.AddRange(DBEpisode.Get(int.Parse(lSeriesId), 0));

                                foreach (var episode in lEpisodes)
                                {
                                    episodes.Add(episode[DBOnlineEpisode.cID], lTime);
                                }
                            }
                        }
                    }
                }
                return;
            }

            // process zip file update...
            long.TryParse(updates.Attributes["time"].Value, out this.timestamp);

            // get all the series ids
            foreach (XmlNode node in updates.SelectNodes("/Data/Series"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                this.series.Add(node.SelectSingleNode("id").InnerText, time);
            }

            // get all the episode ids
            foreach (XmlNode node in updates.SelectNodes("/Data/Episode"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                this.episodes.Add(node.SelectSingleNode("id").InnerText, time);
            }

            // get all the season banners
            string id = string.Empty;
            long   value;

            foreach (XmlNode node in updates.SelectNodes("/Data/Banner[type='season']"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                id = node.SelectSingleNode("Series").InnerText;
                if (!this.banners.TryGetValue(id, out value))
                {
                    this.banners.Add(id, time);
                }
            }

            //get all the series banners
            foreach (XmlNode node in updates.SelectNodes("/Data/Banner[type='series']"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                id = node.SelectSingleNode("Series").InnerText;
                if (!this.banners.TryGetValue(id, out value))
                {
                    this.banners.Add(id, time);
                }
            }

            //get all the poster banners
            foreach (XmlNode node in updates.SelectNodes("/Data/Banner[type='poster']"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                id = node.SelectSingleNode("Series").InnerText;
                if (!this.banners.TryGetValue(id, out value))
                {
                    this.banners.Add(id, time);
                }
            }

            //get all the fanart banners
            id = string.Empty;
            foreach (XmlNode node in updates.SelectNodes("/Data/Banner[type='fanart']"))
            {
                long time;
                long.TryParse(node.SelectSingleNode("time").InnerText, out time);
                id = node.SelectSingleNode("Series").InnerText;
                if (!this.fanart.TryGetValue(id, out value))
                {
                    this.fanart.Add(id, time);
                }
            }
        }
예제 #19
0
        void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            MPTVSeriesLog.Write("File Watcher: Changed event: " + e.FullPath);

            List <PathPair> filesChanged      = new List <PathPair>();
            bool            isDirectoryChange = false;

            if (Directory.Exists(e.FullPath))
            {
                isDirectoryChange = true;

                List <string> folder = new List <string>();
                folder.Add(e.FullPath);
                filesChanged = Filelister.GetFiles(folder);
            }

            // a file has changed! created, not created, whatever. Just add it to our list.
            // we only process this list once in a while
            lock (m_modifiedFilesList)
            {
                if (e.ChangeType == WatcherChangeTypes.Deleted)
                {
                    removeFromModifiedFilesList(e.FullPath, WatcherItemType.Added, true);

                    SQLCondition     condition  = new SQLCondition(new DBEpisode(), DBEpisode.cFilename, e.FullPath + "\\%", SQLConditionType.Like);
                    List <DBEpisode> dbepisodes = DBEpisode.Get(condition, false);
                    if (dbepisodes != null && dbepisodes.Count > 0)
                    {
                        foreach (DBEpisode dbepisode in dbepisodes)
                        {
                            m_modifiedFilesList.Add(new WatcherItem(new PathPair(dbepisode[DBEpisode.cFilename].ToString().Substring(e.FullPath.Length).TrimStart('\\'), dbepisode[DBEpisode.cFilename]), WatcherItemType.Deleted));
                        }
                    }
                }

                if (isDirectoryChange)
                {
                    foreach (PathPair pathPair in filesChanged)
                    {
                        removeFromModifiedFilesList(pathPair.m_sFull_FileName, WatcherItemType.Deleted, false);
                        m_modifiedFilesList.Add(new WatcherItem(pathPair, WatcherItemType.Added));
                    }
                }
                else
                {
                    /* duplicates are removed later
                     * foreach (WatcherItem item in m_modifiedFilesList)
                     * {
                     *  if (item.m_sFullPathFileName == e.FullPath)
                     *      return;
                     * }
                     */

                    String sExtention = System.IO.Path.GetExtension(e.FullPath);
                    if (MediaPortal.Util.Utils.VideoExtensions.IndexOf(sExtention) != -1)
                    {
                        if (e.ChangeType == WatcherChangeTypes.Deleted)
                        {
                            removeFromModifiedFilesList(e.FullPath, WatcherItemType.Added, false);
                        }
                        else
                        {
                            removeFromModifiedFilesList(e.FullPath, WatcherItemType.Deleted, false);
                        }

                        m_modifiedFilesList.Add(new WatcherItem(sender as FileSystemWatcher, e));
                    }
                }
            }
        }
예제 #20
0
        public void GetSeries()
        {
            Log.Instance().Print("Pulling series list from MP-TVSeries started");
            List <DBOnlineSeries> myseries = DBOnlineSeries.getAllSeries();

            foreach (DBOnlineSeries tvshow in myseries)
            {
                DBSeries mytv = Helper.getCorrespondingSeries(tvshow[DBOnlineSeries.cID]);
                if (mytv != null)
                {
                    string ishidden = mytv[DBSeries.cHidden];
                    if (ishidden != "1")
                    {
                        Series s = new Series();
                        s.ID           = (tvshow[DBOnlineSeries.cID]);
                        s.Name         = tvshow[DBOnlineSeries.cPrettyName];
                        s.OriginalName = tvshow[DBOnlineSeries.cOriginalName];
                        s.Description  = tvshow[DBOnlineSeries.cSummary];
                        s.Rating       = tvshow[DBOnlineSeries.cRating];
                        s.Genres       = tvshow[DBOnlineSeries.cGenre];
                        s.Poster       = Config.GetFolder(Config.Dir.Thumbs) + @"\" + "MPTVSeriesBanners" + @"\" + tvshow[DBOnlineSeries.cCurrentBannerFileName].ToString().Replace("/", @"\");

                        DBEpisode lastlocal    = null;
                        DBEpisode firstunlocal = null;
                        DBSeries  series       = Helper.getCorrespondingSeries(tvshow[DBOnlineSeries.cID]);
                        //DownList.Add(todownload);
                        // get all episodes for the series
                        var conditions = new SQLCondition();
                        conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, tvshow[DBOnlineSeries.cID], SQLConditionType.Equal);
                        var episodes = DBEpisode.Get(conditions, false);
                        episodes.Sort();
                        //first option - get all unlocal episodes
                        var           unLocalEpisodes = episodes.Where(e => !e.IsAvailableLocally).ToList();
                        StringBuilder sb = new StringBuilder();

                        foreach (DBEpisode e in unLocalEpisodes)
                        {
                            s.AllUnlocal += "S" + ((int)e[DBEpisode.cSeasonIndex]).ToString("00") + "E" + ((int)e[DBEpisode.cEpisodeIndex]).ToString("00") + "|";
                        }
                        //
                        //second option - get first unlocal episode
                        var localepisodes = episodes.Where(e => e.IsAvailableLocally);
                        try
                        {
                            lastlocal = localepisodes.Last();
                        }
                        catch
                        {
                            lastlocal = null;
                        }
                        int firstunlocalid = episodes.IndexOf(lastlocal) + 1;
                        try
                        {
                            firstunlocal   = episodes[firstunlocalid];
                            s.FirstUnlocal = "S" + ((int)firstunlocal[DBEpisode.cSeasonIndex]).ToString("00") + "E" + ((int)firstunlocal[DBEpisode.cEpisodeIndex]).ToString("00");
                        }
                        catch (Exception e)
                        {
                            firstunlocal   = null;
                            s.FirstUnlocal = "";
                        }
                        allseries.Add(s);
                    }
                }
            }

            Log.Instance().Print("Pulling series list from MP-TVSeries finished");
        }