Example #1
0
                                         }; // TODO: move into settings, and allow user to edit these

        #endregion Fields

        #region Constructors

        public TVDoc(FileInfo settingsFile, TheTVDB tvdb, CommandLineArgs args)
        {
            this.mTVDB = tvdb;
            this.Args = args;

            this.Ignore = new List<IgnoreItem>();

            this.Workers = null;
            this.WorkerSemaphore = null;

            this.mStats = new TVRenameStats();
            this.mDirty = false;
            this.TheActionList = new ItemList();

            this.Settings = new TVSettings();

            this.MonitorFolders = new List<String>();
            this.IgnoreFolders = new List<String>();
            this.SearchFolders = new List<String>();

            ShowItems = new List<ShowItem>();
            this.AddItems = new FolderMonitorEntryList();

            this.DownloadDone = true;
            this.DownloadOK = true;

            this.ActionCancel = false;
            this.ScanProgDlg = null;

            this.LoadOK = ((settingsFile == null) || this.LoadXMLSettings(settingsFile)) && this.mTVDB.LoadOK;

            UpdateTVDBLanguage();

            //    StartServer();
        }
Example #2
0
        public bool Go(TVSettings settings, ref bool pause, TVRenameStats stats)
        {
            System.Net.WebClient wc = new System.Net.WebClient();
            try
            {
                byte[] r = wc.DownloadData(this.RSS.URL);
                if ((r == null) || (r.Length == 0))
                {
                    this.Error = true;
                    this.ErrorText = "No data downloaded";
                    this.Done = true;
                    return false;
                }

                string saveTemp = Path.GetTempPath() + System.IO.Path.DirectorySeparatorChar + settings.FilenameFriendly(this.RSS.Title);
                if (new FileInfo(saveTemp).Extension.ToLower() != "torrent")
                    saveTemp += ".torrent";
                File.WriteAllBytes(saveTemp, r);

                System.Diagnostics.Process.Start(settings.uTorrentPath, "/directory \"" + (new FileInfo(this.TheFileNoExt).Directory.FullName) + "\" \"" + saveTemp + "\"");

                this.Done = true;
                return true;
            }
            catch (Exception e)
            {
                this.ErrorText = e.Message;
                this.Error = true;
                this.Done = true;
                return false;
            }
        }
        public bool Go(TVSettings settings, ref bool pause, TVRenameStats stats)
        {
            // read NTFS permissions (if any)
            System.Security.AccessControl.FileSecurity security = null;
            try
            {
                security = this.From.GetAccessControl();
            }
            catch
            {
            }

            if (this.QuickOperation())
                this.OSMoveRename(stats); // ask the OS to do it for us, since it's easy and quick!
            else
                this.CopyItOurself(ref pause, stats); // do it ourself!

            // set NTFS permissions
            try
            {
                if (security != null)
                    this.To.SetAccessControl(security);
            }
            catch
            {
            }

            return !this.Error;
        }
Example #4
0
        public bool Go(TVSettings settings, ref bool pause, TVRenameStats stats)
        {
            byte[] theData = this.SI.TVDB.GetPage(this.BannerPath, false, typeMaskBits.tmBanner, false);
            if ((theData == null) || (theData.Length == 0))
            {
                this.ErrorText = "Unable to download " + this.BannerPath;
                this.Error = true;
                this.Done = true;
                return false;
            }

            try
            {
                FileStream fs = new FileStream(this.Destination.FullName, FileMode.Create);
                fs.Write(theData, 0, theData.Length);
                fs.Close();
            }
            catch (Exception e)
            {
                this.ErrorText = e.Message;
                this.Error = true;
                this.Done = true;
                return false;
            }
                

            this.Done = true;
            return true;
        }
Example #5
0
        public DirCacheEntry(FileInfo f, TVSettings theSettings)
        {
            this.TheFile = f;
            this.SimplifiedFullName = Helpers.SimplifyName(f.FullName);
            this.LowerName = f.Name.ToLower();
            this.Length = f.Length;

            if (theSettings == null)
                return;

            this.HasUsefulExtension_NotOthersToo = theSettings.UsefulExtension(f.Extension, false);
            this.HasUsefulExtension_OthersToo = this.HasUsefulExtension_NotOthersToo | theSettings.UsefulExtension(f.Extension, true);
        }
        public AddEditSeasEpFinders(List<FilenameProcessorRE> rex, List<ShowItem> sil, ShowItem initialShow, string initialFolder, TVSettings s)
        {
            this.Rex = rex;
            this.SIL = sil;
            this.TheSettings = s;

            this.InitializeComponent();

            this.SetupGrid();
            this.FillGrid(this.Rex);

            foreach (ShowItem si in this.SIL)
            {
                this.cbShowList.Items.Add(si.ShowName);
                if (si == initialShow)
                    this.cbShowList.SelectedIndex = this.cbShowList.Items.Count - 1;
            }
            this.txtFolder.Text = initialFolder;
        }
Example #7
0
        public bool Go(TVSettings tvsettings, ref bool pause, TVRenameStats stats)
        {
            // "try" and silently fail.  eg. when file is use by other...
            StreamWriter writer;
            try
            {
                // create folder if it does not exist. (Only really applies when .meta\ folder is being used.)
                if (!this.Where.Directory.Exists)
                    this.Where.Directory.Create();
                writer = new StreamWriter(this.Where.FullName);
                if (writer == null)
                    return false;
            }
            catch (Exception)
            {
                this.Done = true;
                return true;
            }

            // See: http://pytivo.sourceforge.net/wiki/index.php/Metadata
            writer.WriteLine(string.Format("title : {0}", this.Episode.SI.ShowName));
            writer.WriteLine(string.Format("seriesTitle : {0}", this.Episode.SI.ShowName));
            writer.WriteLine(string.Format("episodeTitle : {0}", this.Episode.Name));
            writer.WriteLine(string.Format("episodeNumber : {0}{1:0#}", this.Episode.SeasonNumber, this.Episode.EpNum));
            writer.WriteLine("isEpisode : true");
            writer.WriteLine(string.Format("description : {0}", this.Episode.Overview));
            if (this.Episode.FirstAired != null)
                writer.WriteLine(string.Format("originalAirDate : {0:yyyy-MM-dd}T00:00:00Z",this.Episode.FirstAired.Value));
            writer.WriteLine(string.Format("callsign : {0}", this.Episode.SI.TheSeries().GetItem("Network")));

            WriteEntries(writer, "vDirector", this.Episode.EpisodeDirector);
            WriteEntries(writer, "vWriter", this.Episode.Writer);
            WriteEntries(writer, "vActor", this.Episode.SI.TheSeries().GetItem("Actors"));
            WriteEntries(writer, "vGuestStar", this.Episode.EpisodeGuestStars); // not worring about actors being repeated
            WriteEntries(writer, "vProgramGenre", this.Episode.SI.TheSeries().GetItem("Genre"));

            writer.Close();
            this.Done = true;
            return true;
        }
Example #8
0
        public bool LoadXMLSettings(FileInfo from)
        {
            if (from == null)
                return true;

            try
            {
                XmlReaderSettings settings = new XmlReaderSettings
                {
                    IgnoreComments = true,
                    IgnoreWhitespace = true
                };

                if (!from.Exists)
                {
                    //LoadErr = from->Name + " : File does not exist";
                    //return false;
                    return true; // that's ok
                }

                XmlReader reader = XmlReader.Create(from.FullName, settings);

                reader.Read();
                if (reader.Name != "xml")
                {
                    this.LoadErr = from.Name + " : Not a valid XML file";
                    return false;
                }

                reader.Read();

                if (reader.Name != "TVRename")
                {
                    this.LoadErr = from.Name + " : Not a TVRename settings file";
                    return false;
                }

                if (reader.GetAttribute("Version") != "2.1")
                {
                    this.LoadErr = from.Name + " : Incompatible version";
                    return false;
                }

                reader.Read(); // move forward one

                while (!reader.EOF)
                {
                    if (reader.Name == "TVRename" && !reader.IsStartElement())
                        break; // end of it all

                    if (reader.Name == "Settings")
                    {
                        this.Settings = new TVSettings(reader.ReadSubtree());
                        reader.Read();
                    }
                    else if (reader.Name == "MyShows")
                    {
                        XmlReader r2 = reader.ReadSubtree();
                        r2.Read();
                        r2.Read();
                        while (!r2.EOF)
                        {
                            if ((r2.Name == "MyShows") && (!r2.IsStartElement()))
                                break;
                            if (r2.Name == "ShowItem")
                            {
                                ShowItem si = new ShowItem(this.mTVDB, r2.ReadSubtree(), this.Settings);

                                if (si.UseCustomShowName) // see if custom show name is actually the real show name
                                {
                                    SeriesInfo ser = si.TheSeries();
                                    if ((ser != null) && (si.CustomShowName == ser.Name))
                                    {
                                        // then, turn it off
                                        si.CustomShowName = "";
                                        si.UseCustomShowName = false;
                                    }
                                }
                                ShowItems.Add(si);

                                r2.Read();
                            }
                            else
                                r2.ReadOuterXml();
                        }
                        reader.Read();
                    }
                    else if (reader.Name == "MonitorFolders")
                        this.MonitorFolders = ReadStringsFromXml(reader, "MonitorFolders", "Folder");
                    else if (reader.Name == "IgnoreFolders")
                        this.IgnoreFolders = ReadStringsFromXml(reader, "IgnoreFolders", "Folder");
                    else if (reader.Name == "FinderSearchFolders")
                        this.SearchFolders = ReadStringsFromXml(reader, "FinderSearchFolders", "Folder");
                    else if (reader.Name == "IgnoreItems")
                    {
                        XmlReader r2 = reader.ReadSubtree();
                        r2.Read();
                        r2.Read();
                        while (r2.Name == "Ignore")
                            this.Ignore.Add(new IgnoreItem(r2));
                        reader.Read();
                    }
                    else
                        reader.ReadOuterXml();
                }

                reader.Close();
                reader = null;
            }
            catch (Exception e)
            {
                this.LoadErr = from.Name + " : " + e.Message;
                return false;
            }

            try
            {
                mStats = TVRenameStats.Load();
            }
            catch (Exception)
            {
                // not worried if stats loading fails
            }
            return true;
        }
Example #9
0
        public System.Collections.Generic.List<TorrentEntry> AllFilesBeingDownloaded(TVSettings settings, CommandLineArgs args)
        {
            System.Collections.Generic.List<TorrentEntry> r = new System.Collections.Generic.List<TorrentEntry>();

            BEncodeLoader bel = new BEncodeLoader();
            foreach (BTDictionaryItem it in this.ResumeDat.GetDict().Items)
            {
                if ((it.Type != BTChunk.kDictionaryItem))
                    continue;

                BTDictionaryItem dictitem = (BTDictionaryItem) (it);

                if ((dictitem.Key == ".fileguard") || (dictitem.Data.Type != BTChunk.kDictionary))
                    continue;

                string torrentFile = dictitem.Key;
                BTDictionary d2 = (BTDictionary) (dictitem.Data);

                BTItem p = d2.GetItem("prio");
                if ((p == null) || (p.Type != BTChunk.kString))
                    continue;

                BTString prioString = (BTString) (p);
                string directoryName = Path.GetDirectoryName(this.ResumeDatPath) + System.IO.Path.DirectorySeparatorChar;

                if (!File.Exists(torrentFile)) // if the torrent file doesn't exist
                    torrentFile = directoryName + torrentFile; // ..try prepending the resume.dat folder's path to it.

                if (!File.Exists(torrentFile))
                    continue; // can't find it.  give up!

                BTFile tor = bel.Load(torrentFile);
                if (tor == null)
                    continue;

                List<string> a = tor.AllFilesInTorrent();
                if (a != null)
                {
                    int c = 0;

                    p = d2.GetItem("path");
                    if ((p == null) || (p.Type != BTChunk.kString))
                        continue;
                    string defaultFolder = ((BTString) p).AsString();

                    BTItem targets = d2.GetItem("targets");
                    bool hasTargets = ((targets != null) && (targets.Type == BTChunk.kList));
                    BTList targetList = (BTList) (targets);

                    foreach (string s in a)
                    {
                        if ((c < prioString.Data.Length) && (prioString.Data[c] != BTPrio.Skip))
                        {
                            string saveTo = Helpers.FileInFolder(defaultFolder, settings.FilenameFriendly(s)).Name;
                            if (hasTargets)
                            {
                                // see if there is a target for this (the c'th) file
                                for (int i = 0; i < targetList.Items.Count; i++)
                                {
                                    BTList l = (BTList) (targetList.Items[i]);
                                    BTInteger n = (BTInteger) (l.Items[0]);
                                    BTString dest = (BTString) (l.Items[1]);
                                    if (n.Value == c)
                                    {
                                        saveTo = dest.AsString();
                                        break;
                                    }
                                }
                            }
                            int percent = (a.Count == 1) ? PercentBitsOn((BTString) (d2.GetItem("have"))) : -1;
                            TorrentEntry te = new TorrentEntry(torrentFile, saveTo, percent);
                            r.Add(te);
                        }
                        c++;
                    }
                }
            }

            return r;
        }
Example #10
0
        public Dictionary<int, List<string>> AllFolderLocations(TVSettings settings, bool manualToo)
        {
            Dictionary<int, List<string>> fld = new Dictionary<int, List<string>>();

            if (manualToo)
            {
                foreach (KeyValuePair<int, List<string>> kvp in this.ManualFolderLocations)
                {
                    if (!fld.ContainsKey(kvp.Key))
                        fld[kvp.Key] = new List<String>();
                    foreach (string s in kvp.Value)
                        fld[kvp.Key].Add(TTS(s));
                }
            }

            if (this.AutoAddNewSeasons && (!string.IsNullOrEmpty(this.AutoAdd_FolderBase)))
            {
                int highestThereIs = -1;
                foreach (KeyValuePair<int, List<ProcessedEpisode>> kvp in this.SeasonEpisodes)
                {
                    if (kvp.Key > highestThereIs)
                        highestThereIs = kvp.Key;
                }
                foreach (int i in SeasonEpisodes.Keys)
                {
                    if (this.IgnoreSeasons.Contains(i))
                        continue;

                    string newName = this.AutoFolderNameForSeason(i, settings);
                    if ((!string.IsNullOrEmpty(newName)) && (Directory.Exists(newName)))
                    {
                        if (!fld.ContainsKey(i))
                            fld[i] = new List<String>();
                        if (!fld[i].Contains(newName))
                            fld[i].Add(TTS(newName));
                    }
                }
            }

            return fld;
        }
Example #11
0
 public Dictionary<int, List<string>> AllFolderLocations(TVSettings settings)
 {
     return this.AllFolderLocations(settings, true);
 }
Example #12
0
        public string AutoFolderNameForSeason(int n, TVSettings settings)
        {
            bool leadingZero = settings.LeadingZeroOnSeason || this.PadSeasonToTwoDigits;
            string r = this.AutoAdd_FolderBase;
            if (string.IsNullOrEmpty(r))
                return "";

            if (!r.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
                r += System.IO.Path.DirectorySeparatorChar.ToString();
            if (this.AutoAdd_FolderPerSeason)
            {
                if (n == 0)
                    r += settings.SpecialsFolderName;
                else
                {
                    r += this.AutoAdd_SeasonFolderName;
                    if ((n < 10) && leadingZero)
                        r += "0";
                    r += n.ToString();
                }
            }
            return r;
        }
Example #13
0
        public ShowItem(TheTVDB db, XmlReader reader, TVSettings settings)
        {
            this.SetDefaults(db);

            reader.Read();
            if (reader.Name != "ShowItem")
                return; // bail out

            reader.Read();
            while (!reader.EOF)
            {
                if ((reader.Name == "ShowItem") && !reader.IsStartElement())
                    break; // all done

                if (reader.Name == "ShowName")
                {
                    this.CustomShowName = reader.ReadElementContentAsString();
                    this.UseCustomShowName = true;
                }
                if (reader.Name == "UseCustomShowName")
                    this.UseCustomShowName = reader.ReadElementContentAsBoolean();
                if (reader.Name == "CustomShowName")
                    this.CustomShowName = reader.ReadElementContentAsString();
                else if (reader.Name == "TVDBID")
                    this.TVDBCode = reader.ReadElementContentAsInt();
                else if (reader.Name == "CountSpecials")
                    this.CountSpecials = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "ShowNextAirdate")
                    this.ShowNextAirdate = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "AutoAddNewSeasons")
                    this.AutoAddNewSeasons = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "FolderBase")
                    this.AutoAdd_FolderBase = reader.ReadElementContentAsString();
                else if (reader.Name == "FolderPerSeason")
                    this.AutoAdd_FolderPerSeason = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "SeasonFolderName")
                    this.AutoAdd_SeasonFolderName = reader.ReadElementContentAsString();
                else if (reader.Name == "DoRename")
                    this.DoRename = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "DoMissingCheck")
                    this.DoMissingCheck = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "DVDOrder")
                    this.DVDOrder = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "CustomSearchURL")
                    this.CustomSearchURL = reader.ReadElementContentAsString();
                else if (reader.Name == "ForceCheckAll") // removed 2.2.0b2
                    this.ForceCheckNoAirdate = this.ForceCheckFuture = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "ForceCheckFuture")
                    this.ForceCheckFuture = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "ForceCheckNoAirdate")
                    this.ForceCheckNoAirdate = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "PadSeasonToTwoDigits")
                    this.PadSeasonToTwoDigits = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "UseSequentialMatch")
                    this.UseSequentialMatch = reader.ReadElementContentAsBoolean();
                else if (reader.Name == "IgnoreSeasons")
                {
                    if (!reader.IsEmptyElement)
                    {
                        reader.Read();
                        while (reader.Name != "IgnoreSeasons")
                        {
                            if (reader.Name == "Ignore")
                                this.IgnoreSeasons.Add(reader.ReadElementContentAsInt());
                            else
                                reader.ReadOuterXml();
                        }
                    }
                    reader.Read();
                }
                else if (reader.Name == "AliasNames")
                {
                    if (!reader.IsEmptyElement)
                    {
                        reader.Read();
                        while (reader.Name != "AliasNames")
                        {
                            if (reader.Name == "Alias")
                                this.AliasNames.Add(reader.ReadElementContentAsString());
                            else
                                reader.ReadOuterXml();
                        }
                    }
                    reader.Read();
                }
                else if (reader.Name == "Rules")
                {
                    if (!reader.IsEmptyElement)
                    {
                        int snum = int.Parse(reader.GetAttribute("SeasonNumber"));
                        this.SeasonRules[snum] = new List<ShowRule>();
                        reader.Read();
                        while (reader.Name != "Rules")
                        {
                            if (reader.Name == "Rule")
                            {
                                this.SeasonRules[snum].Add(new ShowRule(reader.ReadSubtree()));
                                reader.Read();
                            }
                        }
                    }
                    reader.Read();
                }
                else if (reader.Name == "SeasonFolders")
                {
                    if (!reader.IsEmptyElement)
                    {
                        int snum = int.Parse(reader.GetAttribute("SeasonNumber"));
                        this.ManualFolderLocations[snum] = new List<String>();
                        reader.Read();
                        while (reader.Name != "SeasonFolders")
                        {
                            if ((reader.Name == "Folder") && reader.IsStartElement())
                            {
                                string ff = reader.GetAttribute("Location");
                                if (this.AutoFolderNameForSeason(snum, settings) != ff)
                                    this.ManualFolderLocations[snum].Add(ff);
                            }
                            reader.Read();
                        }
                    }
                    reader.Read();
                }

                else
                    reader.ReadOuterXml();
            } // while
        }
Example #14
0
        public bool Go(TVSettings tvsettings, ref bool pause, TVRenameStats stats)
        {
            XmlWriterSettings settings = new XmlWriterSettings
            {
                Indent = true,
                NewLineOnAttributes = true
            };
            // "try" and silently fail.  eg. when file is use by other...
            XmlWriter writer;
            try
            {
                //                XmlWriter writer = XmlWriter.Create(this.Where.FullName, settings);
                writer = XmlWriter.Create(this.Where.FullName, settings);
                if (writer == null)
                    return false;
            }
            catch (Exception)
            {
                this.Done = true;
                return true;
            }

            if (this.Episode != null) // specific episode
            {
                // See: http://xbmc.org/wiki/?title=Import_-_Export_Library#TV_Episodes
                writer.WriteStartElement("episodedetails");
                writer.WriteStartElement("title");
                writer.WriteValue(this.Episode.Name);
                writer.WriteEndElement();
                writer.WriteStartElement("rating");
                writer.WriteValue(this.Episode.EpisodeRating);
                writer.WriteEndElement();
                writer.WriteStartElement("season");
                writer.WriteValue(this.Episode.SeasonNumber);
                writer.WriteEndElement();
                writer.WriteStartElement("episode");
                writer.WriteValue(this.Episode.EpNum);
                writer.WriteEndElement();
                writer.WriteStartElement("plot");
                writer.WriteValue(this.Episode.Overview);
                writer.WriteEndElement();
                writer.WriteStartElement("aired");
                if (this.Episode.FirstAired != null)
                    writer.WriteValue(this.Episode.FirstAired.Value.ToString("yyyy-MM-dd"));
                writer.WriteEndElement();

                if (this.Episode.SI != null)
                {
                    WriteInfo(writer, this.Episode.SI, "ContentRating", "mpaa");
                }

                //Director(s)
                if (!String.IsNullOrEmpty(this.Episode.EpisodeDirector))
                {
                    string EpDirector = this.Episode.EpisodeDirector;
                    if (!string.IsNullOrEmpty(EpDirector))
                    {
                        foreach (string Daa in EpDirector.Split('|'))
                        {
                            if (string.IsNullOrEmpty(Daa))
                                continue;

                            writer.WriteStartElement("director");
                            writer.WriteValue(Daa);
                            writer.WriteEndElement();
                        }
                    }
                }

                //Writers(s)
                if (!String.IsNullOrEmpty(this.Episode.Writer))
                {
                    string EpWriter = this.Episode.Writer;
                    if (!string.IsNullOrEmpty(EpWriter))
                    {
                        writer.WriteStartElement("credits");
                        writer.WriteValue(EpWriter);
                        writer.WriteEndElement();
                    }
                }

                // Guest Stars...
                if (!String.IsNullOrEmpty(this.Episode.EpisodeGuestStars))
                {
                    string RecurringActors = "";

                    if (this.Episode.SI != null)
                    {
                        RecurringActors = this.Episode.SI.TheSeries().GetItem("Actors");
                    }

                    string GuestActors = this.Episode.EpisodeGuestStars;
                    if (!string.IsNullOrEmpty(GuestActors))
                    {
                        foreach (string Gaa in GuestActors.Split('|'))
                        {
                            if (string.IsNullOrEmpty(Gaa))
                                continue;

                            // Skip if the guest actor is also in the overal recurring list
                            if (!string.IsNullOrEmpty(RecurringActors) && RecurringActors.Contains(Gaa))
                            {
                                continue;
                            }

                            writer.WriteStartElement("actor");
                            writer.WriteStartElement("name");
                            writer.WriteValue(Gaa);
                            writer.WriteEndElement(); // name
                            writer.WriteEndElement(); // actor
                        }
                    }
                }

                // actors...
                if (this.Episode.SI != null)
                {
                    string actors = this.Episode.SI.TheSeries().GetItem("Actors");
                    if (!string.IsNullOrEmpty(actors))
                    {
                        foreach (string aa in actors.Split('|'))
                        {
                            if (string.IsNullOrEmpty(aa))
                                continue;

                            writer.WriteStartElement("actor");
                            writer.WriteStartElement("name");
                            writer.WriteValue(aa);
                            writer.WriteEndElement(); // name
                            writer.WriteEndElement(); // actor
                        }
                    }
                }

                writer.WriteEndElement(); // episodedetails
            }
            else if (this.SI != null) // show overview (tvshow.nfo)
            {
                // http://www.xbmc.org/wiki/?title=Import_-_Export_Library#TV_Shows

                writer.WriteStartElement("tvshow");

                writer.WriteStartElement("title");
                writer.WriteValue(this.SI.ShowName);
                writer.WriteEndElement();

                writer.WriteStartElement("episodeguideurl");
                writer.WriteValue(TheTVDB.BuildURL(true, true, this.SI.TVDBCode, this.SI.TVDB.RequestLanguage));
                writer.WriteEndElement();

                WriteInfo(writer, this.SI, "Overview", "plot");

                string genre = this.SI.TheSeries().GetItem("Genre");
                if (!string.IsNullOrEmpty(genre))
                {
                    genre = genre.Trim('|');
                    genre = genre.Replace("|", " / ");
                    writer.WriteStartElement("genre");
                    writer.WriteValue(genre);
                    writer.WriteEndElement();
                }

                WriteInfo(writer, this.SI, "FirstAired", "premiered");
                WriteInfo(writer, this.SI, "Year", "year");
                WriteInfo(writer, this.SI, "Rating", "rating");
                WriteInfo(writer, this.SI, "Status", "status");

                // actors...
                string actors = this.SI.TheSeries().GetItem("Actors");
                if (!string.IsNullOrEmpty(actors))
                {
                    foreach (string aa in actors.Split('|'))
                    {
                        if (string.IsNullOrEmpty(aa))
                            continue;

                        writer.WriteStartElement("actor");
                        writer.WriteStartElement("name");
                        writer.WriteValue(aa);
                        writer.WriteEndElement(); // name
                        writer.WriteEndElement(); // actor
                    }
                }

                WriteInfo(writer, this.SI, "ContentRating", "mpaa");
                WriteInfo(writer, this.SI, "IMDB_ID", "id", "moviedb","imdb");

                writer.WriteStartElement("tvdbid");
                writer.WriteValue(this.SI.TheSeries().TVDBCode);
                writer.WriteEndElement();

                string rt = this.SI.TheSeries().GetItem("Runtime");
                if (!string.IsNullOrEmpty(rt))
                {
                    writer.WriteStartElement("runtime");
                    writer.WriteValue(rt + " minutes");
                    writer.WriteEndElement();
                }

                writer.WriteEndElement(); // tvshow
            }

            writer.Close();
            this.Done = true;
            return true;
        }