protected void OnShowSavedPlaylists(string _directory) { VirtualDirectory _virtualDirectory = new VirtualDirectory(); _virtualDirectory.AddExtension(".tvsplaylist"); List <GUIListItem> itemlist = _virtualDirectory.GetDirectoryExt(_directory); if (_directory == DBOption.GetOptions(DBOption.cPlaylistPath)) { itemlist.RemoveAt(0); } // If no playlists found, show a Message to user and then exit if (itemlist.Count == 0) { GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); dlgOK.SetHeading(983); dlgOK.SetLine(1, Translation.NoPlaylistsFound); dlgOK.SetLine(2, _directory); dlgOK.DoModal(GUIWindowManager.ActiveWindow); return; } GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); if (dlg == null) { return; } dlg.Reset(); dlg.SetHeading(983); // Saved Playlists foreach (GUIListItem item in itemlist) { MediaPortal.Util.Utils.SetDefaultIcons(item); dlg.Add(item); } dlg.DoModal(GetID); if (dlg.SelectedLabel == -1) { return; } GUIListItem selectItem = itemlist[dlg.SelectedLabel]; if (selectItem.IsFolder) { OnShowSavedPlaylists(selectItem.Path); return; } GUIWaitCursor.Show(); LoadPlayList(selectItem.Path); GUIWaitCursor.Hide(); }
public int CompareTo(DBSeason other) { // sort specials last if needed int tSeason = this[DBSeason.cIndex] == 0 ? (9999 * DBOption.GetOptions(DBOption.cSortSpecialSeasonLast)) : (int)this[DBSeason.cIndex]; int oSeason = other[DBSeason.cIndex] == 0 ? (9999 * DBOption.GetOptions(DBOption.cSortSpecialSeasonLast)) : (int)other[DBSeason.cIndex]; return(tSeason.CompareTo(oSeason)); }
protected override void OnPageLoad() { base.OnPageLoad(); if (m_Facade != null) { m_Facade.CurrentLayout = (GUIFacadeControl.Layout)CurrentView; } MediaPortal.GUI.Library.GUIPropertyManager.SetProperty("#currentmodule", GUILocalizeStrings.Get(136)); // Episode Formatting m_sFormatEpisodeTitle = DBOption.GetOptions(DBOption.cViewEpisodeTitle); m_sFormatEpisodeSubtitle = DBOption.GetOptions(DBOption.cViewEpisodeSecondTitle); m_sFormatEpisodeMain = DBOption.GetOptions(DBOption.cViewEpisodeMain); Helper.disableNativeAutoplay(); // Clear GUI Properties ClearGUIProperties(); LoadDirectory(string.Empty); if (g_Player.Playing && playlistPlayer.CurrentPlaylistType == PlayListType.PLAYLIST_TVSERIES) { int iCurrentItem = playlistPlayer.CurrentItem; if (iCurrentItem >= 0 && iCurrentItem <= m_Facade.Count) { GUIControl.SelectItemControl(GetID, m_Facade.GetID, iCurrentItem); } } // Prompt to load a Playlist if there is no items in current plalist if (m_Facade.Count <= 0 && btnLoad != null) { GUIControl.FocusControl(GetID, btnLoad.GetID); } if (m_Facade.Count > 0) { GUIControl.FocusControl(GetID, m_Facade.GetID); SelectCurrentItem(); } playlistPlayer.RepeatPlaylist = DBOption.GetOptions(DBOption.cRepeatPlaylist); if (btnRepeat != null) { btnRepeat.Selected = playlistPlayer.RepeatPlaylist; } playlistPlayer.PlaylistAutoPlay = DBOption.GetOptions(DBOption.cPlaylistAutoPlay); if (btnAutoPlay != null) { btnAutoPlay.Selected = playlistPlayer.PlaylistAutoPlay; btnAutoPlay.Label = Translation.ButtonAutoPlay; } }
public GetSeries(String aSeriesName) { string lUserLanguage = DBOption.GetOptions(DBOption.cOnlineLanguage); if (DBOption.GetOptions(DBOption.cOverrideSearchLanguageToEnglish)) { lUserLanguage = "en"; } // search for series basis the user's language XmlNode lNode = Online_Parsing_Classes.OnlineAPI.GetSeries(aSeriesName, lUserLanguage); if (lNode == null) { return; } // if we have no results from the user's language try English if (lNode.ChildNodes.Count == 0 && lUserLanguage != "en") { lNode = Online_Parsing_Classes.OnlineAPI.GetSeries(aSeriesName, "en"); if (lNode == null) { return; } } foreach (XmlNode itemNode in lNode.ChildNodes) { var lSeries = new DBOnlineSeries(); foreach (XmlNode propertyNode in itemNode.ChildNodes) { if (propertyNode.Name == "seriesid") // work around SeriesID inconsistancy { lSeries[DBOnlineSeries.cID] = propertyNode.InnerText; } else if (DBOnlineSeries.s_OnlineToFieldMap.ContainsKey(propertyNode.Name)) { lSeries[DBOnlineSeries.s_OnlineToFieldMap[propertyNode.Name]] = propertyNode.InnerText; } else { // we don't know that field, add it to the series table lSeries.AddColumn(propertyNode.Name, new DBField(DBField.cTypeString)); lSeries[propertyNode.Name] = propertyNode.InnerText; } } mListSeries.Add(lSeries); } PerfectMatch = RankSearchResults(aSeriesName, mListSeries, out mListSeries); }
public static void Init() { // Import Skin Settings string xmlSkinSettings = Helper.GetThemedSkinFile(ThemeType.File, "TVSeries.SkinSettings.xml"); Load(xmlSkinSettings); #region Display Format Strings TVSeriesPlugin.m_sFormatSeriesCol1 = DBOption.GetOptions(DBOption.cViewSeriesColOne); TVSeriesPlugin.m_sFormatSeriesCol2 = DBOption.GetOptions(DBOption.cViewSeriesColTwo); TVSeriesPlugin.m_sFormatSeriesCol3 = DBOption.GetOptions(DBOption.cViewSeriesColThree); TVSeriesPlugin.m_sFormatSeriesTitle = DBOption.GetOptions(DBOption.cViewSeriesTitle); TVSeriesPlugin.m_sFormatSeriesSubtitle = DBOption.GetOptions(DBOption.cViewSeriesSecondTitle); TVSeriesPlugin.m_sFormatSeriesMain = DBOption.GetOptions(DBOption.cViewSeriesMain); TVSeriesPlugin.m_sFormatSeasonCol1 = DBOption.GetOptions(DBOption.cViewSeasonColOne); TVSeriesPlugin.m_sFormatSeasonCol2 = DBOption.GetOptions(DBOption.cViewSeasonColTwo); TVSeriesPlugin.m_sFormatSeasonCol3 = DBOption.GetOptions(DBOption.cViewSeasonColThree); TVSeriesPlugin.m_sFormatSeasonTitle = DBOption.GetOptions(DBOption.cViewSeasonTitle); TVSeriesPlugin.m_sFormatSeasonSubtitle = DBOption.GetOptions(DBOption.cViewSeasonSecondTitle); TVSeriesPlugin.m_sFormatSeasonMain = DBOption.GetOptions(DBOption.cViewSeasonMain); TVSeriesPlugin.m_sFormatEpisodeCol1 = DBOption.GetOptions(DBOption.cViewEpisodeColOne); TVSeriesPlugin.m_sFormatEpisodeCol2 = DBOption.GetOptions(DBOption.cViewEpisodeColTwo); TVSeriesPlugin.m_sFormatEpisodeCol3 = DBOption.GetOptions(DBOption.cViewEpisodeColThree); TVSeriesPlugin.m_sFormatEpisodeTitle = DBOption.GetOptions(DBOption.cViewEpisodeTitle); TVSeriesPlugin.m_sFormatEpisodeSubtitle = DBOption.GetOptions(DBOption.cViewEpisodeSecondTitle); TVSeriesPlugin.m_sFormatEpisodeMain = DBOption.GetOptions(DBOption.cViewEpisodeMain); #endregion // Load all Skin Fields being used var skinFiles = Directory.GetFiles(GUIGraphicsContext.Skin, "TVSeries*.xml").ToList(); if (Settings.SkinThemesSupported) { string currentTheme = Helper.GetCurrrentSkinTheme(); if (currentTheme != null) { skinFiles = skinFiles.Union(Directory.GetFiles(GUIGraphicsContext.Skin + @"\Themes\" + currentTheme, "TVSeries*.xml").ToList()).ToList(); } } foreach (string skinFile in skinFiles) { MPTVSeriesLog.Write("Loading Skin Properties in: " + skinFile); GetSkinProperties(skinFile); } LogSkinProperties(); // Remember last skin used incase we need to reload PreviousSkin = CurrentSkin; }
public static List <string> getFromDB() { try { string all = DBOption.GetOptions(optionName).ToString().Trim(); entries.Clear(); entriesValidForInfo.Clear(); splitConditions.Clear(); if (all.Length > 0) { entries = new List <string>(Regex.Split(all, entriesSplit)); } entriesInMemory = true; if (entries.Count == 0) { MPTVSeriesLog.Write("No Logo-Rules found!", MPTVSeriesLog.LogLevel.Debug); } else { // we calculate relevances once here so we can avoid doing it everytime // we also split them here so we can avoid doing this later for (int i = 0; i < entries.Count; i++) { List <Level> levels = new List <Level>(); if (isRelevant(entries[i], Level.Series)) { levels.Add(Level.Series); } if (isRelevant(entries[i], Level.Season)) { levels.Add(Level.Season); } if (isRelevant(entries[i], Level.Episode)) { levels.Add(Level.Episode); } entriesValidForInfo.Add(i, levels); splitConditions.Add(i, new List <string>(Regex.Split(entries[i], localLogos.condSplit))); } } return(entries); } catch (Exception e) { MPTVSeriesLog.Write("Error loading logos into memory: " + e.Message); entriesInMemory = false; return(entries); } }
public static void UpdateEpisodeCounts(DBSeries series) { if (series == null) { return; } int seriesEpsTotal = 0; int seriesEpsUnWatched = 0; int epsTotal = 0; int epsUnWatched = 0; // Update for each season in series and add each to total series count SQLCondition condition = new SQLCondition(); if (!DBOption.GetOptions(DBOption.cShowHiddenItems)) { //don't include hidden seasons unless the ShowHiddenItems option is set condition.Add(new DBSeason(), DBSeason.cHidden, 0, SQLConditionType.Equal); } List <DBSeason> Seasons = DBSeason.Get(series[DBSeries.cID], condition); foreach (DBSeason season in Seasons) { epsTotal = 0; epsUnWatched = 0; DBEpisode.GetSeasonEpisodeCounts(series, season, out epsTotal, out epsUnWatched); season[DBSeason.cEpisodeCount] = epsTotal; season[DBSeason.cEpisodesUnWatched] = epsUnWatched; season[DBSeason.cUnwatchedItems] = epsUnWatched > 0; season.Commit(); seriesEpsTotal += epsTotal; // Count the Special (Season 0 (zero)) episodes as watched! if ((season[DBSeason.cIndex] != 0) || (season[DBSeason.cIndex] == 0 && !DBOption.GetOptions(DBOption.cCountSpecialEpisodesAsWatched))) { seriesEpsUnWatched += epsUnWatched; } MPTVSeriesLog.Write(string.Format("Series \"{0} Season {1}\" has {2}/{3} unwatched episodes", series.ToString(), season[DBSeason.cIndex], epsUnWatched, epsTotal), MPTVSeriesLog.LogLevel.Debug); } MPTVSeriesLog.Write(string.Format("Series \"{0}\" has {1}/{2} unwatched episodes", series.ToString(), seriesEpsUnWatched, seriesEpsTotal), MPTVSeriesLog.LogLevel.Debug); series[DBOnlineSeries.cEpisodeCount] = seriesEpsTotal; series[DBOnlineSeries.cEpisodesUnWatched] = seriesEpsUnWatched; series[DBOnlineSeries.cUnwatchedItems] = seriesEpsUnWatched > 0; series.Commit(); }
void DoFileScan(List <String> scannedFolders, ref List <PathPair> previousScan) { MPTVSeriesLog.Write("File Watcher: Performing File Scan on Import Paths for changes", MPTVSeriesLog.LogLevel.Normal); // Check if Fullscreen Video is active as this can cause stuttering/dropped frames if (!DBOption.GetOptions(DBOption.cImportScanWhileFullscreenVideo) && Helper.IsFullscreenVideo) { MPTVSeriesLog.Write("File Watcher: Fullscreen Video has been detected, aborting file scan"); return; } List <PathPair> newScan = Filelister.GetFiles(scannedFolders); List <PathPair> addedFiles = new List <PathPair>(); addedFiles.AddRange(newScan); foreach (PathPair pair in previousScan) { addedFiles.RemoveAll(item => item.m_sFull_FileName == pair.m_sFull_FileName); } List <PathPair> removedFiles = new List <PathPair>(); removedFiles.AddRange(previousScan); foreach (PathPair pair in newScan) { removedFiles.RemoveAll(item => item.m_sFull_FileName == pair.m_sFull_FileName); } lock (m_modifiedFilesList) { foreach (PathPair pair in addedFiles) { m_modifiedFilesList.Add(new WatcherItem(pair, WatcherItemType.Added)); } foreach (PathPair pair in removedFiles) { m_modifiedFilesList.Add(new WatcherItem(pair, WatcherItemType.Deleted)); } } previousScan = newScan; MPTVSeriesLog.Write("File Watcher: Finished File Scan on Import Paths", MPTVSeriesLog.LogLevel.Normal); }
public static string stdGetSQL(SQLCondition condition, bool selectFull, bool includeStdCond) { string orderBy = !condition.customOrderStringIsSet ? " order by " + Q(cIndex) : condition.orderString; if (includeStdCond) { condition.AddCustom(stdConditions.ConditionsSQLString); if (!Settings.isConfig) { SQLCondition fullSubCond = new SQLCondition(); //fullSubCond.AddCustom(DBOnlineEpisode.Q(DBOnlineEpisode.cSeriesID), DBSeason.Q(DBSeason.cSeriesID), SQLConditionType.Equal); //fullSubCond.AddCustom(DBOnlineEpisode.Q(DBOnlineEpisode.cSeasonIndex), DBSeason.Q(DBSeason.cIndex), SQLConditionType.Equal); //condition.AddCustom(" season.seasonindex in ( " + DBEpisode.stdGetSQL(fullSubCond, false, true, DBOnlineEpisode.Q(DBOnlineEpisode.cSeriesID)) + " )"); string join = null; if (DBOption.GetOptions(DBOption.cOnlyShowLocalFiles)) { fullSubCond = DBEpisode.stdConditions; condition.AddCustom(fullSubCond.ConditionsSQLString.Replace("where", "and")); join = " left join local_episodes on season.seriesid = local_episodes.seriesid " + " and season.seasonindex = local_episodes.seasonindex left join online_episodes on local_episodes.compositeid = online_episodes.compositeid "; } else { join = " left join online_episodes on season.seriesid = online_episodes.seriesid " + " and season.seasonindex = online_episodes.seasonindex"; } return("select " + new SQLWhat(new DBSeason()) + join + condition + " group by season.id " + orderBy + condition.limitString); } } if (selectFull) { return("select " + new SQLWhat(new DBSeason()) + condition + orderBy + condition.limitString); } else { return("select " + DBSeason.cID + " from " + DBSeason.cTableName + " " + condition + orderBy + condition.limitString); } }
private void onStopExternal(Process proc, bool waitForExit) { if (!listenToExternalPlayerEvents) { return; } MPTVSeriesLog.Write("Playback Stopped in External Player:" + m_currentEpisode.ToString()); // Exit fullscreen Video so we can see main facade again if (GUIGraphicsContext.IsFullScreenVideo) { GUIGraphicsContext.IsFullScreenVideo = false; } // Mark Episode as watched regardless and prompt for rating bool markAsWatched = (DBOption.GetOptions(DBOption.cWatchedAfter) > 0 && m_currentEpisode[DBOnlineEpisode.cWatched] == 0); PlaybackOperationEnded(markAsWatched); }
public static void InitLogLevel() { using (var xmlreader = new MediaPortal.Profile.MPSettings()) { int logLevel = xmlreader.GetValueAsInt("general", "loglevel", 2); if (DBOption.GetOptions(DBOption.cSQLLoggingEnabled)) { selectedLogLevel = MPTVSeriesLog.LogLevel.DebugSQL; } else if (logLevel == 3) { selectedLogLevel = MPTVSeriesLog.LogLevel.Debug; } else { selectedLogLevel = MPTVSeriesLog.LogLevel.Normal; } } }
private void OnSavePlayList() { currentSelectedItem = m_Facade.SelectedListItemIndex; string playlistFileName = string.Empty; if (GetKeyboard(ref playlistFileName)) { string playListPath = string.Empty; playListPath = DBOption.GetOptions(DBOption.cPlaylistPath); playListPath = MediaPortal.Util.Utils.RemoveTrailingSlash(playListPath); // check if Playlist folder exists, create it if not if (!Directory.Exists(playListPath)) { try { Directory.CreateDirectory(playListPath); } catch (Exception e) { MPTVSeriesLog.Write("Error: Unable to create Playlist path: " + e.Message); return; } } string fullPlayListPath = Path.GetFileNameWithoutExtension(playlistFileName); fullPlayListPath += ".tvsplaylist"; if (playListPath.Length != 0) { fullPlayListPath = playListPath + @"\" + fullPlayListPath; } PlayList playlist = new PlayList(); for (int i = 0; i < m_Facade.Count; ++i) { GUIListItem listItem = m_Facade[i]; PlayListItem playListItem = new PlayListItem(); playListItem.Episode = listItem.TVTag as DBEpisode; playlist.Add(playListItem); } PlayListIO saver = new PlayListIO(); saver.Save(playlist, fullPlayListPath); } }
void workerWatcher_DoWork(object sender, DoWorkEventArgs e) { System.Threading.Thread.CurrentThread.Priority = ThreadPriority.Lowest; // delay the start of file monitoring for a small period // this doesnt really need a config setting but can be manually overridden in DB option // purpose of the delay is to allow network devices to get ready after fresh boot from windows // and resume from standby...benifits UNC shares as Mapped drives are picked up from Device Manager events. // also DoFileScan can be expensive, so we dont want to do this on startup while other plugins/background tasks // are running as well. Thread.Sleep((int)DBOption.GetOptions(DBOption.cDelayImportPathMonitoringValue) * 1000); MPTVSeriesLog.Write("File Watcher: Starting File System Watcher Background Task", MPTVSeriesLog.LogLevel.Normal); setUpWatches(); // do the initial scan m_PreviousScan = Filelister.GetFiles(m_ScannedFolders); m_PreviousScanRemovable = Filelister.GetFiles(GetDeviceManagerWatchedFolders()); DateTime timeLastScan = DateTime.Now; // then start the watcher loop while (!worker.CancellationPending) { TimeSpan tsUpdate = DateTime.Now - timeLastScan; if ((int)tsUpdate.TotalMinutes >= m_nScanLapse) { timeLastScan = DateTime.Now; DoFileScan(); } signalModifiedFiles(); if (refreshWatchers) { setUpWatches(); } Thread.Sleep(1000); } }
public static String GetEpisodeImage(DBEpisode episode) { bool HideEpisodeImage = true; if (!localLogos.appendEpImage && (episode[DBOnlineEpisode.cWatched] || !DBOption.GetOptions(DBOption.cHideUnwatchedThumbnail))) { HideEpisodeImage = false; } // show episode image if (!HideEpisodeImage && !String.IsNullOrEmpty(episode.Image) && System.IO.File.Exists(episode.Image)) { return(episode.Image); } else { // show a fanart thumb instead Fanart fanart = Fanart.getFanart(episode[DBOnlineEpisode.cSeriesID]); return(fanart.FanartThumbFilename); } }
void OnPlaybackChanged(g_Player.MediaType type, int timeMovieStopped, string filename) { if (PlayBackOpWasOfConcern(g_Player.IsVideo? g_Player.MediaType.Video : g_Player.MediaType.Unknown, g_Player.CurrentFile)) { if (PlayPropertyUpdater.IsBusy) { PlayPropertyUpdater.CancelAsync(); } LogPlayBackOp("changed", g_Player.CurrentFile); try { #region Set Resume Point or Watched double watchedAfter = DBOption.GetOptions(DBOption.cWatchedAfter); if (!m_previousEpisode[DBOnlineEpisode.cWatched] && (timeMovieStopped / playlistPlayer.g_Player.Duration) > watchedAfter / 100) { m_previousEpisode[DBEpisode.cStopTime] = 0; m_previousEpisode.Commit(); MPTVSeriesLog.Write("This episode counts as watched"); MarkEpisodeAsWatched(m_previousEpisode); SetGUIProperties(true); } else { m_previousEpisode[DBEpisode.cStopTime] = timeMovieStopped; m_previousEpisode.Commit(); SetGUIProperties(true); } #endregion m_previousEpisode = null; } catch (Exception e) { MPTVSeriesLog.Write("TVSeriesPlugin.VideoHandler.OnPlaybackChanged()\r\n" + e.ToString()); } } }
static DBExpression() { // make sure the table is created - create a dummy object DBExpression dummy = new DBExpression(); DBExpression[] expressions = DBExpression.GetAll(); if (expressions == null || expressions.Length == 0) { // no expressions in the db, add defaults AddDefaults(); } else { // upgrade, add any new expressions int nCurrentDBVersion = cDBVersion; int nUpgradeDBVersion = DBOption.GetOptions(DBOption.cDBExpressionsVersion); while (nUpgradeDBVersion != nCurrentDBVersion) { DBExpression expression = new DBExpression(); switch (nUpgradeDBVersion) { case 4: expression[DBExpression.cEnabled] = "1"; expression[DBExpression.cIndex] = expressions.Length; expression[DBExpression.cType] = DBExpression.cType_Regexp; expression[DBExpression.cExpression] = @"(^.*?\\?(?<series>[^\\$]+?)[ .-]+(?<firstaired>\d{2,4}[.-]\d{2}[.-]\d{2,4})[ .-]*(?<title>(?![^\\]*?(?<!the)[ .(-]sample[ .)-]).*?)\.(?<ext>[^.]*)$)"; expression.Commit(); break; } nUpgradeDBVersion++; } DBOption.SetOptions(DBOption.cDBExpressionsVersion, nCurrentDBVersion); } }
public static String GetSeasonBanner(DBSeason season, bool createIfNotExist, bool isCoverflow) { Size size = isCoverflow ? reqSeasonPosterCFSize : reqSeasonPosterSize; String sFileName = season.Banner; String sTextureName = null; if (sFileName.Length > 0 && System.IO.File.Exists(sFileName)) { if (DBOption.GetOptions(DBOption.cAltImgLoading)) { sTextureName = sFileName; // bypass memoryimagebuilder } else { sTextureName = buildMemoryImageFromFile(sFileName, size); } } if (createIfNotExist && string.IsNullOrEmpty(sTextureName)) { // no image, use text, create our own string text = (season[DBSeason.cIndex] == 0) ? Translation.specials : Translation.Season + season[DBSeason.cIndex]; string ident = season[DBSeason.cSeriesID] + "S" + season[DBSeason.cIndex]; sTextureName = buildMemoryImage(drawSimpleBanner(size, text), ident, size, true); } // nothing left we can do, so return empty if still nothing if (string.IsNullOrEmpty(sTextureName)) { return(string.Empty); } s_SeasonsImageList.Add(sTextureName); return(sTextureName); }
void OnPlayBackStopped(g_Player.MediaType type, int timeMovieStopped, string filename) { if (PlayBackOpIsOfConcern(type, filename)) { if (PlayPropertyUpdater.IsBusy) { PlayPropertyUpdater.CancelAsync(); } LogPlayBackOp("stopped", filename); try { #region Set Resume Point or Watched double watchedAfter = DBOption.GetOptions(DBOption.cWatchedAfter); if ((timeMovieStopped / playlistPlayer.g_Player.Duration) > watchedAfter / 100) { m_currentEpisode[DBEpisode.cStopTime] = 0; m_currentEpisode.Commit(); PlaybackOperationEnded(true); } else { m_currentEpisode[DBEpisode.cStopTime] = timeMovieStopped; m_currentEpisode.Commit(); PlaybackOperationEnded(false); } #endregion m_currentEpisode = null; m_previousEpisode = null; } catch (Exception e) { MPTVSeriesLog.Write("TVSeriesPlugin.VideoHandler.OnPlayBackStopped()\r\n" + e.ToString()); } } }
public static logicalViewStep parseFromDB(string viewStep, bool hasSeriesBeforeIt) { logicalViewStep thisView = new logicalViewStep(); thisView.hasSeriesBeforeIt = hasSeriesBeforeIt; string[] viewSteps = System.Text.RegularExpressions.Regex.Split(viewStep, s_intSeperator); thisView.setType(viewSteps[0]); thisView.addConditionsFromString(viewSteps[1]); if (viewSteps[2].Length > 0) { string[] orderFields = System.Text.RegularExpressions.Regex.Split(viewSteps[2], ";"); thisView.inLineSpecials = orderFields[0] == "<Episode.EpisodeIndex>"; thisView.inLineSpecialsAsc = orderFields[0] != "desc"; for (int i = 0; i < orderFields.Length; i += 2) { if (thisView.Type != type.group) { DBTable table = null; string tableField = string.Empty; getTableFieldname(orderFields[i], out table, out tableField); tableField = getQTableNameFromUnknownType(table, tableField); // example of how the user can order by a different table // needs to be enabled once definable views are ready /* * if (thisView.Type == type.season && table.GetType() != typeof(DBSeason)) * { * Type lType = table.GetType(); * if (lType == typeof(DBOnlineSeries)) * tableField = "( select " + tableField + " from " + DBOnlineSeries.cTableName + " where " + DBOnlineSeries.Q(DBOnlineSeries.cID) + " = " + DBSeason.Q(DBSeason.cSeriesID) + ")"; + }*/ //if (thisView.Type == type.episode && ( table.GetType() == typeof(DBEpisode) || table.GetType() == typeof(DBOnlineEpisode))) //{ // // for perf reason a subquery is build, otherwise custom orders and the nessesary join really slow down sqllite! // SQLCondition subQueryConditions = thisView.conds.Copy(); // have to have all conds too // subQueryConditions.AddOrderItem(tableField, (orderFields[i + 1] == "asc" ? SQLCondition.orderType.Ascending : SQLCondition.orderType.Descending)); // if (viewSteps[3].Length > 0) // set the limit too // { // try // { // subQueryConditions.SetLimit(System.Convert.ToInt32(viewSteps[3])); // } // catch (Exception) // { // } // } // thisView.conds.AddSubQuery("compositeid", table, subQueryConditions, table.m_tableName + "." + DBEpisode.cCompositeID, SQLConditionType.In); //} thisView.conds.AddOrderItem(tableField, (orderFields[i + 1] == "asc" ? SQLCondition.orderType.Ascending : SQLCondition.orderType.Descending)); } } } if (thisView.Type == type.group && thisView.groupedBy != null) // for groups always by their values (ignore user setting!) { if (thisView.groupedBy.table.GetType() == typeof(DBSeries)) { if (!DBOption.GetOptions(DBOption.cShowHiddenItems)) { thisView.conds.Add(new DBSeries(), DBSeries.cHidden, 1, SQLConditionType.NotEqual); } } else if (thisView.groupedBy.table.GetType() == typeof(DBOnlineSeries)) { if (!DBOption.GetOptions(DBOption.cShowHiddenItems)) { thisView.conds.AddCustom(" not exists ( select * from " + DBSeries.cTableName + " where id = " + DBOnlineSeries.Q(DBOnlineSeries.cID) + " and " + DBSeries.Q(DBSeries.cHidden) + " = 1)"); } } else if (thisView.groupedBy.table.GetType() == typeof(DBSeason)) { if (!DBOption.GetOptions(DBOption.cShowHiddenItems)) { thisView.conds.Add(new DBSeason(), DBSeason.cHidden, 1, SQLConditionType.NotEqual); } } thisView.conds.AddOrderItem(thisView.groupedBy.tableField, SQLCondition.orderType.Descending); // tablefield includes tablename itself! } try { if (viewSteps[3].Length > 0) { thisView.limitItems = System.Convert.ToInt32(viewSteps[3]); thisView.conds.SetLimit(thisView.limitItems); } } catch (Exception) { MPTVSeriesLog.Write("Cannot interpret limit in logicalview, limit was: " + viewSteps[3]); } return(thisView); }
public List <string> getGroupItems(int stepIndex, string[] currentStepSelection) // in nested groups, eg. Networks-Genres-.. we also need selections { SQLCondition conditions = null; MPTVSeriesLog.Write("View: GetGroupItems: Begin", MPTVSeriesLog.LogLevel.Debug); if (stepIndex >= m_steps.Count) { return(null); // wrong index specified!! } addHierarchyConditions(ref stepIndex, ref currentStepSelection, ref conditions); logicalViewStep step = m_steps[stepIndex]; List <string> items = new List <string>(); // to ensure we respect on the fly filter settings if (DBOption.GetOptions(DBOption.cOnlyShowLocalFiles) && (typeof(DBOnlineEpisode) != step.groupedBy.table.GetType() && typeof(DBEpisode) != step.groupedBy.table.GetType())) { // not generic SQLCondition fullSubCond = new SQLCondition(); fullSubCond.AddCustom(DBOnlineEpisode.Q(DBOnlineEpisode.cSeriesID), DBOnlineSeries.Q(DBOnlineSeries.cID), SQLConditionType.Equal); conditions.AddCustom(" exists( " + DBEpisode.stdGetSQL(fullSubCond, false) + " )"); } else if (DBOption.GetOptions(DBOption.cOnlyShowLocalFiles)) { // has to be grouped by something episode conditions.Add(new DBEpisode(), DBEpisode.cFilename, "", SQLConditionType.NotEqual); } string fieldName = step.groupedBy.rawFieldname; string tableName = step.groupedBy.table.m_tableName; string tableField = step.groupedBy.tableField; string userEditField = tableField + DBTable.cUserEditPostFix; string sql = string.Empty; // check if the useredit column exists if (DBTable.ColumnExists(tableName, fieldName + DBTable.cUserEditPostFix)) { sql = "select distinct(" + "case when (" + userEditField + " is null or " + userEditField + " = " + "'" + "'" + ") " + "then " + tableField + " else " + userEditField + " " + "end) as gnr, " + "count(*) from " + tableName + conditions + " group by gnr" + step.conds.orderString; } else { sql = "select distinct " + tableField + " , count(*) " + " from " + tableName + conditions + " group by " + tableField + step.conds.orderString; } SQLite.NET.SQLiteResultSet results = DBTVSeries.Execute(sql); MPTVSeriesLog.Write("View: GetGroupItems: SQL complete", MPTVSeriesLog.LogLevel.Debug); if (results.Rows.Count > 0) { for (int index = 0; index < results.Rows.Count; index++) { string tmpItem = results.Rows[index].fields[0]; // assume we now have a list of all distinct ones if (step.groupedBy.attempSplit) { // we want to try to split by "|" eg. for actors/genres string[] split = DBOnlineEpisode.splitField(tmpItem); foreach (string item in split) { if (item.Trim().Length == 0) { // display "Unknown" if field is empty" items.Add(Translation.Unknown); } else { items.Add(item.Trim()); } } } else { if (tmpItem.Trim().Length == 0) { items.Add(Translation.Unknown); } else { items.Add(tmpItem.Trim()); } } } if (step.groupedBy.attempSplit) { // have to check for dups (because we split eg. Drama|Action so "Action" might be in twice items = Helper.RemoveDuplicates(items); } // now we have to sort them again (Unknown/splitting above) items.Sort(); if (step.groupedBy.attempSplit) { // and limit in memory here (again because those splits are hard to deal with) if (step.limitItems > 0) { Helper.LimitList(ref items, step.limitItems); } } } MPTVSeriesLog.Write("View: GetGroupItems: Complete", MPTVSeriesLog.LogLevel.Debug); return(items); }
public void addHierarchyConditions(ref int stepIndex, ref string[] currentStepSelection, ref SQLCondition conditions) { logicalViewStep step = m_steps[stepIndex]; conditions = step.conds.Copy(); // important, don't change the steps themselves // we need to add one additional condition to reflect the selection one hierarchy up if (currentStepSelection != null && currentStepSelection.Length > 0 && stepIndex > 0) { switch (m_steps[stepIndex - 1].Type) { case logicalViewStep.type.group: bool requiresSplit = false; // use sql 'like' for split fields // selected group label string selectedItem = currentStepSelection[0]; // we expect to get the selected group's label // unknown really is "" so get all with null values here if (selectedItem == Translation.Unknown) { selectedItem = string.Empty; } else if (m_steps[stepIndex - 1].groupedBy.attempSplit) { requiresSplit = true; } string fieldName = m_steps[stepIndex - 1].groupedBy.rawFieldname; string tableName = m_steps[stepIndex - 1].groupedBy.table.m_tableName; string tableField = tableName + "." + fieldName; string userEditField = tableField + DBTable.cUserEditPostFix; string value = requiresSplit ? "like " + "'%" + selectedItem + "%'" : "= " + "'" + selectedItem + "'"; string sql = string.Empty; // check if the useredit column exists if (DBTable.ColumnExists(tableName, fieldName + DBTable.cUserEditPostFix)) { sql = "(case when (" + userEditField + " is null or " + userEditField + " = " + "'" + "'" + ") " + "then " + tableField + " else " + userEditField + " " + "end) " + value; } else { sql = tableField + " " + value; } conditions.AddCustom(sql); break; case logicalViewStep.type.series: // we expect to get the seriesID as stepSel conditions.Add(new DBSeason(), DBSeason.cSeriesID, currentStepSelection[0], SQLConditionType.Equal); if (DBOption.GetOptions(DBOption.cSortSpecialSeasonLast)) { conditions.InsertOrderItem(DBSeason.cTableName + "." + DBSeason.cIndex + " = 0", SQLCondition.orderType.Ascending); } break; case logicalViewStep.type.season: // we expect to get the seriesID/seasonIndex as stepSel // we want to query episodes using the CombinedSeason if Sort Order is "DVD" // CombinedSeason gives us the DVD Season and if empty will give us the Aired Season DBSeries series = Helper.getCorrespondingSeries(int.Parse(currentStepSelection[0])); bool SortByDVD = series[DBOnlineSeries.cEpisodeSortOrder] == "DVD"; string seasonIndex = SortByDVD ? DBOnlineEpisode.cCombinedSeason : DBOnlineEpisode.cSeasonIndex; conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, currentStepSelection[0], SQLConditionType.Equal); conditions.beginGroup(); conditions.Add(new DBOnlineEpisode(), seasonIndex, currentStepSelection[1], SQLConditionType.Equal); if (DBOption.GetOptions(DBOption.cSortSpecials) && !SortByDVD) { conditions.nextIsOr = true; conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cAirsBeforeSeason, currentStepSelection[1], SQLConditionType.Equal); conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cAirsAfterSeason, currentStepSelection[1], SQLConditionType.Equal); conditions.nextIsOr = false; } conditions.endGroup(); break; } } }
static DBSeason() { DBSeason dummy = new DBSeason(); //////////////////////////////////////////////////////////////////////////////// #region Pretty Names displayed in Configuration Details Tab s_FieldToDisplayNameMap.Add(cID, "Composite Season ID"); s_FieldToDisplayNameMap.Add(cSeriesID, "Series ID"); s_FieldToDisplayNameMap.Add(cIndex, "Season Index"); s_FieldToDisplayNameMap.Add(cEpisodeCount, "Episodes"); s_FieldToDisplayNameMap.Add(cEpisodesUnWatched, "Episodes UnWatched"); s_FieldToDisplayNameMap.Add(cMyRating, "My Rating"); #endregion //////////////////////////////////////////////////////////////////////////////// int nCurrentDBVersion = cDBVersion; int nUpgradeDBVersion = DBOption.GetOptions(DBOption.cDBSeasonVersion); while (nUpgradeDBVersion != nCurrentDBVersion) { SQLCondition condEmpty = new SQLCondition(); List <DBSeason> AllSeasons = Get(condEmpty, true); // take care of the upgrade in the table switch (nUpgradeDBVersion) { case 1: // upgrade to version 2; clear the season table (series table format changed) try { String sqlQuery = "DROP TABLE season"; DBTVSeries.Execute(sqlQuery); nUpgradeDBVersion++; } catch { } break; case 2: DBSeason.GlobalSet(DBSeason.cHidden, 0, new SQLCondition()); DBSeries.GlobalSet(DBOnlineSeries.cGetEpisodesTimeStamp, 0, new SQLCondition()); nUpgradeDBVersion++; break; case 3: // create the unwatcheditem value by parsin the episodes foreach (DBSeason season in AllSeasons) { DBEpisode episode = DBEpisode.GetFirstUnwatched(season[DBSeason.cSeriesID], season[DBSeason.cIndex]); if (episode != null) { season[DBSeason.cUnwatchedItems] = true; } else { season[DBSeason.cUnwatchedItems] = false; } season.Commit(); } nUpgradeDBVersion++; break; case 4: // Set number of watched/unwatched episodes foreach (DBSeason season in AllSeasons) { int epsTotal = 0; int epsUnWatched = 0; DBEpisode.GetSeasonEpisodeCounts(season, out epsTotal, out epsUnWatched); season[DBSeason.cEpisodeCount] = epsTotal; season[DBSeason.cEpisodesUnWatched] = epsUnWatched; season.Commit(); } nUpgradeDBVersion++; break; default: nUpgradeDBVersion = nCurrentDBVersion; break; } } DBOption.SetOptions(DBOption.cDBSeasonVersion, nCurrentDBVersion); }
public override DBValue this[String fieldName] { get { switch (fieldName) { // if the user chooses a different language for the import, we don't have this as the prettyname case DBOnlineSeries.cOriginalName: string origLanguage = "en"; // English (original) DBValue currentTitle = base[DBOnlineSeries.cPrettyName]; if (DBOption.GetOptions(DBOption.cOnlineLanguage) == "en" && !DBOption.GetOptions(DBOption.cOverrideLanguage)) { return(base[DBOnlineSeries.cPrettyName]); } else { if (base[DBOnlineSeries.cOriginalName].ToString().Length > 0) { return(base[DBOnlineSeries.cOriginalName]); } else { // we need to get it MPTVSeriesLog.Write("Retrieving Original Series Name for '{0}'", currentTitle); UpdateSeries origParser = new UpdateSeries(base[DBOnlineSeries.cID], origLanguage, true); if (origParser != null && origParser.Results.Count == 1) { DBValue origTitle = origParser.Results[0][DBOnlineSeries.cPrettyName]; // there may not be an english title, so localized title is the original name origTitle = string.IsNullOrEmpty(origTitle) ? base[DBOnlineSeries.cPrettyName] : origTitle; // save for next time base[DBOnlineSeries.cOriginalName] = origTitle; Commit(); MPTVSeriesLog.Write("Original Series Name retrieved: '{0}'", origTitle); return(origTitle); } else { // something wrong MPTVSeriesLog.Write("Original Series Name could not be retrieved"); return(base[DBOnlineSeries.cPrettyName]); } } } case cSummary: DBValue summary = base[cSummary]; if (string.IsNullOrEmpty(summary)) { summary = Translation.SummaryNotAvailable; } return(summary); default: return(base[fieldName]); } } set { base[fieldName] = value; } }
public static void UpdateEpisodeCounts(DBSeries series, Dictionary <string, List <EpisodeCounter> > episodes) { if (series == null) { return; } string seriesId = series[DBSeries.cID]; int seriesEpsTotal = 0; int seriesEpsUnWatched = 0; bool airedOrder = series.IsAiredOrder; // dont worry about filtering season list, we already have a filtered episode list // query without std conditions for faster response. var conditions = new SQLCondition(new DBSeason(), DBSeason.cSeriesID, seriesId, SQLConditionType.Equal); var seasons = DBSeason.Get(conditions, false); // update season counts List <EpisodeCounter> eps = new List <EpisodeCounter>(); if (episodes.TryGetValue(seriesId, out eps)) { foreach (var season in seasons) { var seasonEps = eps.Where(e => airedOrder ? e.SeasonAirIdx == season[DBSeason.cIndex] : e.SeasonDvdIdx == season[DBSeason.cIndex]).ToList(); // dont commit seasons if are not viewing them // episodes for count is already filtered so can return 0 results if (seasonEps.Count == 0) { continue; } int count = seasonEps.Count(); int unWatchedCount = seasonEps.Where(e => e.EpisodeWatched != "1").Count(); season[DBSeason.cEpisodeCount] = count; season[DBSeason.cEpisodesUnWatched] = unWatchedCount; season[DBSeason.cUnwatchedItems] = unWatchedCount > 0; season.Commit(); seriesEpsTotal += count; // Count the Special (Season 0 (zero)) episodes as watched! if ((season[DBSeason.cIndex] != 0) || (season[DBSeason.cIndex] == 0 && !DBOption.GetOptions(DBOption.cCountSpecialEpisodesAsWatched))) { seriesEpsUnWatched += unWatchedCount; } } // update series counts series[DBOnlineSeries.cEpisodeCount] = seriesEpsTotal; series[DBOnlineSeries.cEpisodesUnWatched] = seriesEpsUnWatched; series[DBOnlineSeries.cUnwatchedItems] = seriesEpsUnWatched > 0; series.Commit(); } }
public static Dictionary <string, List <EpisodeCounter> > GetEpisodesForCount() { var episodesForCount = new Dictionary <string, List <EpisodeCounter> >(); string selectFields = "online_episodes.SeriesID, online_episodes.EpisodeIndex, online_episodes.SeasonIndex, online_episodes.Combined_season, online_episodes.Watched"; string query = string.Empty; string whereClause = string.Empty; var wheres = new List <string>(); if (!DBOption.GetOptions(DBOption.cShowHiddenItems)) { wheres.Add("online_episodes.Hidden = 0"); } if (DBOption.GetOptions(DBOption.cOnlyShowLocalFiles)) { wheres.Add("local_episodes.EpisodeFilename != ''"); } if (!DBOption.GetOptions(DBOption.cCountEmptyAndFutureAiredEps)) { wheres.Add(string.Format("online_episodes.FirstAired <= '{0}' AND online_episodes.FirstAired != ''", DateTime.Now.ToString("yyyy-MM-dd"))); } if (wheres.Count > 0) { whereClause = string.Format("WHERE {0}", string.Join(" AND ", wheres.ToArray())); } if (DBOption.GetOptions(DBOption.cOnlyShowLocalFiles)) { // if we are only counting episodes that have a file ie. local reference // then we need to join the local and online episode tables // further more we also need to union two select statements with // one returning only the first of a single/double episode and the other // returning the second of any double episodes query = string.Format(@" SELECT {0} FROM online_episodes LEFT JOIN local_episodes ON local_episodes.CompositeID = online_episodes.CompositeID {1} UNION SELECT {0} FROM online_episodes LEFT JOIN local_episodes ON local_episodes.CompositeID2 = online_episodes.CompositeID {1} ", selectFields, whereClause); } else { query = string.Format(@" SELECT {0} FROM online_episodes {1} ", selectFields, whereClause); } SQLiteResultSet results = DBTVSeries.Execute(query); foreach (var row in results.Rows) { var seriesId = row.fields[0]; var episodeAirIdx = row.fields[1]; var seasonAirIdx = row.fields[2]; var seasonDvdIdx = row.fields[3]; var watched = row.fields[4]; if (episodesForCount.ContainsKey(seriesId)) { episodesForCount[seriesId].Add(new EpisodeCounter { EpisodeIdx = episodeAirIdx, SeasonAirIdx = seasonAirIdx, SeasonDvdIdx = seasonDvdIdx, EpisodeWatched = watched }); } else { var episodeList = new List <EpisodeCounter>(); episodeList.Add(new EpisodeCounter { EpisodeIdx = episodeAirIdx, SeasonAirIdx = seasonAirIdx, SeasonDvdIdx = seasonDvdIdx, EpisodeWatched = watched }); episodesForCount.Add(seriesId, episodeList); } } return(episodesForCount); }
public List <DBFanart> FanartsToDownload(int SeriesID) { // Only get a list of fanart that is available for download String sqlQuery = "select * from " + cTableName; sqlQuery += " where " + cSeriesID + " = " + SeriesID.ToString(); // Get Preferred Resolution int res = DBOption.GetOptions(DBOption.cAutoDownloadFanartResolution); bool getSeriesNameFanart = DBOption.GetOptions(DBOption.cAutoDownloadFanartSeriesNames); if (res == (int)FanartResolution.HD) { sqlQuery += " and " + cResolution + " = " + "\"1280x720\""; } if (res == (int)FanartResolution.FULLHD) { sqlQuery += " and " + cResolution + " = " + "\"1920x1080\""; } if (!getSeriesNameFanart) { sqlQuery += " and " + cSeriesName + " != " + "\"true\""; } SQLiteResultSet results = DBTVSeries.Execute(sqlQuery); if (results.Rows.Count > 0) { int iFanartCount = 0; List <DBFanart> AvailableFanarts = new List <DBFanart>(results.Rows.Count); for (int index = 0; index < results.Rows.Count; index++) { if (results.GetField(index, (int)results.ColumnIndices[cLocalPath]).Length > 0) { iFanartCount++; } else { // Add 'Available to Download' fanart to list AvailableFanarts.Add(new DBFanart()); AvailableFanarts[AvailableFanarts.Count - 1].Read(ref results, index); } } // sort by highest rated AvailableFanarts.Sort(); // Only return the fanarts that we want to download int AutoDownloadCount = DBOption.GetOptions(DBOption.cAutoDownloadFanartCount); for (int i = 0; i < AvailableFanarts.Count; i++) { // Dont get more than the user wants if (iFanartCount >= AutoDownloadCount) { break; } _FanartsToDownload.Add(AvailableFanarts[i]); iFanartCount++; } } return(_FanartsToDownload); }
void PlaybackOperationEnded(bool countAsWatched) { // notify listeners if (!countAsWatched && EpisodeStopped != null) { EpisodeStopped(m_currentEpisode); } if (countAsWatched || m_currentEpisode[DBOnlineEpisode.cWatched]) { MPTVSeriesLog.Write("This episode counts as watched"); if (countAsWatched) { MarkEpisodeAsWatched(m_currentEpisode); // notify listeners if (EpisodeWatched != null) { EpisodeWatched(m_currentEpisode); } } // if the ep wasn't rated before, and the option to ask is set, bring up the ratings menu if ((String.IsNullOrEmpty(m_currentEpisode[DBOnlineEpisode.cMyRating]) || m_currentEpisode[DBOnlineEpisode.cMyRating] == 0) && DBOption.GetOptions(DBOption.cAskToRate)) { MPTVSeriesLog.Write("Episode not rated yet"); if (RateRequestOccured != null) { RateRequestOccured.Invoke(m_currentEpisode); } } else { MPTVSeriesLog.Write("Episode has already been rated or option not set"); } } SetGUIProperties(true); // clear GUI Properties #region Invoke After Playback string invoke = (string)DBOption.GetOptions(DBOption.cInvokeExtAfterPlayback); if (countAsWatched && !string.IsNullOrEmpty(invoke)) { string invokeArgs = (string)DBOption.GetOptions(DBOption.cInvokeExtAfterPlaybackArgs); 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 AfterFilePlay 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.cInvokeExtAfterPlaybackWaitForExit); // 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 ExtAfterPlayback Command: '{0}' '{1}'", invoke, invokeArgs)); MPTVSeriesLog.Write(e.Message); } } #endregion }
private void doWork(string seriesID) { XmlNode banners = OnlineAPI.getBannerList(Int32.Parse(seriesID)); if (banners == null) { return; } if (Helper.getCorrespondingSeries(Int32.Parse(seriesID)) == null) { return; } string SeriesName = Helper.getCorrespondingSeries(Int32.Parse(seriesID)).ToString(); List <WideBannerSeries> widebannerSeriesList = new List <WideBannerSeries>(); List <PosterSeries> posterSeriesList = new List <PosterSeries>(); List <PosterSeason> posterSeasonList = new List <PosterSeason>(); SeriesBannersMap map = new SeriesBannersMap(); map.SeriesID = seriesID; #region Series WideBanners foreach (XmlNode banner in banners.SelectNodes("/Banners/Banner[BannerType='series']")) { WideBannerSeries seriesWideBanners = new WideBannerSeries(); seriesWideBanners.Language = banner.SelectSingleNode("Language").InnerText; seriesWideBanners.OnlinePath = banner.SelectSingleNode("BannerPath").InnerText; seriesWideBanners.SeriesName = SeriesName; try { seriesWideBanners.Style = (ArtworkStyles)Enum.Parse(typeof(ArtworkStyles), banner.SelectSingleNode("BannerType2").InnerText, true); } catch { // maybe a new style introduced seriesWideBanners.Style = ArtworkStyles.unknown; } if (!string.IsNullOrEmpty(banner.SelectSingleNode("Rating").InnerText)) { double rating = double.Parse(banner.SelectSingleNode("Rating").InnerText, NumberStyles.Any, NumberFormatInfo.InvariantInfo); seriesWideBanners.Rating = Math.Round(rating, 1, MidpointRounding.AwayFromZero); } if (!string.IsNullOrEmpty(banner.SelectSingleNode("RatingCount").InnerText)) { seriesWideBanners.RatingCount = int.Parse(banner.SelectSingleNode("RatingCount").InnerText); } seriesWideBanners.SeriesID = seriesID; widebannerSeriesList.Add(seriesWideBanners); } // sort by highest rated widebannerSeriesList.Sort(); // remove banners of no interest if (!DBOption.GetOptions(DBOption.cGetTextBanners)) { widebannerSeriesList.RemoveAll(b => b.Style == ArtworkStyles.text); } if (!DBOption.GetOptions(DBOption.cGetBlankBanners)) { widebannerSeriesList.RemoveAll(b => b.Style == ArtworkStyles.blank); } // Respect User Limits, exception: if higher rated image or localised image is uploaded online int limit = DBOption.GetOptions(DBOption.cArtworkLimitSeriesWideBanners); if (limit < widebannerSeriesList.Count) { widebannerSeriesList.RemoveRange(limit, widebannerSeriesList.Count - limit); } map.SeriesWideBanners = widebannerSeriesList; #endregion #region Series Posters foreach (XmlNode banner in banners.SelectNodes("/Banners/Banner[BannerType='poster']")) { PosterSeries seriesPoster = new PosterSeries(); seriesPoster.Language = banner.SelectSingleNode("Language").InnerText; seriesPoster.OnlinePath = banner.SelectSingleNode("BannerPath").InnerText; seriesPoster.SeriesName = SeriesName; if (!string.IsNullOrEmpty(banner.SelectSingleNode("Rating").InnerText)) { double rating = double.Parse(banner.SelectSingleNode("Rating").InnerText, NumberStyles.Any, NumberFormatInfo.InvariantInfo); seriesPoster.Rating = Math.Round(rating, 1, MidpointRounding.AwayFromZero); } if (!string.IsNullOrEmpty(banner.SelectSingleNode("RatingCount").InnerText)) { seriesPoster.RatingCount = int.Parse(banner.SelectSingleNode("RatingCount").InnerText); } seriesPoster.SeriesID = seriesID; posterSeriesList.Add(seriesPoster); } posterSeasonList.Sort(); limit = DBOption.GetOptions(DBOption.cArtworkLimitSeriesPosters); if (limit < posterSeriesList.Count) { posterSeriesList.RemoveRange(limit, posterSeriesList.Count - limit); } map.SeriesPosters = posterSeriesList; #endregion #region Season Posters List <string> seasons = new List <string>(); foreach (XmlNode banner in banners.SelectNodes("/Banners/Banner[BannerType='season']")) { PosterSeason seasonPoster = new PosterSeason(); seasonPoster.Language = banner.SelectSingleNode("Language").InnerText; seasonPoster.OnlinePath = banner.SelectSingleNode("BannerPath").InnerText; seasonPoster.SeasonIndex = banner.SelectSingleNode("Season").InnerText; seasonPoster.SeriesName = SeriesName; try { seasonPoster.Style = (ArtworkStyles)Enum.Parse(typeof(ArtworkStyles), banner.SelectSingleNode("BannerType2").InnerText, true); } catch { // maybe a new style introduced seasonPoster.Style = ArtworkStyles.unknown; } if (!string.IsNullOrEmpty(banner.SelectSingleNode("Rating").InnerText)) { double rating = double.Parse(banner.SelectSingleNode("Rating").InnerText, NumberStyles.Any, NumberFormatInfo.InvariantInfo); seasonPoster.Rating = Math.Round(rating, 1, MidpointRounding.AwayFromZero); } if (!string.IsNullOrEmpty(banner.SelectSingleNode("RatingCount").InnerText)) { seasonPoster.RatingCount = int.Parse(banner.SelectSingleNode("RatingCount").InnerText); } if (!seasons.Contains(seasonPoster.SeasonIndex)) { seasons.Add(seasonPoster.SeasonIndex); } seasonPoster.SeriesID = seriesID; posterSeasonList.Add(seasonPoster); } posterSeasonList.Sort(); // we dont support season widebanners posterSeasonList.RemoveAll(p => p.Style == ArtworkStyles.seasonwide); limit = DBOption.GetOptions(DBOption.cArtworkLimitSeasonPosters); List <PosterSeason> posterSeasonListTemp = new List <PosterSeason>(posterSeasonList); foreach (string season in seasons) { int count = 0; foreach (PosterSeason pSeason in posterSeasonListTemp) { if (season == pSeason.SeasonIndex) { count++; if (limit < count) { posterSeasonList.Remove(pSeason); } } } } map.SeasonPosters = posterSeasonList; #endregion // series already in? if (SeriesBannersMap.Contains(map)) { SeriesBannersMap seriesMap = SeriesBannersMap[SeriesBannersMap.IndexOf(map)]; seriesMap.SeasonPosters.AddRange(map.SeasonPosters); seriesMap.SeriesWideBanners.AddRange(map.SeriesWideBanners); seriesMap.SeriesPosters.AddRange(map.SeriesPosters); } else { SeriesBannersMap.Add(map); } }
public void DownloadBanners(string onlineLanguage) { int maxConsecutiveDownloadErrors; var consecutiveDownloadErrors = 0; if (!int.TryParse(DBOption.GetOptions(DBOption.cMaxConsecutiveDownloadErrors).ToString(), out maxConsecutiveDownloadErrors)) { maxConsecutiveDownloadErrors = 3; } // now that we have all the paths, download all the files foreach (SeriesBannersMap map in SeriesBannersMap) { #region Series Wide Banners var seriesWideBanners = new List <WideBannerSeries>(map.SeriesWideBanners); var seriesWideBannersToKeep = new List <WideBannerSeries>(); // if localized and english banners exist then only get them // if none exist, then get what's left over if (seriesWideBanners.Exists(b => b.Language == onlineLanguage || b.Language == "en" || b.Language == string.Empty)) { seriesWideBanners.RemoveAll(b => b.Language != onlineLanguage && b.Language != "en" && b.Language != string.Empty); } foreach (var seriesWideBanner in seriesWideBanners) { if (consecutiveDownloadErrors >= maxConsecutiveDownloadErrors) { MPTVSeriesLog.Write("Too many consecutive download errors. Aborting."); return; } // mark the filename with the language seriesWideBanner.FileName = Helper.cleanLocalPath(seriesWideBanner.SeriesName) + @"\-lang" + seriesWideBanner.Language + "-" + seriesWideBanner.OnlinePath; string file = OnlineAPI.DownloadBanner(seriesWideBanner.OnlinePath, Settings.Path.banners, seriesWideBanner.FileName); if (BannerDownloadDone != null) { BannerDownloadDone(file); seriesWideBannersToKeep.Add(seriesWideBanner); consecutiveDownloadErrors = 0; } else { consecutiveDownloadErrors++; } } map.SeriesWideBanners = seriesWideBannersToKeep; #endregion #region Series Posters var seriesPosters = new List <PosterSeries>(map.SeriesPosters); var seriesPostersToKeep = new List <PosterSeries>(); // if localized and english banners exist then only get them // if none exist, then get what's left over if (seriesPosters.Exists(p => p.Language == onlineLanguage || p.Language == "en" || p.Language == string.Empty)) { seriesPosters.RemoveAll(p => p.Language != onlineLanguage && p.Language != "en" && p.Language != string.Empty); } foreach (var seriesPoster in seriesPosters) { if (consecutiveDownloadErrors >= maxConsecutiveDownloadErrors) { MPTVSeriesLog.Write("Too many consecutive download errors. Aborting."); return; } // mark the filename with the language seriesPoster.FileName = Helper.cleanLocalPath(seriesPoster.SeriesName) + @"\-lang" + seriesPoster.Language + "-" + seriesPoster.OnlinePath; string file = OnlineAPI.DownloadBanner(seriesPoster.OnlinePath, Settings.Path.banners, seriesPoster.FileName); if (BannerDownloadDone != null) { BannerDownloadDone(file); seriesPostersToKeep.Add(seriesPoster); consecutiveDownloadErrors = 0; } else { consecutiveDownloadErrors++; } } map.SeriesPosters = seriesPostersToKeep; #endregion #region Season Posters List <DBSeason> localSeasons = DBSeason.Get(new SQLCondition(new DBSeason(), DBSeason.cSeriesID, map.SeriesID, SQLConditionType.Equal), false); var seasonPosters = new List <PosterSeason>(map.SeasonPosters); var seasonPostersToKeep = new List <PosterSeason>(); // if localized and english banners exist then only get them // if none exist, then get what's left over if (seasonPosters.Exists(p => p.Language == onlineLanguage || p.Language == "en" || p.Language == string.Empty)) { seasonPosters.RemoveAll(p => p.Language != onlineLanguage && p.Language != "en" && p.Language != string.Empty); } foreach (var seasonPoster in seasonPosters) { if (consecutiveDownloadErrors >= maxConsecutiveDownloadErrors) { MPTVSeriesLog.Write("Too many consecutive download errors. Aborting."); return; } // only download season banners if we have online season in database if (!localSeasons.Any(s => s[DBSeason.cIndex] == seasonPoster.SeasonIndex)) { continue; } seasonPoster.FileName = Helper.cleanLocalPath(seasonPoster.SeriesName) + @"\-lang" + seasonPoster.Language + "-" + seasonPoster.OnlinePath; string file = OnlineAPI.DownloadBanner(seasonPoster.OnlinePath, Settings.Path.banners, seasonPoster.FileName); if (BannerDownloadDone != null) { BannerDownloadDone(file); seasonPostersToKeep.Add(seasonPoster); consecutiveDownloadErrors = 0; } else { consecutiveDownloadErrors++; } } map.SeasonPosters = seasonPostersToKeep; #endregion } }
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); } }