コード例 #1
0
        public AvailableEpisodes GetAvailableEpisodes(string progExtId, ProgrammeInfo progInfo, int page)
        {
            AvailableEpisodes available = new AvailableEpisodes();
            XmlDocument       rss       = this.LoadFeedXml(new Uri(progExtId));

            XmlNodeList itemNodes = null;

            itemNodes = rss.SelectNodes("./rss/channel/item");

            if (itemNodes == null)
            {
                return(available);
            }

            List <string> episodeIDs = new List <string>();

            foreach (XmlNode itemNode in itemNodes)
            {
                string itemId = this.ItemNodeToEpisodeID(itemNode);

                if (!string.IsNullOrEmpty(itemId))
                {
                    episodeIDs.Add(itemId);
                }
            }

            available.EpisodeIds = episodeIDs.ToArray();
            return(available);
        }
コード例 #2
0
        public override AvailableEpisodes GetAvailableEpisodes(string progExtId, ProgrammeInfo progInfo, int page)
        {
            AvailableEpisodes available = new AvailableEpisodes();
            XmlDocument       rss       = this.LoadFeedXml(new Uri(progExtId));

            XmlNodeList itemNodes = null;

            itemNodes = rss.SelectNodes("./rss/channel/item");

            if (itemNodes == null)
            {
                return(available);
            }

            foreach (XmlNode itemNode in itemNodes)
            {
                string itemId = this.ItemNodeToEpisodeID(itemNode);

                if (string.IsNullOrEmpty(itemId))
                {
                    continue;
                }

                if (this.FilterItemNode(itemNode))
                {
                    continue;
                }

                available.EpisodeIds.Add(itemId);
            }

            return(available);
        }
コード例 #3
0
        public override AvailableEpisodes GetAvailableEpisodes(string progExtId, ProgrammeInfo progInfo, int page)
        {
            AvailableEpisodes available = new AvailableEpisodes();
            XmlDocument       rss       = this.LoadFeedXml(new Uri(progExtId));

            XmlNodeList itemNodes = null;

            itemNodes = rss.SelectNodes("./rss/channel/item");

            if (itemNodes == null)
            {
                return(available);
            }

            foreach (XmlNode itemNode in itemNodes)
            {
                string itemId = this.ItemNodeToEpisodeID(itemNode);

                if (string.IsNullOrEmpty(itemId))
                {
                    continue;
                }

                if (itemNode.SelectSingleNode("./title[text()]") == null)
                {
                    continue;
                }

                var urlAttrib = itemNode.SelectSingleNode("./enclosure/@url") as XmlAttribute;

                if (urlAttrib == null)
                {
                    continue;
                }

                Uri uri;
                Uri.TryCreate(urlAttrib.Value, UriKind.Absolute, out uri);

                if (uri == null)
                {
                    continue;
                }

                available.EpisodeIds.Add(itemId);
            }

            return(available);
        }
コード例 #4
0
        public ProgrammeInfo GetProgrammeInfo(string progExtId)
        {
            XmlDocument         rss          = this.LoadFeedXml(new Uri(progExtId));
            XmlNamespaceManager namespaceMgr = this.CreateNamespaceMgr(rss);

            XmlNode titleNode = rss.SelectSingleNode("./rss/channel/title");

            if (titleNode == null || string.IsNullOrEmpty(titleNode.InnerText))
            {
                throw new InvalidDataException("Channel title node is missing or empty");
            }

            ProgrammeInfo progInfo = new ProgrammeInfo();

            progInfo.Name = titleNode.InnerText;

            XmlNode descriptionNode = null;

            // If the channel has an itunes:summary tag use this for the description (as it shouldn't contain HTML)
            if (namespaceMgr.HasNamespace("itunes"))
            {
                descriptionNode = rss.SelectSingleNode("./rss/channel/itunes:summary", namespaceMgr);
            }

            if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText))
            {
                progInfo.Description = descriptionNode.InnerText;
            }
            else
            {
                // Fall back to the standard description tag, but strip the HTML
                descriptionNode = rss.SelectSingleNode("./rss/channel/description");

                if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText))
                {
                    progInfo.Description = this.HtmlToText(descriptionNode.InnerText);
                }
            }

            progInfo.Image = this.RSSNodeImage(rss.SelectSingleNode("./rss/channel"), namespaceMgr);

            return(progInfo);
        }
コード例 #5
0
        public override ProgrammeInfo GetProgrammeInfo(string progExtId)
        {
            XmlDocument         rss          = this.LoadFeedXml(new Uri(progExtId));
            XmlNamespaceManager namespaceMgr = this.CreateNamespaceMgr(rss);

            XmlNode titleNode = rss.SelectSingleNode("./rss/channel/title");

            if (titleNode == null || string.IsNullOrEmpty(titleNode.InnerText))
            {
                throw new InvalidDataException("Channel title node is missing or empty");
            }

            ProgrammeInfo progInfo = new ProgrammeInfo();

            progInfo.Name = titleNode.InnerText;

            // If the channel has an itunes:summary tag use this for the description (as it shouldn't contain HTML)
            var descriptionNode = rss.SelectSingleNode("./rss/channel/itunes:summary", namespaceMgr);

            if (!string.IsNullOrEmpty(descriptionNode?.InnerText))
            {
                progInfo.Description = this.TidyUpWhitespace(descriptionNode.InnerText);
            }
            else
            {
                // Fall back to the standard description tag, but strip the HTML
                descriptionNode = rss.SelectSingleNode("./rss/channel/description");

                if (!string.IsNullOrEmpty(descriptionNode?.InnerText))
                {
                    progInfo.Description = this.TidyUpWhitespace(HtmlToText.ConvertHtml(descriptionNode.InnerText));
                }
            }

            progInfo.Image = this.FetchImage(rss, "./rss/channel/itunes:image/@href", namespaceMgr);

            if (progInfo.Image == null)
            {
                progInfo.Image = this.FetchImage(rss, "./rss/channel/image/url/text()", namespaceMgr);
            }

            return(progInfo);
        }
コード例 #6
0
ファイル: Episode.cs プロジェクト: ribbons/RadioDownloader
        private static int? UpdateInfo(int progid, string episodeExtId)
        {
            Guid pluginId;
            string progExtId;
            ProgrammeInfo progInfo;

            using (SQLiteCommand command = new SQLiteCommand("select pluginid, extid, name, description, singleepisode from programmes where progid=@progid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (!reader.Read())
                    {
                        throw new DataNotFoundException(progid, "Programme does not exist");
                    }

                    pluginId = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
                    progExtId = reader.GetString(reader.GetOrdinal("extid"));

                    progInfo = new ProgrammeInfo();
                    progInfo.Name = reader.GetString(reader.GetOrdinal("name"));
                    int descriptionOrdinal = reader.GetOrdinal("description");

                    if (!reader.IsDBNull(descriptionOrdinal))
                    {
                        progInfo.Description = reader.GetString(descriptionOrdinal);
                    }

                    progInfo.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));
                }
            }

            IRadioProvider providerInst = Provider.GetFromId(pluginId).CreateInstance();
            EpisodeInfo episodeInfo;

            try
            {
                episodeInfo = providerInst.GetEpisodeInfo(progExtId, progInfo, episodeExtId);

                if (episodeInfo == null)
                {
                    return null;
                }

                if (string.IsNullOrEmpty(episodeInfo.Name))
                {
                    throw new InvalidDataException("Episode name cannot be null or an empty string");
                }
            }
            catch (Exception provExp)
            {
                provExp.Data.Add("Programme", progInfo.ToString() + "\r\nExtID: " + progExtId);
                provExp.Data.Add("Episode ExtID", episodeExtId);
                throw new ProviderException("Call to GetEpisodeInfo failed", provExp, pluginId);
            }

            if (episodeInfo.Date == null)
            {
                // The date of the episode isn't known, so use the current date
                episodeInfo.Date = DateTime.Now;
            }

            lock (DbUpdateLock)
            {
                using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction()))
                {
                    int? epid = null;

                    using (SQLiteCommand command = new SQLiteCommand("select epid from episodes where progid=@progid and extid=@extid", FetchDbConn(), transMon.Trans))
                    {
                        command.Parameters.Add(new SQLiteParameter("@progid", progid));
                        command.Parameters.Add(new SQLiteParameter("@extid", episodeExtId));

                        using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                        {
                            if (reader.Read())
                            {
                                epid = reader.GetInt32(reader.GetOrdinal("epid"));
                            }
                        }
                    }

                    if (epid == null)
                    {
                        using (SQLiteCommand command = new SQLiteCommand("insert into episodes (progid, extid, name, date) values (@progid, @extid, @name, @date)", FetchDbConn(), transMon.Trans))
                        {
                            command.Parameters.Add(new SQLiteParameter("@progid", progid));
                            command.Parameters.Add(new SQLiteParameter("@extid", episodeExtId));
                            command.Parameters.Add(new SQLiteParameter("@name", episodeInfo.Name));
                            command.Parameters.Add(new SQLiteParameter("@date", episodeInfo.Date));
                            command.ExecuteNonQuery();
                        }

                        using (SQLiteCommand command = new SQLiteCommand("select last_insert_rowid()", FetchDbConn(), transMon.Trans))
                        {
                            epid = (int)(long)command.ExecuteScalar();
                        }
                    }

                    using (SQLiteCommand command = new SQLiteCommand("update episodes set name=@name, description=@description, duration=@duration, date=@date, image=@image, available=1 where epid=@epid", FetchDbConn(), transMon.Trans))
                    {
                        command.Parameters.Add(new SQLiteParameter("@name", episodeInfo.Name));
                        command.Parameters.Add(new SQLiteParameter("@description", episodeInfo.Description));
                        command.Parameters.Add(new SQLiteParameter("@duration", episodeInfo.Duration));
                        command.Parameters.Add(new SQLiteParameter("@date", episodeInfo.Date));
                        command.Parameters.Add(new SQLiteParameter("@image", StoreImage(episodeInfo.Image)));
                        command.Parameters.Add(new SQLiteParameter("@epid", epid));
                        command.ExecuteNonQuery();
                    }

                    using (SQLiteCommand command = new SQLiteCommand("insert or replace into episodeext (epid, name, value) values (@epid, @name, @value)", FetchDbConn(), transMon.Trans))
                    {
                        foreach (KeyValuePair<string, string> extItem in episodeInfo.ExtInfo)
                        {
                            command.Parameters.Add(new SQLiteParameter("@epid", epid));
                            command.Parameters.Add(new SQLiteParameter("@name", extItem.Key));
                            command.Parameters.Add(new SQLiteParameter("@value", extItem.Value));
                            command.ExecuteNonQuery();
                        }
                    }

                    transMon.Trans.Commit();
                    return epid;
                }
            }
        }
コード例 #7
0
ファイル: Programme.cs プロジェクト: ribbons/RadioDownloader
        public static List<string> GetAvailableEpisodes(int progid, bool fetchAll)
        {
            Guid providerId;
            string progExtId;
            ProgrammeInfo progInfo;

            using (SQLiteCommand command = new SQLiteCommand("select pluginid, extid, name, description, singleepisode from programmes where progid=@progid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (!reader.Read())
                    {
                        throw new DataNotFoundException(progid, "Programme does not exist");
                    }

                    providerId = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
                    progExtId = reader.GetString(reader.GetOrdinal("extid"));

                    progInfo = new ProgrammeInfo();
                    progInfo.Name = reader.GetString(reader.GetOrdinal("name"));
                    int descriptionOrdinal = reader.GetOrdinal("description");

                    if (!reader.IsDBNull(descriptionOrdinal))
                    {
                        progInfo.Description = reader.GetString(descriptionOrdinal);
                    }

                    progInfo.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));
                }
            }

            if (!Provider.Exists(providerId))
            {
                return null;
            }

            // Fetch a list of previously available episodes for the programme
            List<string> previousAvailable = new List<string>();

            using (SQLiteCommand command = new SQLiteCommand("select extid from episodes where progid=@progid and available=1 order by date desc", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    int epidOrdinal = reader.GetOrdinal("extid");

                    while (reader.Read())
                    {
                        previousAvailable.Add(reader.GetString(epidOrdinal));
                    }
                }
            }

            List<string> allEpExtIds = new List<string>();
            int page = 1;

            IRadioProvider providerInst = Provider.GetFromId(providerId).CreateInstance();
            AvailableEpisodes available;

            do
            {
                try
                {
                    available = providerInst.GetAvailableEpisodes(progExtId, progInfo, page);
                }
                catch (Exception provExp)
                {
                    provExp.Data.Add("Programme ExtID", progExtId);
                    throw new ProviderException("Call to GetAvailableEpisodeIds failed", provExp, providerId);
                }

                if (available.EpisodeIds.Count == 0)
                {
                    break;
                }

                int trackOverlap = -1;

                foreach (string epExtId in available.EpisodeIds)
                {
                    // Append the returned IDs to the list of all episodes (minus duplicates)
                    if (!allEpExtIds.Contains(epExtId))
                    {
                        allEpExtIds.Add(epExtId);
                    }

                    if (previousAvailable.Contains(epExtId))
                    {
                        // Store where the available & previously available ID lists overlap
                        trackOverlap = previousAvailable.IndexOf(epExtId);
                    }
                    else if (trackOverlap >= 0)
                    {
                        // Bump up the overlap index to show there are more after the overlap
                        trackOverlap++;
                    }
                }

                if (available.MoreAvailable && !fetchAll)
                {
                    if (trackOverlap >= 0)
                    {
                        // Remove previously available programmes before this page from the list so that they
                        // are not incorrectly un-flagged as available in the database
                        if (trackOverlap < previousAvailable.Count - 1)
                        {
                            previousAvailable.RemoveRange(trackOverlap + 1, previousAvailable.Count - (trackOverlap + 1));
                        }

                        // Stop fetching available episode pages
                        break;
                    }
                }

                page++;
            }
            while (available.MoreAvailable);

            // Remove the still available episodes from the previously available list
            foreach (string epExtId in allEpExtIds)
            {
                previousAvailable.Remove(epExtId);
            }

            // Unflag any no-longer available episodes in the database
            if (previousAvailable.Count > 0)
            {
                lock (DbUpdateLock)
                {
                    using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction()))
                    {
                        using (SQLiteCommand command = new SQLiteCommand("update episodes set available=0 where progid=@progid and extid=@extid", FetchDbConn(), transMon.Trans))
                        {
                            SQLiteParameter extidParam = new SQLiteParameter("@extid");
                            command.Parameters.Add(new SQLiteParameter("@progid", progid));
                            command.Parameters.Add(extidParam);

                            foreach (string epExtId in previousAvailable)
                            {
                                extidParam.Value = epExtId;
                                command.ExecuteNonQuery();
                            }
                        }

                        transMon.Trans.Commit();
                    }
                }
            }

            return allEpExtIds;
        }
コード例 #8
0
        private static int?UpdateInfo(int progid, string episodeExtId)
        {
            Guid          pluginId;
            string        progExtId;
            ProgrammeInfo progInfo;

            using (SQLiteCommand command = new SQLiteCommand("select pluginid, extid, name, description, singleepisode from programmes where progid=@progid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (!reader.Read())
                    {
                        throw new DataNotFoundException(progid, "Programme does not exist");
                    }

                    pluginId  = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
                    progExtId = reader.GetString(reader.GetOrdinal("extid"));

                    progInfo      = new ProgrammeInfo();
                    progInfo.Name = reader.GetString(reader.GetOrdinal("name"));
                    int descriptionOrdinal = reader.GetOrdinal("description");

                    if (!reader.IsDBNull(descriptionOrdinal))
                    {
                        progInfo.Description = reader.GetString(descriptionOrdinal);
                    }

                    progInfo.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));
                }
            }

            IRadioProvider providerInst = Provider.GetFromId(pluginId).CreateInstance();
            EpisodeInfo    episodeInfo;

            try
            {
                episodeInfo = providerInst.GetEpisodeInfo(progExtId, progInfo, episodeExtId);

                if (episodeInfo == null)
                {
                    return(null);
                }

                if (string.IsNullOrEmpty(episodeInfo.Name))
                {
                    throw new InvalidDataException("Episode name cannot be null or an empty string");
                }
            }
            catch (Exception provExp)
            {
                provExp.Data.Add("Programme", progInfo.ToString() + "\r\nExtID: " + progExtId);
                provExp.Data.Add("Episode ExtID", episodeExtId);
                throw new ProviderException("Call to GetEpisodeInfo failed", provExp, pluginId);
            }

            if (episodeInfo.Date == null)
            {
                // The date of the episode isn't known, so use the current date
                episodeInfo.Date = DateTime.Now;
            }

            lock (Database.DbUpdateLock)
            {
                using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction()))
                {
                    int?epid = null;

                    using (SQLiteCommand command = new SQLiteCommand("select epid from episodes where progid=@progid and extid=@extid", FetchDbConn(), transMon.Trans))
                    {
                        command.Parameters.Add(new SQLiteParameter("@progid", progid));
                        command.Parameters.Add(new SQLiteParameter("@extid", episodeExtId));

                        using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                        {
                            if (reader.Read())
                            {
                                epid = reader.GetInt32(reader.GetOrdinal("epid"));
                            }
                        }
                    }

                    if (epid == null)
                    {
                        using (SQLiteCommand command = new SQLiteCommand("insert into episodes (progid, extid, name, date) values (@progid, @extid, @name, @date)", FetchDbConn(), transMon.Trans))
                        {
                            command.Parameters.Add(new SQLiteParameter("@progid", progid));
                            command.Parameters.Add(new SQLiteParameter("@extid", episodeExtId));
                            command.Parameters.Add(new SQLiteParameter("@name", episodeInfo.Name));
                            command.Parameters.Add(new SQLiteParameter("@date", episodeInfo.Date));
                            command.ExecuteNonQuery();
                        }

                        using (SQLiteCommand command = new SQLiteCommand("select last_insert_rowid()", FetchDbConn(), transMon.Trans))
                        {
                            epid = (int)(long)command.ExecuteScalar();
                        }
                    }

                    using (SQLiteCommand command = new SQLiteCommand("update episodes set name=@name, description=@description, duration=@duration, date=@date, image=@image, available=1 where epid=@epid", FetchDbConn(), transMon.Trans))
                    {
                        command.Parameters.Add(new SQLiteParameter("@name", episodeInfo.Name));
                        command.Parameters.Add(new SQLiteParameter("@description", episodeInfo.Description));
                        command.Parameters.Add(new SQLiteParameter("@duration", episodeInfo.Duration));
                        command.Parameters.Add(new SQLiteParameter("@date", episodeInfo.Date));
                        command.Parameters.Add(new SQLiteParameter("@image", StoreImage(episodeInfo.Image)));
                        command.Parameters.Add(new SQLiteParameter("@epid", epid));
                        command.ExecuteNonQuery();
                    }

                    using (SQLiteCommand command = new SQLiteCommand("insert or replace into episodeext (epid, name, value) values (@epid, @name, @value)", FetchDbConn(), transMon.Trans))
                    {
                        foreach (KeyValuePair <string, string> extItem in episodeInfo.ExtInfo)
                        {
                            command.Parameters.Add(new SQLiteParameter("@epid", epid));
                            command.Parameters.Add(new SQLiteParameter("@name", extItem.Key));
                            command.Parameters.Add(new SQLiteParameter("@value", extItem.Value));
                            command.ExecuteNonQuery();
                        }
                    }

                    transMon.Trans.Commit();
                    return(epid);
                }
            }
        }
コード例 #9
0
ファイル: Programme.cs プロジェクト: chrisbu/RadioDownloader
        public static List <string> GetAvailableEpisodes(int progid, bool fetchAll)
        {
            Guid          providerId;
            string        progExtId;
            ProgrammeInfo progInfo;

            using (SQLiteCommand command = new SQLiteCommand("select pluginid, extid, name, description, singleepisode from programmes where progid=@progid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (!reader.Read())
                    {
                        throw new DataNotFoundException(progid, "Programme does not exist");
                    }

                    providerId = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
                    progExtId  = reader.GetString(reader.GetOrdinal("extid"));

                    progInfo      = new ProgrammeInfo();
                    progInfo.Name = reader.GetString(reader.GetOrdinal("name"));
                    int descriptionOrdinal = reader.GetOrdinal("description");

                    if (!reader.IsDBNull(descriptionOrdinal))
                    {
                        progInfo.Description = reader.GetString(descriptionOrdinal);
                    }

                    progInfo.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));
                }
            }

            if (!Provider.Exists(providerId))
            {
                return(null);
            }

            // Fetch a list of previously available episodes for the programme
            List <string> previousAvailable = new List <string>();

            using (SQLiteCommand command = new SQLiteCommand("select extid from episodes where progid=@progid and available=1 order by date desc", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@progid", progid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    int epidOrdinal = reader.GetOrdinal("extid");

                    while (reader.Read())
                    {
                        previousAvailable.Add(reader.GetString(epidOrdinal));
                    }
                }
            }

            List <string> allEpExtIds = new List <string>();
            int           page        = 1;

            IRadioProvider    providerInst = Provider.GetFromId(providerId).CreateInstance();
            AvailableEpisodes available;

            do
            {
                try
                {
                    available = providerInst.GetAvailableEpisodes(progExtId, progInfo, page);
                }
                catch (Exception provExp)
                {
                    provExp.Data.Add("Programme ExtID", progExtId);
                    throw new ProviderException("Call to GetAvailableEpisodeIds failed", provExp, providerId);
                }

                if (available.EpisodeIds == null || available.EpisodeIds.Length == 0)
                {
                    break;
                }

                int trackOverlap = -1;

                foreach (string epExtId in available.EpisodeIds)
                {
                    // Append the returned IDs to the list of all episodes (minus duplicates)
                    if (!allEpExtIds.Contains(epExtId))
                    {
                        allEpExtIds.Add(epExtId);
                    }

                    if (previousAvailable.Contains(epExtId))
                    {
                        // Store where the available & previously available ID lists overlap
                        trackOverlap = previousAvailable.IndexOf(epExtId);
                    }
                    else if (trackOverlap >= 0)
                    {
                        // Bump up the overlap index to show there are more after the overlap
                        trackOverlap++;
                    }
                }

                if (available.MoreAvailable && !fetchAll)
                {
                    if (trackOverlap >= 0)
                    {
                        // Remove previously available programmes before this page from the list so that they
                        // are not incorrectly un-flagged as available in the database
                        if (trackOverlap < previousAvailable.Count - 1)
                        {
                            previousAvailable.RemoveRange(trackOverlap + 1, previousAvailable.Count - (trackOverlap + 1));
                        }

                        // Stop fetching available episode pages
                        break;
                    }
                }

                page++;
            }while (available.MoreAvailable);

            // Remove the still available episodes from the previously available list
            foreach (string epExtId in allEpExtIds)
            {
                previousAvailable.Remove(epExtId);
            }

            // Unflag any no-longer available episodes in the database
            if (previousAvailable.Count > 0)
            {
                lock (Database.DbUpdateLock)
                {
                    using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction()))
                    {
                        using (SQLiteCommand command = new SQLiteCommand("update episodes set available=0 where progid=@progid and extid=@extid", FetchDbConn(), transMon.Trans))
                        {
                            SQLiteParameter extidParam = new SQLiteParameter("@extid");
                            command.Parameters.Add(new SQLiteParameter("@progid", progid));
                            command.Parameters.Add(extidParam);

                            foreach (string epExtId in previousAvailable)
                            {
                                extidParam.Value = epExtId;
                                command.ExecuteNonQuery();
                            }
                        }

                        transMon.Trans.Commit();
                    }
                }
            }

            return(allEpExtIds);
        }
コード例 #10
0
        public string DownloadProgramme(string progExtId, string episodeExtId, ProgrammeInfo progInfo, EpisodeInfo epInfo, string finalName)
        {
            XmlDocument         rss           = this.LoadFeedXml(new Uri(progExtId));
            XmlNamespaceManager namespaceMgr  = this.CreateNamespaceMgr(rss);
            XmlNode             itemNode      = this.ItemNodeFromEpisodeID(rss, episodeExtId);
            XmlNode             enclosureNode = itemNode.SelectSingleNode("./enclosure");
            XmlAttribute        urlAttrib     = enclosureNode.Attributes["url"];
            Uri downloadUrl = new Uri(urlAttrib.Value);

            int    fileNamePos  = finalName.LastIndexOf("\\", StringComparison.Ordinal);
            int    extensionPos = downloadUrl.AbsolutePath.LastIndexOf(".", StringComparison.Ordinal);
            string extension    = "mp3";

            if (extensionPos > -1)
            {
                extension = downloadUrl.AbsolutePath.Substring(extensionPos + 1);
            }

            using (TempFile downloadFile = new TempFile(extension))
            {
                finalName += "." + extension;

                this.doDownload = new DownloadWrapper(downloadUrl, downloadFile.FilePath);
                this.doDownload.DownloadProgress += this.DoDownload_DownloadProgress;
                this.doDownload.Download();

                while ((!this.doDownload.Complete) && this.doDownload.Error == null)
                {
                    Thread.Sleep(500);
                }

                if (this.doDownload.Error != null)
                {
                    if (this.doDownload.Error is WebException)
                    {
                        WebException webExp = (WebException)this.doDownload.Error;

                        if (webExp.Status == WebExceptionStatus.NameResolutionFailure)
                        {
                            throw new DownloadException(ErrorType.NetworkProblem, "Unable to resolve " + downloadUrl.Host + " to download this episode from.  Check your internet connection or try again later.");
                        }
                        else if (webExp.Response is HttpWebResponse)
                        {
                            HttpWebResponse webErrorResponse = (HttpWebResponse)webExp.Response;

                            switch (webErrorResponse.StatusCode)
                            {
                            case HttpStatusCode.Forbidden:
                                throw new DownloadException(ErrorType.RemoteProblem, downloadUrl.Host + " returned a status 403 (Forbidden) in response to the request for this episode.  You may need to contact the podcast publisher if this problem persists.");

                            case HttpStatusCode.NotFound:
                                throw new DownloadException(ErrorType.NotAvailable, "This episode appears to be no longer available.  You can either try again later, or cancel the download to remove it from the list and clear the error.");
                            }
                        }
                    }

                    throw this.doDownload.Error;
                }

                if (this.Progress != null)
                {
                    this.Progress(100, ProgressType.Processing);
                }

                File.Move(downloadFile.FilePath, finalName);
            }

            return(extension);
        }
コード例 #11
0
        public EpisodeInfo GetEpisodeInfo(string progExtId, ProgrammeInfo progInfo, string episodeExtId)
        {
            XmlDocument         rss          = this.LoadFeedXml(new Uri(progExtId));
            XmlNamespaceManager namespaceMgr = this.CreateNamespaceMgr(rss);
            XmlNode             itemNode     = this.ItemNodeFromEpisodeID(rss, episodeExtId);

            if (itemNode == null)
            {
                return(null);
            }

            XmlNode titleNode     = itemNode.SelectSingleNode("./title");
            XmlNode pubDateNode   = itemNode.SelectSingleNode("./pubDate");
            XmlNode enclosureNode = itemNode.SelectSingleNode("./enclosure");

            if (enclosureNode == null)
            {
                return(null);
            }

            XmlAttribute urlAttrib = enclosureNode.Attributes["url"];

            if (urlAttrib == null)
            {
                return(null);
            }

            try
            {
                new Uri(urlAttrib.Value);
            }
            catch (UriFormatException)
            {
                // The enclosure url is empty or malformed
                return(null);
            }

            EpisodeInfo episodeInfo = new EpisodeInfo();

            if (titleNode == null || string.IsNullOrEmpty(titleNode.InnerText))
            {
                return(null);
            }

            episodeInfo.Name = titleNode.InnerText;

            XmlNode descriptionNode = null;

            // If the item has an itunes:summary tag use this for the description (as it shouldn't contain HTML)
            if (namespaceMgr.HasNamespace("itunes"))
            {
                descriptionNode = itemNode.SelectSingleNode("./itunes:summary", namespaceMgr);
            }

            if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText))
            {
                episodeInfo.Description = descriptionNode.InnerText;
            }
            else
            {
                // Fall back to the standard description tag, but strip the HTML
                descriptionNode = itemNode.SelectSingleNode("./description");

                if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText))
                {
                    episodeInfo.Description = this.HtmlToText(descriptionNode.InnerText);
                }
            }

            try
            {
                XmlNode durationNode = itemNode.SelectSingleNode("./itunes:duration", namespaceMgr);

                if (durationNode != null)
                {
                    string[] splitDuration = durationNode.InnerText.Split(new char[] { '.', ':' });

                    if (splitDuration.GetUpperBound(0) == 0)
                    {
                        episodeInfo.Duration = Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture);
                    }
                    else if (splitDuration.GetUpperBound(0) == 1)
                    {
                        episodeInfo.Duration = (Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture) * 60) + Convert.ToInt32(splitDuration[1], CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        episodeInfo.Duration = (((Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture) * 60) + Convert.ToInt32(splitDuration[1], CultureInfo.InvariantCulture)) * 60) + Convert.ToInt32(splitDuration[2], CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    episodeInfo.Duration = null;
                }
            }
            catch
            {
                episodeInfo.Duration = null;
            }

            if (pubDateNode != null)
            {
                string   pubDate = pubDateNode.InnerText.Trim();
                int      zonePos = pubDate.LastIndexOf(" ", StringComparison.Ordinal);
                TimeSpan offset  = new TimeSpan(0);

                if (zonePos > 0)
                {
                    string zone     = pubDate.Substring(zonePos + 1);
                    string zoneFree = pubDate.Substring(0, zonePos);

                    switch (zone)
                    {
                    case "GMT":
                        // No need to do anything
                        break;

                    case "UT":
                        offset  = new TimeSpan(0);
                        pubDate = zoneFree;
                        break;

                    case "EDT":
                        offset  = new TimeSpan(-4, 0, 0);
                        pubDate = zoneFree;
                        break;

                    case "EST":
                    case "CDT":
                        offset  = new TimeSpan(-5, 0, 0);
                        pubDate = zoneFree;
                        break;

                    case "CST":
                    case "MDT":
                        offset  = new TimeSpan(-6, 0, 0);
                        pubDate = zoneFree;
                        break;

                    case "MST":
                    case "PDT":
                        offset  = new TimeSpan(-7, 0, 0);
                        pubDate = zoneFree;
                        break;

                    case "PST":
                        offset  = new TimeSpan(-8, 0, 0);
                        pubDate = zoneFree;
                        break;

                    default:
                        if (zone.Length >= 4 && (Information.IsNumeric(zone) || Information.IsNumeric(zone.Substring(1))))
                        {
                            try
                            {
                                int value = int.Parse(zone, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture);
                                offset  = new TimeSpan(value / 100, value % 100, 0);
                                pubDate = zoneFree;
                            }
                            catch (FormatException)
                            {
                                // The last part of the date was not a time offset
                            }
                        }

                        break;
                    }
                }

                // Strip the day of the week from the beginning of the date string if it is there,
                // as it can contradict the date itself.
                string[] days =
                {
                    "mon,",
                    "tue,",
                    "wed,",
                    "thu,",
                    "fri,",
                    "sat,",
                    "sun,"
                };

                foreach (string day in days)
                {
                    if (pubDate.StartsWith(day, StringComparison.OrdinalIgnoreCase))
                    {
                        pubDate = pubDate.Substring(day.Length).Trim();
                        break;
                    }
                }

                try
                {
                    episodeInfo.Date = DateTime.Parse(pubDate, null, DateTimeStyles.AssumeUniversal);
                    episodeInfo.Date = episodeInfo.Date.Value.Subtract(offset);
                }
                catch (FormatException)
                {
                    episodeInfo.Date = null;
                }
            }
            else
            {
                episodeInfo.Date = null;
            }

            episodeInfo.Image = this.RSSNodeImage(itemNode, namespaceMgr);

            return(episodeInfo);
        }
コード例 #12
0
        public override DownloadInfo DownloadProgramme(string progExtId, string episodeExtId, ProgrammeInfo progInfo, EpisodeInfo epInfo)
        {
            XmlDocument rss      = this.LoadFeedXml(new Uri(progExtId));
            XmlNode     itemNode = this.ItemNodeFromEpisodeID(rss, episodeExtId);

            if (itemNode == null)
            {
                throw new DownloadException(ErrorType.RemoveFromList);
            }

            XmlNode      enclosureNode = itemNode.SelectSingleNode("./enclosure");
            XmlAttribute urlAttrib     = enclosureNode.Attributes["url"];
            Uri          downloadUrl   = new Uri(urlAttrib.Value);

            int extensionPos = downloadUrl.AbsolutePath.LastIndexOf(".", StringComparison.Ordinal);

            DownloadInfo info = new DownloadInfo();

            this.EpisodeChapters(info.Chapters, itemNode, this.CreateNamespaceMgr(rss));

            info.Extension = "mp3";

            if (extensionPos > -1)
            {
                info.Extension = downloadUrl.AbsolutePath.Substring(extensionPos + 1);
            }

            info.Downloaded = this.GetTempFileInstance(info.Extension);

            this.doDownload = this.GetDownloadWrapperInstance(downloadUrl, info.Downloaded.FilePath);
            this.doDownload.DownloadProgress += this.DoDownload_DownloadProgress;
            this.doDownload.Download();

            while ((!this.doDownload.Complete) && this.doDownload.Error == null)
            {
                Thread.Sleep(500);

                if (this.doDownload.Canceled)
                {
                    return(null);
                }
            }

            if (this.doDownload.Error != null)
            {
                if (this.doDownload.Error is WebException webExp)
                {
                    throw new DownloadException(
                              webExp.Status == WebExceptionStatus.ProtocolError
                            ? ErrorType.RemoteProblem
                            : ErrorType.NetworkProblem,
                              webExp.GetBaseException().Message);
                }

                throw this.doDownload.Error;
            }

            this.Progress?.Invoke(100, ProgressType.Downloading);

            return(info);
        }