private string DurationString(Model.Download download) { int hours = download.Duration / 3600; int mins = (download.Duration - (hours * 3600)) / 60; int secs = (download.Duration - (hours * 3600)) - (mins * 60); return(string.Format(CultureInfo.InvariantCulture, "{0:0:; ; }{1:00}:{2:00}", hours, mins, secs)); }
private void DownloadContent(HttpListenerContext context) { Regex epidPattern = new Regex(@"^\?epid=([0-9]+)$"); Match match = epidPattern.Match(context.Request.Url.Query); int epid; if (!int.TryParse(match.Groups[1].Value, out epid)) { // Request doesn't contain a valid episode id this.ErrorPage404(context); return; } Model.Download download; try { download = new Model.Download(epid); } catch (DataNotFoundException) { // Specified download does not exist this.ErrorPage404(context); return; } FileInfo file = new FileInfo(download.DownloadPath); if (!file.Exists) { // File for specified download no-longer exists this.ErrorPage404(context); return; } context.Response.ContentType = this.MimeTypeForFile(download.DownloadPath); context.Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name); context.Response.ContentLength64 = file.Length; using (FileStream fs = File.OpenRead(download.DownloadPath)) { byte[] buffer = new byte[4096]; int count; try { while ((count = fs.Read(buffer, 0, buffer.Length)) != 0) { context.Response.OutputStream.Write(buffer, 0, count); } } catch (HttpListenerException) { // Don't worry about dropped connections etc. } } }
private void ChapterImageContent(HttpListenerContext context) { Regex paramsPattern = new Regex(@"^\?epid=([0-9]+)&start=([0-9]+)$"); Match match = paramsPattern.Match(context.Request.Url.Query); int epid, start; if (!int.TryParse(match.Groups[1].Value, out epid)) { // Request doesn't contain a valid episode id this.ErrorPage404(context); return; } if (!int.TryParse(match.Groups[2].Value, out start)) { // Request doesn't contain a valid start time this.ErrorPage404(context); return; } var download = new Model.Download(epid); var chapter = new Model.Chapter(download, start); CompressedImage image = chapter.Image; if (image == null) { // Specified chapter does not have an image this.ErrorPage404(context); return; } context.Response.ContentType = "image/png"; // Find the appropriate codec for saving the image as a png System.Drawing.Imaging.ImageCodecInfo pngCodec = null; foreach (System.Drawing.Imaging.ImageCodecInfo codec in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()) { if (codec.MimeType == context.Response.ContentType) { pngCodec = codec; break; } } try { image.Image.Save(context.Response.OutputStream, pngCodec, null); } catch (HttpListenerException) { // Don't worry about dropped connections etc. } }
private void AddDownload(Model.Download storeData) { lock (this.updateIndexLock) { using (SQLiteCommand command = new SQLiteCommand("insert or replace into downloads (docid, name, description) values (@epid, @name, @description)", this.FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("@epid", storeData.Epid)); command.Parameters.Add(new SQLiteParameter("@name", storeData.Name)); command.Parameters.Add(new SQLiteParameter("@description", storeData.Description)); command.ExecuteNonQuery(); } } lock (this.downloadVisLock) { this.downloadsVisible = null; } }
private void AddDownload(int epid) { Model.Download downloadData = new Model.Download(epid); this.AddDownload(downloadData); }
private void DataSearch_DownloadUpdated(int epid) { if (this.IsDisposed) { return; } if (this.InvokeRequired) { this.Invoke((MethodInvoker)delegate { this.DataSearch_DownloadUpdated(epid); }); return; } Model.Download info = new Model.Download(epid); ListViewItem item = this.ListDownloads.Items[epid.ToString(CultureInfo.InvariantCulture)]; item = this.DownloadListItem(info, item); if (this.downloadColOrder.Contains(Model.Download.DownloadCols.Progress)) { this.ListDownloads.HideProgress(item); } // Update the downloads list sorting, as the order may now have changed this.ListDownloads.Sort(); if (this.view.CurrentView == ViewState.View.Downloads) { if (item.Selected) { this.ShowDownloadInfo(epid); } else if (this.ListDownloads.SelectedItems.Count == 0) { // Update the displayed statistics this.SetViewDefaults(); } } }
private void DataSearch_DownloadAdded(int epid) { if (this.IsDisposed) { return; } if (this.InvokeRequired) { this.Invoke((MethodInvoker)delegate { this.DataSearch_DownloadAdded(epid); }); return; } Model.Download info = new Model.Download(epid); this.ListDownloads.Items.Add(this.DownloadListItem(info, null)); if (this.view.CurrentView == ViewState.View.Downloads) { if (this.ListDownloads.SelectedItems.Count == 0) { // Update the displayed statistics this.SetViewDefaults(); } } }
private void ButtonPlay_Click() { int epid = Convert.ToInt32(this.ListDownloads.SelectedItems[0].Name, CultureInfo.InvariantCulture); Model.Download info = new Model.Download(epid); if (info.Status == Model.Download.DownloadStatus.Downloaded) { if (File.Exists(info.DownloadPath)) { try { Process.Start(info.DownloadPath); } catch (System.ComponentModel.Win32Exception playExp) { MessageBox.Show("Failed to play the download: " + playExp.Message + ". Check your file associations for " + Path.GetExtension(info.DownloadPath) + " files and try again.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // Bump the play count of this item up by one Model.Download.BumpPlayCount(epid); } } }
private void ShowDownloadInfo(int epid) { Model.Download info = new Model.Download(epid); string infoText = string.Empty; List<ToolBarButton> buttons = new List<ToolBarButton>(); buttons.Add(this.ButtonCleanUp); if (info.Description != null) { infoText += info.Description + Environment.NewLine + Environment.NewLine; } infoText += "Date: " + info.Date.ToString("ddd dd/MMM/yy HH:mm", CultureInfo.CurrentCulture); infoText += TextUtils.DescDuration(info.Duration); switch (info.Status) { case Model.Download.DownloadStatus.Downloaded: if (File.Exists(info.DownloadPath)) { buttons.Add(this.ButtonPlay); } buttons.Add(this.ButtonDelete); infoText += Environment.NewLine + "Play count: " + info.PlayCount.ToString(CultureInfo.CurrentCulture); break; case Model.Download.DownloadStatus.Errored: string errorName = string.Empty; string errorDetails = info.ErrorDetails; buttons.Add(this.ButtonRetry); buttons.Add(this.ButtonCancel); switch (info.ErrorType) { case ErrorType.LocalProblem: errorName = "Local problem"; break; case ErrorType.ShorterThanExpected: errorName = "Shorter than expected"; break; case ErrorType.NotAvailable: errorName = "Not available"; break; case ErrorType.NotAvailableInLocation: errorName = "Not available in your location"; break; case ErrorType.NetworkProblem: errorName = "Network problem"; break; case ErrorType.RemoteProblem: errorName = "Remote problem"; break; case ErrorType.UnknownError: errorName = "Unknown error"; errorDetails = "An unknown error occurred when trying to download this programme. Press the 'Report Error' button on the toolbar to send a report of this error back to NerdoftheHerd, so that it can be fixed."; buttons.Add(this.ButtonReportError); break; } infoText += Environment.NewLine + Environment.NewLine + "Error: " + errorName; if (!string.IsNullOrEmpty(errorDetails)) { infoText += Environment.NewLine + Environment.NewLine + errorDetails; } break; default: buttons.Add(this.ButtonCancel); break; } this.SetToolbarButtons(buttons.ToArray()); this.SetSideBar(TextUtils.StripDateFromName(info.Name, info.Date), infoText, Model.Episode.GetImage(epid)); }
private void ButtonDelete_Click() { int epid = Convert.ToInt32(this.ListDownloads.SelectedItems[0].Name, CultureInfo.InvariantCulture); Model.Download info = new Model.Download(epid); bool fileExists = File.Exists(info.DownloadPath); string delQuestion = "Are you sure that you would like to delete this episode"; if (fileExists) { delQuestion += " and the associated audio file"; } if (Interaction.MsgBox(delQuestion + "?", MsgBoxStyle.Question | MsgBoxStyle.YesNo) == MsgBoxResult.Yes) { if (fileExists) { try { File.Delete(info.DownloadPath); } catch (IOException) { if (Interaction.MsgBox("There was a problem deleting the audio file for this episode, as the file is in use by another application." + Environment.NewLine + Environment.NewLine + "Would you like to delete the episode from the list anyway?", MsgBoxStyle.Exclamation | MsgBoxStyle.YesNo) == MsgBoxResult.No) { return; } } catch (UnauthorizedAccessException) { if (Interaction.MsgBox("There was a problem deleting the audio file for this episode, as the file is either read-only or you do not have the permissions required." + Environment.NewLine + Environment.NewLine + "Would you like to delete the episode from the list anyway?", MsgBoxStyle.Exclamation | MsgBoxStyle.YesNo) == MsgBoxResult.No) { return; } } } Model.Download.Remove(epid); } }
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(); }); }