Exemple #1
0
        protected void FetchData(SQLiteMonDataReader reader)
        {
            int descriptionOrdinal    = reader.GetOrdinal("description");
            int latestdownloadOrdinal = reader.GetOrdinal("latestdownload");

            this.Progid = reader.GetInt32(reader.GetOrdinal("progid"));
            this.Name   = reader.GetString(reader.GetOrdinal("name"));

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

            this.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));

            Guid     pluginId = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
            Provider provider = Provider.GetFromId(pluginId);

            if (provider != null)
            {
                this.ProviderName = provider.Name;
            }
            else
            {
                this.ProviderName = "<missing>";
            }

            if (!reader.IsDBNull(latestdownloadOrdinal))
            {
                this.LatestDownload = reader.GetDateTime(latestdownloadOrdinal);
            }
        }
Exemple #2
0
        protected void FetchData(SQLiteMonDataReader reader)
        {
            int descriptionOrdinal = reader.GetOrdinal("description");
            int durationOrdinal    = reader.GetOrdinal("duration");
            int imageOrdinal       = reader.GetOrdinal("image");

            this.Epid   = reader.GetInt32(reader.GetOrdinal("epid"));
            this.Progid = reader.GetInt32(reader.GetOrdinal("progid"));
            this.Date   = reader.GetDateTime(reader.GetOrdinal("date"));
            this.Name   = reader.GetString(reader.GetOrdinal("name"));

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

            if (!reader.IsDBNull(durationOrdinal))
            {
                this.Duration = reader.GetInt32(durationOrdinal);
            }

            this.AutoDownload = reader.GetInt32(reader.GetOrdinal("autodownload")) == 1;

            if (!reader.IsDBNull(imageOrdinal))
            {
                this.imgid = reader.GetInt32(imageOrdinal);
            }
        }
Exemple #3
0
        protected new void FetchData(SQLiteMonDataReader reader)
        {
            base.FetchData(reader);

            int filepathOrdinal = reader.GetOrdinal("filepath");

            this.Status = (DownloadStatus)reader.GetInt32(reader.GetOrdinal("status"));

            if (this.Status == DownloadStatus.Errored)
            {
                this.ErrorType = (Provider.ErrorType)reader.GetInt32(reader.GetOrdinal("errortype"));

                if (this.ErrorType != Provider.ErrorType.UnknownError)
                {
                    this.ErrorDetails = reader.GetString(reader.GetOrdinal("errordetails"));
                }
            }

            if (!reader.IsDBNull(filepathOrdinal))
            {
                this.DownloadPath = reader.GetString(filepathOrdinal);
            }

            this.PlayCount = reader.GetInt32(reader.GetOrdinal("playcount"));
        }
Exemple #4
0
        public static System.Drawing.Bitmap GetImage(int epid)
        {
            using (SQLiteCommand command = new SQLiteCommand("select image, progid from episodes where epid=@epid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@epid", epid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (reader.Read())
                    {
                        int imageOrdinal = reader.GetOrdinal("image");

                        if (!reader.IsDBNull(imageOrdinal))
                        {
                            return(RetrieveImage(reader.GetInt32(imageOrdinal)));
                        }

                        using (SQLiteCommand progCmd = new SQLiteCommand("select image from programmes where progid=@progid and image not null", FetchDbConn()))
                        {
                            progCmd.Parameters.Add(new SQLiteParameter("@progid", reader.GetInt32(reader.GetOrdinal("progid"))));

                            using (SQLiteMonDataReader progReader = new SQLiteMonDataReader(progCmd.ExecuteReader()))
                            {
                                if (progReader.Read())
                                {
                                    return(RetrieveImage(progReader.GetInt32(progReader.GetOrdinal("image"))));
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
        private void FetchData(SQLiteMonDataReader reader)
        {
            int linkOrdinal  = reader.GetOrdinal("link");
            int imageOrdinal = reader.GetOrdinal("image");

            this.Start = TimeSpan.FromMilliseconds(reader.GetInt32(reader.GetOrdinal("start")));
            this.Name  = reader.GetString(reader.GetOrdinal("name"));

            if (!reader.IsDBNull(linkOrdinal))
            {
                this.Link = new Uri(reader.GetString(linkOrdinal));
            }

            if (!reader.IsDBNull(imageOrdinal))
            {
                this.imgid = reader.GetInt32(imageOrdinal);
            }
        }
Exemple #6
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 (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;
                }
            }
        }
Exemple #7
0
        protected void FetchData(SQLiteMonDataReader reader)
        {
            int descriptionOrdinal = reader.GetOrdinal("description");
            int durationOrdinal = reader.GetOrdinal("duration");

            this.Epid = reader.GetInt32(reader.GetOrdinal("epid"));
            this.Progid = reader.GetInt32(reader.GetOrdinal("progid"));
            this.Date = reader.GetDateTime(reader.GetOrdinal("date"));
            this.Name = reader.GetString(reader.GetOrdinal("name"));

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

            if (!reader.IsDBNull(durationOrdinal))
            {
                this.Duration = reader.GetInt32(durationOrdinal);
            }

            this.AutoDownload = reader.GetInt32(reader.GetOrdinal("autodownload")) == 1;
        }
Exemple #8
0
        public static System.Drawing.Bitmap GetImage(int epid)
        {
            using (SQLiteCommand command = new SQLiteCommand("select image, progid from episodes where epid=@epid", FetchDbConn()))
            {
                command.Parameters.Add(new SQLiteParameter("@epid", epid));

                using (SQLiteMonDataReader reader = new SQLiteMonDataReader(command.ExecuteReader()))
                {
                    if (reader.Read())
                    {
                        int imageOrdinal = reader.GetOrdinal("image");

                        if (!reader.IsDBNull(imageOrdinal))
                        {
                            return RetrieveImage(reader.GetInt32(imageOrdinal));
                        }

                        using (SQLiteCommand progCmd = new SQLiteCommand("select image from programmes where progid=@progid and image not null", FetchDbConn()))
                        {
                            progCmd.Parameters.Add(new SQLiteParameter("@progid", reader.GetInt32(reader.GetOrdinal("progid"))));

                            using (SQLiteMonDataReader progReader = new SQLiteMonDataReader(progCmd.ExecuteReader()))
                            {
                                if (progReader.Read())
                                {
                                    return RetrieveImage(progReader.GetInt32(progReader.GetOrdinal("image")));
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }
Exemple #9
0
        protected void FetchData(SQLiteMonDataReader reader)
        {
            int descriptionOrdinal = reader.GetOrdinal("description");
            int latestdownloadOrdinal = reader.GetOrdinal("latestdownload");

            this.Progid = reader.GetInt32(reader.GetOrdinal("progid"));
            this.extId = reader.GetString(reader.GetOrdinal("extid"));
            this.Name = reader.GetString(reader.GetOrdinal("name"));

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

            this.SingleEpisode = reader.GetBoolean(reader.GetOrdinal("singleepisode"));

            Guid pluginId = new Guid(reader.GetString(reader.GetOrdinal("pluginid")));
            Provider provider = Provider.GetFromId(pluginId);

            if (provider != null)
            {
                this.ProviderName = provider.Name;
                this.moreInfoHandler = provider.ShowMoreProgInfoHandler;
            }
            else
            {
                this.ProviderName = "<missing>";
            }

            if (!reader.IsDBNull(latestdownloadOrdinal))
            {
                this.LatestDownload = reader.GetDateTime(latestdownloadOrdinal);
            }
        }
Exemple #10
0
        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;
        }
Exemple #11
0
        private static int?UpdateInfo(int progid, string episodeExtId)
        {
            Guid   pluginId;
            string progExtId;

            Provider.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 Provider.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"));
                }
            }

            Provider.RadioProvider providerInst = Provider.Handler.GetFromId(pluginId).CreateInstance();
            Provider.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);
                }
            }
        }
        protected new void FetchData(SQLiteMonDataReader reader)
        {
            base.FetchData(reader);

            int filepathOrdinal = reader.GetOrdinal("filepath");

            this.Status = (DownloadStatus)reader.GetInt32(reader.GetOrdinal("status"));

            if (this.Status == DownloadStatus.Errored)
            {
                this.ErrorType = (ErrorType)reader.GetInt32(reader.GetOrdinal("errortype"));

                if (this.ErrorType != ErrorType.UnknownError)
                {
                    this.ErrorDetails = reader.GetString(reader.GetOrdinal("errordetails"));
                }
            }

            if (!reader.IsDBNull(filepathOrdinal))
            {
                this.DownloadPath = reader.GetString(filepathOrdinal);
            }

            this.PlayCount = reader.GetInt32(reader.GetOrdinal("playcount"));
        }
Exemple #13
0
        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);
        }