private static void AddAsync(int progid) { lock (Database.DbUpdateLock) { using (SQLiteCommand command = new SQLiteCommand("insert into subscriptions (progid) values (@progid)", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("@progid", progid)); try { command.ExecuteNonQuery(); } catch (SQLiteException sqliteExp) { if (sqliteExp.ErrorCode == SQLiteErrorCode.Constraint) { // Already added while this was waiting in the threadpool return; } throw; } } } if (Added != null) { Added(progid); } Programme.RaiseUpdated(progid); }
public static string CreateSaveFileName(string formatString, Programme progInfo, Episode epInfo) { if (string.IsNullOrEmpty(formatString)) { // The format string is an empty string, so the output must be an empty string return(string.Empty); } // Normalise slashes to main directory separator for platform string fileName = Regex.Replace(formatString, @"[\\/]", Path.DirectorySeparatorChar.ToString()); // Convert %title% -> %epname% for backwards compatability fileName = fileName.Replace("%title%", "%epname%"); // Make variable substitutions fileName = fileName.Replace("%progname%", Regex.Replace(progInfo.Name, @"[\\/]", " ")); fileName = fileName.Replace("%epname%", Regex.Replace(epInfo.Name, @"[\\/]", " ")); fileName = fileName.Replace("%hour%", epInfo.Date.ToString("HH", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%minute%", epInfo.Date.ToString("mm", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%day%", epInfo.Date.ToString("dd", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%month%", epInfo.Date.ToString("MM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%shortmonthname%", epInfo.Date.ToString("MMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%monthname%", epInfo.Date.ToString("MMMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%year%", epInfo.Date.ToString("yy", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%longyear%", epInfo.Date.ToString("yyyy", CultureInfo.CurrentCulture)); // Replace problematic chars and runs of spaces with a single space // Although most of these are permitted in Linux filenames, remove // them anyway to prevent interoperability issues. fileName = Regex.Replace(fileName, "[\x00-\x1f\"<>|:*? ]+", " "); return(fileName.Trim()); }
public static bool Add(int progid) { Programme progInfo = new Programme(progid); if (progInfo.SingleEpisode) { using (SQLiteCommand command = new SQLiteCommand("select downloads.epid from downloads, episodes where downloads.epid=episodes.epid and progid=@progid", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("progid", progid)); using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader())) { if (reader.Read()) { // The one download for this programme is already in the downloads list return(false); } } } } ThreadPool.QueueUserWorkItem(state => { AddAsync(progid); }); return(true); }
private void TextFileNameFormat_TextChanged(object sender, EventArgs e) { Model.Programme dummyProg = new Model.Programme(); dummyProg.Name = "Programme Name"; Model.Episode dummyEp = new Model.Episode(); dummyEp.Name = "Episode Name"; dummyEp.Date = DateTime.Now; this.LabelFilenameFormatResult.Text = "Result: " + Model.Download.CreateSaveFileName(this.TextFileNameFormat.Text, dummyProg, dummyEp) + ".mp3"; }
public static string MoveToSaveFolder(string formatString, Programme progInfo, Episode epInfo, string baseSavePath, string extension, string sourceFile) { string rootName = Path.Combine(baseSavePath, CreateSaveFileName(formatString, progInfo, epInfo)); // Make sure the save folder exists (to support subfolders in the save file name template) Directory.CreateDirectory(OsUtils.GetDirectoryName(rootName)); for (int diffNum = 0; ; diffNum++) { string savePath = rootName + (diffNum > 0 ? diffNum.ToString(CultureInfo.CurrentCulture) : string.Empty) + "." + extension; if (savePath == sourceFile) { // File is already named correctly, nothing to do return(savePath); } if (!File.Exists(savePath)) { try { OsUtils.MoveFile(sourceFile, savePath); } catch (IOException e) { // We only want to handle IOException itself as a // number of IOException subclasses are thrown for // other cases we don't want to handle if (e.GetType() == typeof(IOException)) { // Destination file created since File.Exists check continue; } throw; } return(savePath); } } }
public static string FindFreeSaveFileName(string formatString, Programme progInfo, Episode epInfo, string baseSavePath) { string rootName = Path.Combine(baseSavePath, CreateSaveFileName(formatString, progInfo, epInfo)); string savePath = rootName; // Make sure the save folder exists (to support subfolders in the save file name template) string saveDir = Path.GetDirectoryName(savePath); Directory.CreateDirectory(saveDir); string currentFileName = null; // If the passed episode info is actually a download, get it's current path if (typeof(Download) == epInfo.GetType()) { currentFileName = ((Download)epInfo).DownloadPath; // Remove the extension from the current name if applicable if (currentFileName != null) { int extensionPos = currentFileName.LastIndexOf('.'); if (extensionPos > -1) { currentFileName = currentFileName.Substring(0, extensionPos); } } } int diffNum = 1; // Check for a pre-existing file with the same name (ignoring the current name for this file) while (Directory.GetFiles(saveDir, Path.GetFileName(savePath) + ".*").Length > 0 && savePath != currentFileName) { savePath = rootName + Convert.ToString(diffNum, CultureInfo.CurrentCulture); diffNum += 1; } return(savePath); }
public static string CreateSaveFileName(string formatString, Programme progInfo, Episode epInfo) { if (string.IsNullOrEmpty(formatString)) { // The format string is an empty string, so the output must be an empty string return(string.Empty); } string fileName = formatString; // Convert %title% -> %epname% for backwards compatability fileName = fileName.Replace("%title%", "%epname%"); // Make variable substitutions fileName = fileName.Replace("%progname%", progInfo.Name.Replace(Path.DirectorySeparatorChar, ' ')); fileName = fileName.Replace("%epname%", epInfo.Name.Replace(Path.DirectorySeparatorChar, ' ')); fileName = fileName.Replace("%hour%", epInfo.Date.ToString("HH", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%minute%", epInfo.Date.ToString("mm", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%day%", epInfo.Date.ToString("dd", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%month%", epInfo.Date.ToString("MM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%shortmonthname%", epInfo.Date.ToString("MMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%monthname%", epInfo.Date.ToString("MMMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%year%", epInfo.Date.ToString("yy", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%longyear%", epInfo.Date.ToString("yyyy", CultureInfo.CurrentCulture)); // Replace invalid file name characters with spaces (except for directory separators // as this then allows the flexibility of storing the downloads in subdirectories) foreach (char removeChar in Path.GetInvalidFileNameChars()) { if (removeChar != Path.DirectorySeparatorChar) { fileName = fileName.Replace(removeChar, ' '); } } // Replace runs of spaces with a single space fileName = Regex.Replace(fileName, " {2,}", " "); return(fileName.Trim()); }
private static void RemoveAsync(int progid) { lock (Database.DbUpdateLock) { using (SQLiteCommand command = new SQLiteCommand("delete from subscriptions where progid=@progid", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("@progid", progid)); if (command.ExecuteNonQuery() == 0) { // Subscription has already been removed return; } } } Programme.RaiseUpdated(progid); if (Removed != null) { Removed(progid); } }
public DownloadHandler(int epid) { using (SQLiteCommand command = new SQLiteCommand("select pr.progid, pluginid, pr.image as progimg, ep.duration, ep.image as epimg, pr.extid as progextid, ep.extid as epextid from episodes as ep, programmes as pr where ep.epid=@epid and ep.progid=pr.progid", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("@epid", epid)); using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader())) { if (!reader.Read()) { throw new DataNotFoundException(epid, "Episode does not exist"); } this.pluginId = new Guid(reader.GetString(reader.GetOrdinal("pluginid"))); this.progExtId = reader.GetString(reader.GetOrdinal("progextid")); this.episodeExtId = reader.GetString(reader.GetOrdinal("epextid")); this.progInfo = new Model.Programme(reader.GetInt32(reader.GetOrdinal("progid"))); this.episodeInfo = new Model.Episode(epid); this.providerProgInfo = new Provider.ProgrammeInfo(this.progInfo); if (reader.IsDBNull(reader.GetOrdinal("progimg"))) { this.providerProgInfo.Image = null; } else { this.providerProgInfo.Image = RetrieveImage(reader.GetInt32(reader.GetOrdinal("progimg"))); } this.providerEpisodeInfo = new Provider.EpisodeInfo(this.episodeInfo); if (reader.IsDBNull(reader.GetOrdinal("duration"))) { this.providerEpisodeInfo.Duration = null; } else { this.providerEpisodeInfo.Duration = reader.GetInt32(reader.GetOrdinal("duration")); } if (reader.IsDBNull(reader.GetOrdinal("epimg"))) { this.providerEpisodeInfo.Image = null; } else { this.providerEpisodeInfo.Image = RetrieveImage(reader.GetInt32(reader.GetOrdinal("epimg"))); } using (SQLiteCommand extCommand = new SQLiteCommand("select name, value from episodeext where epid=@epid", FetchDbConn())) { extCommand.Parameters.Add(new SQLiteParameter("@epid", epid)); using (SQLiteMonDataReader extReader = new SQLiteMonDataReader(extCommand.ExecuteReader())) { while (extReader.Read()) { this.providerEpisodeInfo.ExtInfo.Add(extReader.GetString(extReader.GetOrdinal("name")), extReader.GetString(extReader.GetOrdinal("value"))); } } } } } }
public static bool Add(int progid) { Programme progInfo = new Programme(progid); if (progInfo.SingleEpisode) { using (SQLiteCommand command = new SQLiteCommand("select downloads.epid from downloads, episodes where downloads.epid=episodes.epid and progid=@progid", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("progid", progid)); using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader())) { if (reader.Read()) { // The one download for this programme is already in the downloads list return false; } } } } ThreadPool.QueueUserWorkItem(delegate { AddAsync(progid); }); return true; }
private void ShowProgrammeInfo(int progid) { Model.Programme progInfo = new Model.Programme((int)this.view.CurrentViewData); List<ToolBarButton> buttons = new List<ToolBarButton>(); if (Model.Favourite.IsFavourite(progid)) { buttons.Add(this.ButtonRemFavourite); } else { buttons.Add(this.ButtonAddFavourite); } if (Model.Subscription.IsSubscribed(progid)) { buttons.Add(this.ButtonUnsubscribe); } else { buttons.Add(this.ButtonSubscribe); } this.SetToolbarButtons(buttons.ToArray()); this.SetSideBar(progInfo.Name, progInfo.Description, Model.Programme.GetImage(progid)); }
public DownloadHandler(int epid) { using (SQLiteCommand command = new SQLiteCommand("select pr.progid, pluginid, pr.image as progimg, ep.duration, ep.image as epimg, pr.extid as progextid, ep.extid as epextid from episodes as ep, programmes as pr where ep.epid=@epid and ep.progid=pr.progid", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("@epid", epid)); using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader())) { if (!reader.Read()) { throw new DataNotFoundException(epid, "Episode does not exist"); } this.pluginId = new Guid(reader.GetString(reader.GetOrdinal("pluginid"))); this.progExtId = reader.GetString(reader.GetOrdinal("progextid")); this.episodeExtId = reader.GetString(reader.GetOrdinal("epextid")); this.progInfo = new Model.Programme(reader.GetInt32(reader.GetOrdinal("progid"))); this.episodeInfo = new Model.Episode(epid); this.providerProgInfo = new ProgrammeInfo(this.progInfo); if (reader.IsDBNull(reader.GetOrdinal("progimg"))) { this.providerProgInfo.Image = null; } else { this.providerProgInfo.Image = Database.RetrieveImage(reader.GetInt32(reader.GetOrdinal("progimg"))); } this.providerEpisodeInfo = new EpisodeInfo(this.episodeInfo); if (reader.IsDBNull(reader.GetOrdinal("duration"))) { this.providerEpisodeInfo.Duration = null; } else { this.providerEpisodeInfo.Duration = reader.GetInt32(reader.GetOrdinal("duration")); } if (reader.IsDBNull(reader.GetOrdinal("epimg"))) { this.providerEpisodeInfo.Image = null; } else { this.providerEpisodeInfo.Image = Database.RetrieveImage(reader.GetInt32(reader.GetOrdinal("epimg"))); } using (SQLiteCommand extCommand = new SQLiteCommand("select name, value from episodeext where epid=@epid", FetchDbConn())) { extCommand.Parameters.Add(new SQLiteParameter("@epid", epid)); using (SQLiteMonDataReader extReader = new SQLiteMonDataReader(extCommand.ExecuteReader())) { while (extReader.Read()) { this.providerEpisodeInfo.ExtInfo.Add(extReader.GetString(extReader.GetOrdinal("name")), extReader.GetString(extReader.GetOrdinal("value"))); } } } } } }
public static string FindFreeSaveFileName(string formatString, Programme progInfo, Episode epInfo, string baseSavePath) { string rootName = Path.Combine(baseSavePath, CreateSaveFileName(formatString, progInfo, epInfo)); string savePath = rootName; // Make sure the save folder exists (to support subfolders in the save file name template) string saveDir = Path.GetDirectoryName(savePath); Directory.CreateDirectory(saveDir); string currentFileName = null; // If the passed episode info is actually a download, get it's current path if (typeof(Download) == epInfo.GetType()) { currentFileName = ((Download)epInfo).DownloadPath; // Remove the extension from the current name if applicable if (currentFileName != null) { int extensionPos = currentFileName.LastIndexOf('.'); if (extensionPos > -1) { currentFileName = currentFileName.Substring(0, extensionPos); } } } int diffNum = 1; // Check for a pre-existing file with the same name (ignoring the current name for this file) while (Directory.GetFiles(saveDir, Path.GetFileName(savePath) + ".*").Length > 0 && savePath != currentFileName) { savePath = rootName + Convert.ToString(diffNum, CultureInfo.CurrentCulture); diffNum += 1; } return savePath; }
public static string CreateSaveFileName(string formatString, Programme progInfo, Episode epInfo) { if (string.IsNullOrEmpty(formatString)) { // The format string is an empty string, so the output must be an empty string return string.Empty; } string fileName = formatString; // Convert %title% -> %epname% for backwards compatability fileName = fileName.Replace("%title%", "%epname%"); // Make variable substitutions fileName = fileName.Replace("%progname%", progInfo.Name.Replace(Path.DirectorySeparatorChar, ' ')); fileName = fileName.Replace("%epname%", epInfo.Name.Replace(Path.DirectorySeparatorChar, ' ')); fileName = fileName.Replace("%hour%", epInfo.Date.ToString("HH", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%minute%", epInfo.Date.ToString("mm", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%day%", epInfo.Date.ToString("dd", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%month%", epInfo.Date.ToString("MM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%shortmonthname%", epInfo.Date.ToString("MMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%monthname%", epInfo.Date.ToString("MMMM", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%year%", epInfo.Date.ToString("yy", CultureInfo.CurrentCulture)); fileName = fileName.Replace("%longyear%", epInfo.Date.ToString("yyyy", CultureInfo.CurrentCulture)); // Replace invalid file name characters with spaces (except for directory separators // as this then allows the flexibility of storing the downloads in subdirectories) foreach (char removeChar in Path.GetInvalidFileNameChars()) { if (removeChar != Path.DirectorySeparatorChar) { fileName = fileName.Replace(removeChar, ' '); } } // Replace runs of spaces with a single space fileName = Regex.Replace(fileName, " {2,}", " "); return fileName.Trim(); }
/// <summary> /// Initializes a new instance of the <see cref="ProgrammeInfo" /> class with the values /// contained in the specified Programme object. /// </summary> /// <param name="progInfo">Programme object specifying initial values.</param> internal ProgrammeInfo(Model.Programme progInfo) { this.Name = progInfo.Name; this.Description = progInfo.Description; this.SingleEpisode = progInfo.SingleEpisode; }
private static void CheckSubscriptions() { // Fetch the current subscriptions into a list, so that the reader doesn't remain open while // checking all of the subscriptions, as this blocks writes to the database from other threads List <Subscription> subscriptions = Subscription.FetchAll(); // Work through the list of subscriptions and check for new episodes foreach (Subscription subscription in subscriptions) { List <string> episodeExtIds = null; try { episodeExtIds = Programme.GetAvailableEpisodes(subscription.Progid, false); } catch (ProviderException) { // Ignore any unhandled provider exceptions continue; } if (episodeExtIds != null) { foreach (string episodeExtId in episodeExtIds) { int?epid = null; try { epid = Episode.FetchInfo(subscription.Progid, episodeExtId); } catch (ProviderException) { // Ignore any unhandled provider exceptions continue; } if (epid == null) { continue; } try { Episode.UpdateInfoIfRequired(epid.Value); } catch (ProviderException) { // Ignore any unhandled provider exceptions continue; } if (!subscription.SingleEpisode) { Episode info = new Episode(epid.Value); if (!info.AutoDownload) { // Don't download the episode automatically, skip to the next one continue; } else if (info.Date.AddDays(14) < DateTime.Now) { // Stop checking the episodes for this subscription, this and the rest // are past the automatic download threshold break; } } if (!Download.IsDownload(epid.Value)) { Download.Add(new int[] { epid.Value }); } } } } // Wait for 10 minutes to give a pause between each check for new episodes Thread.Sleep(600000); // Queue the next subscription check. This is used instead of a loop as // it frees up a slot in the thread pool in case other actions are waiting. ThreadPool.QueueUserWorkItem(delegate { CheckSubscriptions(); }); }