// Thread to scan private void runwork() { // Log in again if (!login()) { SetStatus(statusWindow, "Will try to log on again in 10 seconds"); hourTimer.Change(10000, 1000 * 60 * 60 * 4); scanner.Abort(); } try { // List to save movies to db file List<string> downloadedTrailers = new List<string>(); ObjectToSerialize trailerDBobject = new ObjectToSerialize(); trailerDBobject.DownloadedTrailers = downloadedTrailers; // Scan for trailers SetStatus(statusWindow, "Scanning for new Trailers"); string URL = "http://www.trailerfreaks.com/"; HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(new System.Uri(URL)); HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); Stream resStream = webres.GetResponseStream(); string response = new StreamReader(resStream).ReadToEnd(); // Find trailer string trailerStart = "a href =\"trai"; string toFind; string trailerName; string trailerDescription; string trailerDate; string trailerActors; string trailerNameClean; string trailerDetailsURL; int startindex, endindex; //int numToGet = 10000; //if (!numTrailersToGet.Equals("All")) // numToGet = int.Parse(numTrailersToGet); //int count = 0; //while ((startindex = response.IndexOf(trailerStart)) > -1 && count < numToGet) while ((startindex = response.IndexOf(trailerStart)) > -1) { bool skip = false; if (startindex > -1) { response = response.Substring(startindex); } else { SetStatus(statusWindow, "Error Finding Trailer Page Links"); SetStatus(statusWindow, "Scanning aborted."); enableControls(true); scanner.Abort(); } toFind = "title=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Name"); continue; } endindex = response.IndexOf("\"", startindex); trailerName = response.Substring(startindex, endindex - startindex).Trim(); // Remove Year trailerName = trailerName.Remove(trailerName.LastIndexOf(" ")); trailerNameClean = replaceSpecials(trailerName); trailerNameClean = trailerNameClean.Remove(trailerNameClean.LastIndexOf(" ")); SetStatus(statusWindow, "Found Trailer: " + trailerName); response = response.Substring(endindex); // Check if it exists already in flat file string trailerDB = Application.StartupPath + "\\trailerDB.txt"; if (!File.Exists(trailerDB)) { if (verbose) SetStatus(statusWindow, "New DB Created and will add Trailer after successfull download"); } else { Serializer serializer = new Serializer(); trailerDBobject = serializer.DeSerializeObject(Application.StartupPath + "\\trailerDB.txt"); downloadedTrailers = trailerDBobject.DownloadedTrailers; if (downloadedTrailers.Contains(trailerName + GetText(formatBox))) { SetStatus(statusWindow, "Already Downloaded, Skipping Trailer"); skip = true; } else { if (verbose) SetStatus(statusWindow, "Not in DB will add Trailer after successfull download"); } } if (!skip) { // Get description toFind = "<a href=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Details URL"); continue; } endindex = response.IndexOf("\"", startindex); trailerDetailsURL = "http://www.trailerfreaks.com/" + response.Substring(startindex, endindex - startindex).Trim(); if (verbose) SetStatus(statusWindow, "Found Detailed Page URL: " + trailerDetailsURL); response = response.Substring(endindex); // Open new URL to get description HttpWebRequest webreqDesc = (HttpWebRequest)WebRequest.Create(new System.Uri(trailerDetailsURL)); HttpWebResponse webresDesc = (HttpWebResponse)webreqDesc.GetResponse(); Stream resStreamDesc = webresDesc.GetResponseStream(); string responseDesc = new StreamReader(resStreamDesc).ReadToEnd(); toFind = "class=\"plot\">"; int startindexDesc = responseDesc.IndexOf(toFind); if (startindexDesc > -1) { startindexDesc += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Description"); continue; } int endindexDesc = responseDesc.IndexOf("</td>", startindexDesc); trailerDescription = responseDesc.Substring(startindexDesc, endindexDesc - startindexDesc).Trim(); // Find date toFind = "trailer\" title=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Date"); continue; } endindex = startindex + 10; trailerDate = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) SetStatus(statusWindow, "Found Date: " + trailerDate); response = response.Substring(endindex); // Find Actors toFind = "trailer\" alt=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Actors"); continue; } endindex = response.IndexOf("\"", startindex); trailerActors = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) SetStatus(statusWindow, "Found Actors: " + trailerActors); response = response.Substring(endindex); // Find MOV file toFind = "class=\"trailerlink\">" + GetText(formatBox).ToUpper() + "</a>"; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex -= 250; // Move to starting position of new Trailer file } else { SetStatus(statusWindow, "Error parsing for Trailer File"); continue; } toFind = "<a href=\""; startindex = response.IndexOf(toFind, startindex); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer File"); continue; } endindex = response.IndexOf("\"", startindex); trailerURL = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) SetStatus(statusWindow, "Found URL: " + trailerURL); response = response.Substring(endindex + 250); movFile = GetText(locationBox) + "\\" + trailerNameClean + "." + GetText(formatBox) + ".mov"; string mp4File = GetText(locationBox) + "\\" + trailerNameClean + "." + GetText(formatBox) + ".mp4"; if (verbose) SetStatus(statusWindow, "Downloading Trailer File"); //WebClient Client = new WebClient(); //bool downloadSuccess = true; //try //{ // Client.DownloadFile(trailerURL, movFile); //} //catch (Exception e) //{ // SetStatus(statusWindow, "Error Downloading. Try again next time."); // downloadSuccess = false; //} downloader = new Thread(new ThreadStart(DownloadFile)); downloader.Start(); SetStatus(statusWindow, "\r\nDownloading"); while (downloader.IsAlive) { Thread.Sleep(1000); SetStatusDownloading(statusWindow, "."); if (GetText(scanButton) == "Scan") { SetStatus(statusWindow, "Download canceled"); downloader.Abort(); break; } } downloader.Join(); downloader = null; if (downloadSuccess) { SetStatus(statusWindow, "\r\nDownload Completed"); if (verbose) SetStatus(statusWindow, "Converting to MP4"); // Convert using ffmpeg to mp4 string ffmpegPath = Application.StartupPath + "\\ffmpeg.exe"; string ffmpegParams = " -y -i \"" + movFile + "\" -vcodec copy -acodec copy \"" + mp4File + "\""; if (verbose) { SetStatus(statusWindow, ffmpegPath); SetStatus(statusWindow, ffmpegParams); } Process ffmpeg = new Process(); ffmpeg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; ffmpeg.StartInfo.FileName = ffmpegPath; ffmpeg.StartInfo.Arguments = ffmpegParams; //ffmpeg.StartInfo.FileName = "cmd.exe"; //ffmpeg.StartInfo.Arguments = "/k " + ffmpegPath + " " + ffmpegParams; ffmpeg.Start(); ffmpeg.WaitForExit(); System.IO.File.Delete(@movFile); if (verbose) SetStatus(statusWindow, "Conversion Completed"); // Add to database file downloadedTrailers.Add(trailerName + GetText(formatBox)); Serializer serializer = new Serializer(); serializer.SerializeObject(Application.StartupPath + "\\trailerDB.txt", trailerDBobject); // Wait for 5 seconds Thread.Sleep(5000); // Import metadata // Find file library = new BTVLibrary(); library.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLibrary.asmx"; PVSPropertyBag[] unknownFiles = library.GetItemsBySeries(auth, "Unknown"); foreach (PVSPropertyBag mediafile in unknownFiles) { foreach (PVSProperty pvp1 in mediafile.Properties) { if (pvp1.Name.Equals("FullName")) { string filename = pvp1.Value; if (filename.Equals(mp4File)) { if (verbose) SetStatus(statusWindow, "Found File in BTV Library"); List<PVSProperty> propList = new List<PVSProperty>(); PVSProperty pTitle = new PVSProperty(); pTitle.Name = "Title"; pTitle.Value = "Movie Trailers"; propList.Add(pTitle); PVSProperty pEpisodeTitle = new PVSProperty(); pEpisodeTitle.Name = "EpisodeTitle"; pEpisodeTitle.Value = String.Empty; propList.Add(pEpisodeTitle); PVSProperty pDisplayTitle = new PVSProperty(); pDisplayTitle.Name = "DisplayTitle"; pDisplayTitle.Value = trailerName; propList.Add(pDisplayTitle); if (verbose) SetStatus(statusWindow, "Injected Title: " + pDisplayTitle.Value); PVSProperty pEpisodeDescription = new PVSProperty(); pEpisodeDescription.Name = "EpisodeDescription"; pEpisodeDescription.Value = "[" + GetText(formatBox) + "] " + trailerDescription; propList.Add(pEpisodeDescription); PVSProperty pActors = new PVSProperty(); pActors.Name = "Actors"; pActors.Value = trailerActors; propList.Add(pActors); PVSProperty pDate = new PVSProperty(); pDate.Name = "OriginalAirDate"; pDate.Value = trailerDate.Replace("-", ""); propList.Add(pDate); if (verbose) SetStatus(statusWindow, "Injected Date: " + pDate.Value); PVSPropertyBag bag = new PVSPropertyBag(); bag.Properties = (PVSProperty[])propList.ToArray(); library.EditMedia(auth, @filename, bag); if (verbose) SetStatus(statusWindow, "Metadata Injected"); } } } } } } // Abort if unchecked if (GetText(scanButton) == "Scan") { SetStatus(statusWindow, "Scanning aborted."); enableControls(true); scanner.Abort(); } count++; } } catch (Exception e) { SetStatus(statusWindow, "Major Error: " + e.ToString()); } // Done, for now SetStatus(statusWindow, "Scanning Completed. Waiting 8 hours to scan again. Force restart by clicking Scan button"); }
static void Main(string[] args) { bool simMode = true; bool unattended = false; // Bag of all the media files in the BTV Library PVSPropertyBag[] mediafiles; int mediaCounter = 0; // List to save the Series names and ID List<string> seriesNameList = new List<string>(); List<string> seriesIDList = new List<string>(); // String for holding console line responses String res; // Logon to the BeyondTV server BTVLicenseManager manager = new BTVLicenseManager(); // Get server details Console.Write("Enter BeyondTV Server URL [localhost]: "); string serverURL = Console.ReadLine(); if (serverURL.Equals("")) serverURL = "localhost"; Console.Write("Enter BeyondTV Server port [8129]: "); string port = Console.ReadLine(); if (port.Equals("")) port = "8129"; manager.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLicenseManager.asmx"; Console.Write("Enter BeyondTV Server username []: "); string username = Console.ReadLine(); if (username.Equals("")) username = ""; Console.Write("Enter BeyondTV Server password []: "); string password = getPassword(); if (password.Equals("")) password = ""; Console.WriteLine("Connecting to Beyond TV Server..."); PVSPropertyBag lbag = null; try { lbag = manager.Logon("", username, password); } catch (Exception e) { Console.WriteLine("Cannot log into Beyond TV Server. Exitting..."); return; } string auth = ""; foreach (PVSProperty pvp in lbag.Properties) { if (pvp.Name.Equals("AuthTicket")) { //gets ticket so we can run all the other commands auth = pvp.Value; } } Console.WriteLine("Connected!"); Console.Write("Run in Simulation Mode? [y]/n: "); res = Console.ReadLine(); if (!res.Equals("y") && !res.Equals("Y") && !res.Equals("")) simMode = false; if (!simMode) { Console.Write("Run Unattended (Unless user input required)? y/[n]: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y")) unattended = true; } // Create a BTVTaskListProcessor //BTVTaskListProcessor taskprocessor = new BTVTaskListProcessor(serverURL, Int32.Parse(port)); //Console.WriteLine("pending: " + taskprocessor.GetNumberOfTasksPending(auth)); //Console.WriteLine("process: " + taskprocessor.GetNumberOfTasksInProgress(auth)); // Load Library BTVLibrary library = new BTVLibrary(); library.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLibrary.asmx"; Console.Write("Retrieving Library... "); // Get all filenames in library that were recorded by BTV mediafiles = library.FlatViewByTitle(auth); Console.WriteLine(" Found {0} files.", mediafiles.Length); foreach (PVSPropertyBag mediafile in mediafiles) { // Define variables for the media looping string seriesName = null; string originalAirDate = null; string channel; string seasonNumber = null; string episodeNumber = null; string episodeTitle = null; string filename = null; string newfilename; string URLString; XmlTextReader reader = null; XmlDocument doc = null; int seriesIndex = 0; int episodeIndex = 0; string seriesID = null; string watchedFlag = ""; // Reset the flag to see if the channel data is set bool hasChannel = false; // Reset the flag to see if the channel data is set bool foundMovie = false; // Reset the flag to see if the series exists in memory bool existsInMemory = false; // Reset the flag to see if the user wants to scrape and rename bool rename = false; // Reset the flag to see if a series was found bool foundSeries = false; // Reset the flag to see if an episode was found bool foundEpisode = false; // Reset the flag to see if the episode was multipart bool multipart = false; // Reset watched flag watchedFlag = ""; try { // See if the media has channel info foreach (PVSProperty pvp in mediafile.Properties) { if (pvp.Name.Equals("Channel") && pvp.Value.Length > 0) { hasChannel = true; } if (pvp.Name.Equals("FullName")) { Console.WriteLine("{1}/{2} File: {0}", pvp.Value, ++mediaCounter, mediafiles.Length); filename = pvp.Value; } } // Display and retrieve the data if (hasChannel) { foreach (PVSProperty pvp in mediafile.Properties) { //Console.WriteLine("{0} : {1}", pvp.Name, pvp.Value); if (pvp.Name.Equals("Title") && pvp.Value.Equals("Movies")) { foundMovie = true; Console.WriteLine("Skipping natively recorded movie."); break; } if (pvp.Name.Equals("FullName")) { Console.WriteLine("File: {0}", pvp.Value); filename = pvp.Value; } if (pvp.Name.Equals("SortableName")) { Console.WriteLine("Series Name: {0}", pvp.Value); seriesName = pvp.Value; } if (pvp.Name.Equals("OriginalAirDate")) { originalAirDate = pvp.Value; originalAirDate = originalAirDate.Insert(6, "-").Insert(4, "-"); Console.WriteLine("Original Air Date: {0}", originalAirDate); } if (pvp.Name.Equals("EpisodeTitle")) { Console.WriteLine("Episode Name: {0}", pvp.Value); episodeTitle = pvp.Value; } if (pvp.Name.Equals("Channel")) { Console.WriteLine("Channel: {0}", pvp.Value); channel = pvp.Value; } if (pvp.Name.Equals("Watched")) { Console.WriteLine("Watched: {0}", pvp.Value); if (pvp.Value.Equals("True")) watchedFlag = "True"; else watchedFlag = "False"; } } } else Console.WriteLine("Media not a Beyond TV native recording. Ignoring."); // Ignore a recorded movie if (foundMovie) { //Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); //Console.ReadLine(); Console.WriteLine("---------------------------------------\n"); continue; } // Does the filename already have SxxExx in it? if (hasChannel) { if (Regex.IsMatch(filename, "[Ss]+([0-9]+)+[Ee]+([0-9]+)")) { Console.WriteLine("Show already in proper format!"); //Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); //Console.ReadLine(); Console.WriteLine("---------------------------------------\n"); continue; } } // Ask user if this file should be scraped and renamed since this was deemed a BTV recording if (hasChannel) { if (!unattended) { Console.Write("Try to rename this recording? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) rename = true; } else rename = true; } // Check array first if (hasChannel && rename) { int indexOfShowInArray = seriesNameList.IndexOf(seriesName); if (indexOfShowInArray != -1) { Console.WriteLine("'{0}' exists in memory already", seriesName); seriesID = seriesIDList[indexOfShowInArray]; existsInMemory = true; foundSeries = true; } } // Search TheTVDB.com since I have the permission to rename if (hasChannel && rename && !existsInMemory) { // Search theTVDB.com API for the series ID Console.WriteLine("Searching TheTVDB.com..."); URLString = "http://www.thetvdb.com/api/GetSeries.php?seriesname=" + seriesName + "&language=en"; reader = new XmlTextReader(URLString); doc = new XmlDocument(); try { doc.Load(reader); } catch (Exception e) { Console.WriteLine("Bad URL: {0} for Series '{1}'", URLString, seriesName); Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); continue; } reader.Close(); // Get the series name and the index in the XML if there are multiple XmlNodeList seriesNamesList = doc.GetElementsByTagName("SeriesName"); int seriesCount = seriesNamesList.Count; seriesIndex = 0; // Check if any items were found if (seriesCount == 0) // Found no shows { Console.WriteLine("No Series Found for '{0}'", seriesName); foundSeries = false; if (!unattended) { Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); } } else if (seriesCount == 1) // Found one show { Console.WriteLine("Found: {0}", seriesNamesList.Item(0).InnerText); foundSeries = true; } else // Found multiple shows { Console.WriteLine("Found Multiple Series: {0}", seriesCount); // Show all the series found for (int i = 0; i < seriesNamesList.Count; i++) { Console.WriteLine(" " + (i + 1).ToString() + " :" + seriesNamesList.Item(i).InnerText); } // Ask user to select a show or 0 to skip Console.Write("Select a Series to match '{0}' or enter 0 to skip [1]: ", seriesName); res = Console.ReadLine(); if (res.Equals("")) seriesIndex = 0; else seriesIndex = int.Parse(res) - 1; // Check if > 0 to see if the user picked a series if (seriesIndex > -1) { Console.WriteLine("Using Series '{0}'", seriesNamesList.Item(seriesIndex).InnerText); //seriesName = seriesNamesList.Item(seriesIndex).InnerText; foundSeries = true; } else { Console.WriteLine("Ignoring Series '{0}' ", seriesName); foundSeries = false; } } } // Get series ID from the XML since at this point I have the series index from the search if (hasChannel && rename && foundSeries && !existsInMemory) { XmlNodeList seriesIDXMLList = doc.GetElementsByTagName("seriesid"); seriesID = seriesIDXMLList.Item(seriesIndex).InnerText; Console.WriteLine("Using {0} with TVDB_ID: {1}", seriesName, seriesID); // Store tagged name and series ID in memory seriesNameList.Add(seriesName); seriesIDList.Add(seriesID); } // Get the Series and Episode Numbers now if (hasChannel && rename && foundSeries && seriesID != null) { URLString = "http://www.thetvdb.com/api/8DB53EF83E7E8308/series/" + seriesID + "/all/en.xml"; reader = new XmlTextReader(URLString); doc = new XmlDocument(); try { doc.Load(reader); } catch (Exception e) { Console.WriteLine("Bad URL: {0} for Series '{1}'", URLString, seriesName); Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); continue; } reader.Close(); // Get the episode list XmlNodeList episodeList = doc.GetElementsByTagName("Episode"); int episodeCount = episodeList.Count; Console.WriteLine("Found {0} episode(s)", episodeCount.ToString()); // Go through each episode and find if the original air date exists string[] seasonSearch = new string[10]; string[] episodeSearch = new string[10]; string[] episodeNameSearch = new string[10]; int dateMatches = 0; for (int i = 0; i < episodeCount; i++) { string dateSearch = episodeList.Item(i).SelectSingleNode("FirstAired").InnerText.ToString(); if (dateSearch == originalAirDate) { seasonSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("SeasonNumber").InnerText.ToString(); episodeSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("EpisodeNumber").InnerText.ToString(); episodeNameSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("EpisodeName").InnerText.ToString(); Console.WriteLine("Found episode match to original air date: '{0}' S{1}E{2}", episodeNameSearch[dateMatches], (int.Parse(seasonSearch[dateMatches])).ToString("D2"), (int.Parse(episodeSearch[dateMatches])).ToString("D2")); dateMatches++; } } // Check to see how many matches were found if (dateMatches <= 0) // No Matches Found, so maybe the air date was wrong { Console.WriteLine("No Episodes found for Original Air Date {0}", originalAirDate); Console.Write("Manually choose episode from list? [y]/n: "); res = Console.ReadLine(); bool chooseEpisode; if (res.Equals("") || res.Equals("y") || res.Equals("Y")) chooseEpisode = true; else chooseEpisode = false; // Show all the episodes found if (chooseEpisode) { seasonSearch = new string[episodeCount]; episodeSearch = new string[episodeCount]; episodeNameSearch = new string[episodeCount]; for (int i = 0; i < episodeCount; i++) { seasonSearch[i] = episodeList.Item(i).SelectSingleNode("SeasonNumber").InnerText.ToString(); episodeSearch[i] = episodeList.Item(i).SelectSingleNode("EpisodeNumber").InnerText.ToString(); episodeNameSearch[i] = episodeList.Item(i).SelectSingleNode("EpisodeName").InnerText.ToString(); Console.WriteLine(" " + (i + 1).ToString() + " : '{0}' S{1}E{2}", episodeNameSearch[i], (int.Parse(seasonSearch[i])).ToString("D2"), (int.Parse(episodeSearch[i])).ToString("D2")); } // Ask user to select a show or 0 to skip Console.Write("Select an Episode to use or enter 0 to skip [0]: "); res = Console.ReadLine(); if (res.Equals("")) episodeIndex = -1; else episodeIndex = int.Parse(res) - 1; // Check if > 0 to see if the user picked a series if (episodeIndex > -1) { Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndex], (int.Parse(seasonSearch[episodeIndex])).ToString("D2"), (int.Parse(episodeSearch[episodeIndex])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndex])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[episodeIndex])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndex]; foundEpisode = true; } else { Console.WriteLine("Ignoring Episode Search"); foundEpisode = false; } } else foundEpisode = false; } else if (dateMatches == 1) // Found one match { seasonNumber = (int.Parse(seasonSearch[0])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[0])).ToString("D2"); foundEpisode = true; } else // Found multiple matches { Console.WriteLine("Found Multiple Episodes: {0}", dateMatches); // Show all the episodes found for (int i = 0; i < dateMatches; i++) { Console.WriteLine(" " + (i + 1).ToString() + " : '{0}' S{1}E{2}", episodeNameSearch[i], (int.Parse(seasonSearch[i])).ToString("D2"), (int.Parse(episodeSearch[i])).ToString("D2")); } // Ask user to select a show or 0 to skip Console.Write("Select an Episode to use, 'cXX..X' to combine multipart (ie: c124) or enter 0 to skip [1]: "); res = Console.ReadLine(); if (res.Equals("")) episodeIndex = 0; else { // Check if selected single episode or multipart if (res.Length == 1) episodeIndex = int.Parse(res) - 1; else { // Set a flag for multiple episodes multipart = true; // Check if c, if not set episodeIndex to -1 if (res[0].Equals('c')) { // Parse out the selections char[] episodes = res.Substring(1).ToCharArray(); for (int i = 0; i < episodes.Length; i++) { // Parse out the index int episodeIndexNumber = int.Parse(episodes[i].ToString()) - 1; // Look up the episode numbers if (i == 0) episodeNumber = (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2"); else episodeNumber = episodeNumber + "-" + (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2"); // Show what has been used Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndexNumber], (int.Parse(seasonSearch[episodeIndexNumber])).ToString("D2"), (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndexNumber])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndexNumber]; } } else episodeIndex = -1; } } // Check if > 0 to see if the user picked a series if (episodeIndex > -1 && !multipart) { Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndex], (int.Parse(seasonSearch[episodeIndex])).ToString("D2"), (int.Parse(episodeSearch[episodeIndex])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndex])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[episodeIndex])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndex]; foundEpisode = true; } else if (multipart) foundEpisode = true; else { Console.WriteLine("Ignoring Episode Search"); foundEpisode = false; } } } // Move file to new filename format and delete original file if user wants since I have everything now if (hasChannel && rename && foundSeries && seriesID != null && foundEpisode) { string extension = filename.Substring(filename.LastIndexOf(".")); string filenameNoExt = filename.Remove(filename.LastIndexOf(".")); string path = filename.Remove(filename.LastIndexOf("\\") + 1); seriesName = Renamer.replaceSpecialChars(seriesName); episodeTitle = Renamer.replaceSpecialChars(episodeTitle); string newfilenameNoExt = path + seriesName + ".S" + seasonNumber + "E" + episodeNumber + "." + episodeTitle; newfilename = newfilenameNoExt + extension; if (!File.Exists(newfilename)) { if (simMode) Console.WriteLine("SIMULATING Creating {0}.", newfilename); else { // Add SxxExx to Episode Description if it doesn't exist foreach (PVSProperty pvp in mediafile.Properties) { if (pvp.Name.Equals("EpisodeDescription")) { string episodeDescription = pvp.Value; if (!(Regex.IsMatch(episodeDescription, "[Ss]+([0-9]+)+[Ee]+([0-9]+)"))) { episodeDescription = "S" + seasonNumber + "E" + episodeNumber + " - " + episodeDescription; pvp.Value = episodeDescription; } library.EditMedia(auth, @filename, mediafile); break; } } // Copy all files with this filename // Copy main video file //System.IO.File.Copy(@filename, @newfilename); while (IsFileLocked(new FileInfo(@filename))); System.IO.File.Move(@filename, @newfilename); // Copy chapters xml file string tempsource = filename + ".chapters.xml"; string tempdest = newfilename + ".chapters.xml"; if (File.Exists(tempsource)) //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); // Copy edl file tempsource = filenameNoExt + ".edl"; tempdest = newfilenameNoExt + ".edl"; if (File.Exists(tempsource)) //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); // Copy txt file tempsource = filenameNoExt + ".txt"; tempdest = newfilenameNoExt + ".txt"; if (File.Exists(tempsource)) //System.IO.File.Copy(@tempsource, @tempdest); System.IO.File.Move(@tempsource, @tempdest); // Copy log file tempsource = filenameNoExt + ".log"; tempdest = newfilenameNoExt + ".log"; if (File.Exists(tempsource)) //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); // Wait for library to be uploaded if changing the watched flag if (watchedFlag.Equals("True")) { // Check if new file is in library PVSPropertyBag newfile = null; Console.WriteLine("Waiting for Library to update"); while (newfile == null) { try { newfile = library.GetMediaByFullName(auth, @newfilename); Thread.Sleep(500); } catch (Exception e) { Console.Write("."); }; } Console.WriteLine(""); // Maintain the Watched flag library.SetUserSpecificProperty(auth, @newfilename, "Watched", watchedFlag); library.EditMedia(auth, @newfilename, mediafile); } } } else { Console.WriteLine("File {0} Exists. Ignoring changes.", newfilename); /* if (simMode) Console.WriteLine("SIMULATING Deleting {0} if the user requested.", filename); else { // Ask user to delete the original Console.Write("Delete the original file? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { // Delete Main Video File FileInfo file = new FileInfo(filename); if (file.IsReadOnly) { Console.Write("File is Read Only, override and delete? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { file.IsReadOnly = false; System.IO.File.Delete(@filename); } } else System.IO.File.Delete(@filename); // Delete Chapters XML file string tempsource = filename + ".chapters.xml"; if (File.Exists(tempsource)) { file = new FileInfo(tempsource); if (file.IsReadOnly) { Console.Write("File is Read Only, override and delete? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { file.IsReadOnly = false; System.IO.File.Delete(@tempsource); } } else System.IO.File.Delete(@tempsource); } // Delete EDL file tempsource = filenameNoExt + ".edl"; if (File.Exists(tempsource)) { file = new FileInfo(tempsource); if (file.IsReadOnly) { Console.Write("File is Read Only, override and delete? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { file.IsReadOnly = false; System.IO.File.Delete(@tempsource); } } else System.IO.File.Delete(@tempsource); } // Delete TXT file tempsource = filenameNoExt + ".txt"; if (File.Exists(tempsource)) { file = new FileInfo(tempsource); if (file.IsReadOnly) { Console.Write("File is Read Only, override and delete? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { file.IsReadOnly = false; System.IO.File.Delete(@tempsource); } } else System.IO.File.Delete(@tempsource); } // Delete LOG file tempsource = filenameNoExt + ".log"; if (File.Exists(tempsource)) { file = new FileInfo(tempsource); if (file.IsReadOnly) { Console.Write("File is Read Only, override and delete? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { file.IsReadOnly = false; System.IO.File.Delete(@tempsource); } } else System.IO.File.Delete(@tempsource); } } } */ } if (!unattended) { Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); } } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } Console.WriteLine("---------------------------------------\n"); } //Logoff the BeyondTV server Console.WriteLine("Finished...logging off"); manager.Logoff(auth); Console.ReadLine(); }
// Thread to scan private void runwork() { // Log in again if (!login()) { SetStatus(statusWindow, "Will try to log on again in 10 seconds"); hourTimer.Change(10000, 1000 * 60 * 60 * 4); scanner.Abort(); } try { // List to save movies to db file List <string> downloadedTrailers = new List <string>(); ObjectToSerialize trailerDBobject = new ObjectToSerialize(); trailerDBobject.DownloadedTrailers = downloadedTrailers; // Scan for trailers SetStatus(statusWindow, "Scanning for new Trailers"); string URL = "http://www.trailerfreaks.com/"; HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(new System.Uri(URL)); HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); Stream resStream = webres.GetResponseStream(); string response = new StreamReader(resStream).ReadToEnd(); // Find trailer string trailerStart = "a href =\"trai"; string toFind; string trailerName; string trailerDescription; string trailerDate; string trailerActors; string trailerNameClean; string trailerDetailsURL; int startindex, endindex; //int numToGet = 10000; //if (!numTrailersToGet.Equals("All")) // numToGet = int.Parse(numTrailersToGet); //int count = 0; //while ((startindex = response.IndexOf(trailerStart)) > -1 && count < numToGet) while ((startindex = response.IndexOf(trailerStart)) > -1) { bool skip = false; if (startindex > -1) { response = response.Substring(startindex); } else { SetStatus(statusWindow, "Error Finding Trailer Page Links"); SetStatus(statusWindow, "Scanning aborted."); enableControls(true); scanner.Abort(); } toFind = "title=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Name"); continue; } endindex = response.IndexOf("\"", startindex); trailerName = response.Substring(startindex, endindex - startindex).Trim(); // Remove Year trailerName = trailerName.Remove(trailerName.LastIndexOf(" ")); trailerNameClean = replaceSpecials(trailerName); trailerNameClean = trailerNameClean.Remove(trailerNameClean.LastIndexOf(" ")); SetStatus(statusWindow, "Found Trailer: " + trailerName); response = response.Substring(endindex); // Check if it exists already in flat file string trailerDB = Application.StartupPath + "\\trailerDB.txt"; if (!File.Exists(trailerDB)) { if (verbose) { SetStatus(statusWindow, "New DB Created and will add Trailer after successfull download"); } } else { Serializer serializer = new Serializer(); trailerDBobject = serializer.DeSerializeObject(Application.StartupPath + "\\trailerDB.txt"); downloadedTrailers = trailerDBobject.DownloadedTrailers; if (downloadedTrailers.Contains(trailerName + GetText(formatBox))) { SetStatus(statusWindow, "Already Downloaded, Skipping Trailer"); skip = true; } else { if (verbose) { SetStatus(statusWindow, "Not in DB will add Trailer after successfull download"); } } } if (!skip) { // Get description toFind = "<a href=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Details URL"); continue; } endindex = response.IndexOf("\"", startindex); trailerDetailsURL = "http://www.trailerfreaks.com/" + response.Substring(startindex, endindex - startindex).Trim(); if (verbose) { SetStatus(statusWindow, "Found Detailed Page URL: " + trailerDetailsURL); } response = response.Substring(endindex); // Open new URL to get description HttpWebRequest webreqDesc = (HttpWebRequest)WebRequest.Create(new System.Uri(trailerDetailsURL)); HttpWebResponse webresDesc = (HttpWebResponse)webreqDesc.GetResponse(); Stream resStreamDesc = webresDesc.GetResponseStream(); string responseDesc = new StreamReader(resStreamDesc).ReadToEnd(); toFind = "class=\"plot\">"; int startindexDesc = responseDesc.IndexOf(toFind); if (startindexDesc > -1) { startindexDesc += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Description"); continue; } int endindexDesc = responseDesc.IndexOf("</td>", startindexDesc); trailerDescription = responseDesc.Substring(startindexDesc, endindexDesc - startindexDesc).Trim(); // Find date toFind = "trailer\" title=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Date"); continue; } endindex = startindex + 10; trailerDate = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) { SetStatus(statusWindow, "Found Date: " + trailerDate); } response = response.Substring(endindex); // Find Actors toFind = "trailer\" alt=\""; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer Actors"); continue; } endindex = response.IndexOf("\"", startindex); trailerActors = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) { SetStatus(statusWindow, "Found Actors: " + trailerActors); } response = response.Substring(endindex); // Find MOV file toFind = "class=\"trailerlink\">" + GetText(formatBox).ToUpper() + "</a>"; startindex = response.IndexOf(toFind); if (startindex > -1) { startindex -= 250; // Move to starting position of new Trailer file } else { SetStatus(statusWindow, "Error parsing for Trailer File"); continue; } toFind = "<a href=\""; startindex = response.IndexOf(toFind, startindex); if (startindex > -1) { startindex += toFind.Length; // Move to starting position of new Trailer } else { SetStatus(statusWindow, "Error parsing for Trailer File"); continue; } endindex = response.IndexOf("\"", startindex); trailerURL = response.Substring(startindex, endindex - startindex).Trim(); if (verbose) { SetStatus(statusWindow, "Found URL: " + trailerURL); } response = response.Substring(endindex + 250); movFile = GetText(locationBox) + "\\" + trailerNameClean + "." + GetText(formatBox) + ".mov"; string mp4File = GetText(locationBox) + "\\" + trailerNameClean + "." + GetText(formatBox) + ".mp4"; if (verbose) { SetStatus(statusWindow, "Downloading Trailer File"); } //WebClient Client = new WebClient(); //bool downloadSuccess = true; //try //{ // Client.DownloadFile(trailerURL, movFile); //} //catch (Exception e) //{ // SetStatus(statusWindow, "Error Downloading. Try again next time."); // downloadSuccess = false; //} downloader = new Thread(new ThreadStart(DownloadFile)); downloader.Start(); SetStatus(statusWindow, "\r\nDownloading"); while (downloader.IsAlive) { Thread.Sleep(1000); SetStatusDownloading(statusWindow, "."); if (GetText(scanButton) == "Scan") { SetStatus(statusWindow, "Download canceled"); downloader.Abort(); break; } } downloader.Join(); downloader = null; if (downloadSuccess) { SetStatus(statusWindow, "\r\nDownload Completed"); if (verbose) { SetStatus(statusWindow, "Converting to MP4"); } // Convert using ffmpeg to mp4 string ffmpegPath = Application.StartupPath + "\\ffmpeg.exe"; string ffmpegParams = " -y -i \"" + movFile + "\" -vcodec copy -acodec copy \"" + mp4File + "\""; if (verbose) { SetStatus(statusWindow, ffmpegPath); SetStatus(statusWindow, ffmpegParams); } Process ffmpeg = new Process(); ffmpeg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; ffmpeg.StartInfo.FileName = ffmpegPath; ffmpeg.StartInfo.Arguments = ffmpegParams; //ffmpeg.StartInfo.FileName = "cmd.exe"; //ffmpeg.StartInfo.Arguments = "/k " + ffmpegPath + " " + ffmpegParams; ffmpeg.Start(); ffmpeg.WaitForExit(); System.IO.File.Delete(@movFile); if (verbose) { SetStatus(statusWindow, "Conversion Completed"); } // Add to database file downloadedTrailers.Add(trailerName + GetText(formatBox)); Serializer serializer = new Serializer(); serializer.SerializeObject(Application.StartupPath + "\\trailerDB.txt", trailerDBobject); // Wait for 5 seconds Thread.Sleep(5000); // Import metadata // Find file library = new BTVLibrary(); library.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLibrary.asmx"; PVSPropertyBag[] unknownFiles = library.GetItemsBySeries(auth, "Unknown"); foreach (PVSPropertyBag mediafile in unknownFiles) { foreach (PVSProperty pvp1 in mediafile.Properties) { if (pvp1.Name.Equals("FullName")) { string filename = pvp1.Value; if (filename.Equals(mp4File)) { if (verbose) { SetStatus(statusWindow, "Found File in BTV Library"); } List <PVSProperty> propList = new List <PVSProperty>(); PVSProperty pTitle = new PVSProperty(); pTitle.Name = "Title"; pTitle.Value = "Movie Trailers"; propList.Add(pTitle); PVSProperty pEpisodeTitle = new PVSProperty(); pEpisodeTitle.Name = "EpisodeTitle"; pEpisodeTitle.Value = String.Empty; propList.Add(pEpisodeTitle); PVSProperty pDisplayTitle = new PVSProperty(); pDisplayTitle.Name = "DisplayTitle"; pDisplayTitle.Value = trailerName; propList.Add(pDisplayTitle); if (verbose) { SetStatus(statusWindow, "Injected Title: " + pDisplayTitle.Value); } PVSProperty pEpisodeDescription = new PVSProperty(); pEpisodeDescription.Name = "EpisodeDescription"; pEpisodeDescription.Value = "[" + GetText(formatBox) + "] " + trailerDescription; propList.Add(pEpisodeDescription); PVSProperty pActors = new PVSProperty(); pActors.Name = "Actors"; pActors.Value = trailerActors; propList.Add(pActors); PVSProperty pDate = new PVSProperty(); pDate.Name = "OriginalAirDate"; pDate.Value = trailerDate.Replace("-", ""); propList.Add(pDate); if (verbose) { SetStatus(statusWindow, "Injected Date: " + pDate.Value); } PVSPropertyBag bag = new PVSPropertyBag(); bag.Properties = (PVSProperty[])propList.ToArray(); library.EditMedia(auth, @filename, bag); if (verbose) { SetStatus(statusWindow, "Metadata Injected"); } } } } } } } // Abort if unchecked if (GetText(scanButton) == "Scan") { SetStatus(statusWindow, "Scanning aborted."); enableControls(true); scanner.Abort(); } count++; } } catch (Exception e) { SetStatus(statusWindow, "Major Error: " + e.ToString()); } // Done, for now SetStatus(statusWindow, "Scanning Completed. Waiting 8 hours to scan again. Force restart by clicking Scan button"); }
static void Main(string[] args) { bool simMode = true; bool unattended = false; // Bag of all the media files in the BTV Library PVSPropertyBag[] mediafiles; int mediaCounter = 0; // List to save the Series names and ID List <string> seriesNameList = new List <string>(); List <string> seriesIDList = new List <string>(); // String for holding console line responses String res; // Logon to the BeyondTV server BTVLicenseManager manager = new BTVLicenseManager(); // Get server details Console.Write("Enter BeyondTV Server URL [localhost]: "); string serverURL = Console.ReadLine(); if (serverURL.Equals("")) { serverURL = "localhost"; } Console.Write("Enter BeyondTV Server port [8129]: "); string port = Console.ReadLine(); if (port.Equals("")) { port = "8129"; } manager.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLicenseManager.asmx"; Console.Write("Enter BeyondTV Server username []: "); string username = Console.ReadLine(); if (username.Equals("")) { username = ""; } Console.Write("Enter BeyondTV Server password []: "); string password = getPassword(); if (password.Equals("")) { password = ""; } Console.WriteLine("Connecting to Beyond TV Server..."); PVSPropertyBag lbag = null; try { lbag = manager.Logon("", username, password); } catch (Exception e) { Console.WriteLine("Cannot log into Beyond TV Server. Exitting..."); return; } string auth = ""; foreach (PVSProperty pvp in lbag.Properties) { if (pvp.Name.Equals("AuthTicket")) { //gets ticket so we can run all the other commands auth = pvp.Value; } } Console.WriteLine("Connected!"); Console.Write("Run in Simulation Mode? [y]/n: "); res = Console.ReadLine(); if (!res.Equals("y") && !res.Equals("Y") && !res.Equals("")) { simMode = false; } if (!simMode) { Console.Write("Run Unattended (Unless user input required)? y/[n]: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y")) { unattended = true; } } // Create a BTVTaskListProcessor //BTVTaskListProcessor taskprocessor = new BTVTaskListProcessor(serverURL, Int32.Parse(port)); //Console.WriteLine("pending: " + taskprocessor.GetNumberOfTasksPending(auth)); //Console.WriteLine("process: " + taskprocessor.GetNumberOfTasksInProgress(auth)); // Load Library BTVLibrary library = new BTVLibrary(); library.Url = "http://" + serverURL + ":" + port + "/wsdl/BTVLibrary.asmx"; Console.Write("Retrieving Library... "); // Get all filenames in library that were recorded by BTV mediafiles = library.FlatViewByTitle(auth); Console.WriteLine(" Found {0} files.", mediafiles.Length); foreach (PVSPropertyBag mediafile in mediafiles) { // Define variables for the media looping string seriesName = null; string originalAirDate = null; string channel; string seasonNumber = null; string episodeNumber = null; string episodeTitle = null; string filename = null; string newfilename; string URLString; XmlTextReader reader = null; XmlDocument doc = null; int seriesIndex = 0; int episodeIndex = 0; string seriesID = null; string watchedFlag = ""; // Reset the flag to see if the channel data is set bool hasChannel = false; // Reset the flag to see if the channel data is set bool foundMovie = false; // Reset the flag to see if the series exists in memory bool existsInMemory = false; // Reset the flag to see if the user wants to scrape and rename bool rename = false; // Reset the flag to see if a series was found bool foundSeries = false; // Reset the flag to see if an episode was found bool foundEpisode = false; // Reset the flag to see if the episode was multipart bool multipart = false; // Reset watched flag watchedFlag = ""; try { // See if the media has channel info foreach (PVSProperty pvp in mediafile.Properties) { if (pvp.Name.Equals("Channel") && pvp.Value.Length > 0) { hasChannel = true; } if (pvp.Name.Equals("FullName")) { Console.WriteLine("{1}/{2} File: {0}", pvp.Value, ++mediaCounter, mediafiles.Length); filename = pvp.Value; } } // Display and retrieve the data if (hasChannel) { foreach (PVSProperty pvp in mediafile.Properties) { //Console.WriteLine("{0} : {1}", pvp.Name, pvp.Value); if (pvp.Name.Equals("Title") && pvp.Value.Equals("Movies")) { foundMovie = true; Console.WriteLine("Skipping natively recorded movie."); break; } if (pvp.Name.Equals("FullName")) { Console.WriteLine("File: {0}", pvp.Value); filename = pvp.Value; } if (pvp.Name.Equals("SortableName")) { Console.WriteLine("Series Name: {0}", pvp.Value); seriesName = pvp.Value; } if (pvp.Name.Equals("OriginalAirDate")) { originalAirDate = pvp.Value; originalAirDate = originalAirDate.Insert(6, "-").Insert(4, "-"); Console.WriteLine("Original Air Date: {0}", originalAirDate); } if (pvp.Name.Equals("EpisodeTitle")) { Console.WriteLine("Episode Name: {0}", pvp.Value); episodeTitle = pvp.Value; } if (pvp.Name.Equals("Channel")) { Console.WriteLine("Channel: {0}", pvp.Value); channel = pvp.Value; } if (pvp.Name.Equals("Watched")) { Console.WriteLine("Watched: {0}", pvp.Value); if (pvp.Value.Equals("True")) { watchedFlag = "True"; } else { watchedFlag = "False"; } } } } else { Console.WriteLine("Media not a Beyond TV native recording. Ignoring."); } // Ignore a recorded movie if (foundMovie) { //Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); //Console.ReadLine(); Console.WriteLine("---------------------------------------\n"); continue; } // Does the filename already have SxxExx in it? if (hasChannel) { if (Regex.IsMatch(filename, "[Ss]+([0-9]+)+[Ee]+([0-9]+)")) { Console.WriteLine("Show already in proper format!"); //Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); //Console.ReadLine(); Console.WriteLine("---------------------------------------\n"); continue; } } // Ask user if this file should be scraped and renamed since this was deemed a BTV recording if (hasChannel) { if (!unattended) { Console.Write("Try to rename this recording? [y]/n: "); res = Console.ReadLine(); if (res.Equals("y") || res.Equals("Y") || res.Equals("")) { rename = true; } } else { rename = true; } } // Check array first if (hasChannel && rename) { int indexOfShowInArray = seriesNameList.IndexOf(seriesName); if (indexOfShowInArray != -1) { Console.WriteLine("'{0}' exists in memory already", seriesName); seriesID = seriesIDList[indexOfShowInArray]; existsInMemory = true; foundSeries = true; } } // Search TheTVDB.com since I have the permission to rename if (hasChannel && rename && !existsInMemory) { // Search theTVDB.com API for the series ID Console.WriteLine("Searching TheTVDB.com..."); URLString = "http://www.thetvdb.com/api/GetSeries.php?seriesname=" + seriesName + "&language=en"; reader = new XmlTextReader(URLString); doc = new XmlDocument(); try { doc.Load(reader); } catch (Exception e) { Console.WriteLine("Bad URL: {0} for Series '{1}'", URLString, seriesName); Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); continue; } reader.Close(); // Get the series name and the index in the XML if there are multiple XmlNodeList seriesNamesList = doc.GetElementsByTagName("SeriesName"); int seriesCount = seriesNamesList.Count; seriesIndex = 0; // Check if any items were found if (seriesCount == 0) // Found no shows { Console.WriteLine("No Series Found for '{0}'", seriesName); foundSeries = false; if (!unattended) { Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); } } else if (seriesCount == 1) // Found one show { Console.WriteLine("Found: {0}", seriesNamesList.Item(0).InnerText); foundSeries = true; } else // Found multiple shows { Console.WriteLine("Found Multiple Series: {0}", seriesCount); // Show all the series found for (int i = 0; i < seriesNamesList.Count; i++) { Console.WriteLine(" " + (i + 1).ToString() + " :" + seriesNamesList.Item(i).InnerText); } // Ask user to select a show or 0 to skip Console.Write("Select a Series to match '{0}' or enter 0 to skip [1]: ", seriesName); res = Console.ReadLine(); if (res.Equals("")) { seriesIndex = 0; } else { seriesIndex = int.Parse(res) - 1; } // Check if > 0 to see if the user picked a series if (seriesIndex > -1) { Console.WriteLine("Using Series '{0}'", seriesNamesList.Item(seriesIndex).InnerText); //seriesName = seriesNamesList.Item(seriesIndex).InnerText; foundSeries = true; } else { Console.WriteLine("Ignoring Series '{0}' ", seriesName); foundSeries = false; } } } // Get series ID from the XML since at this point I have the series index from the search if (hasChannel && rename && foundSeries && !existsInMemory) { XmlNodeList seriesIDXMLList = doc.GetElementsByTagName("seriesid"); seriesID = seriesIDXMLList.Item(seriesIndex).InnerText; Console.WriteLine("Using {0} with TVDB_ID: {1}", seriesName, seriesID); // Store tagged name and series ID in memory seriesNameList.Add(seriesName); seriesIDList.Add(seriesID); } // Get the Series and Episode Numbers now if (hasChannel && rename && foundSeries && seriesID != null) { URLString = "http://www.thetvdb.com/api/8DB53EF83E7E8308/series/" + seriesID + "/all/en.xml"; reader = new XmlTextReader(URLString); doc = new XmlDocument(); try { doc.Load(reader); } catch (Exception e) { Console.WriteLine("Bad URL: {0} for Series '{1}'", URLString, seriesName); Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); continue; } reader.Close(); // Get the episode list XmlNodeList episodeList = doc.GetElementsByTagName("Episode"); int episodeCount = episodeList.Count; Console.WriteLine("Found {0} episode(s)", episodeCount.ToString()); // Go through each episode and find if the original air date exists string[] seasonSearch = new string[10]; string[] episodeSearch = new string[10]; string[] episodeNameSearch = new string[10]; int dateMatches = 0; for (int i = 0; i < episodeCount; i++) { string dateSearch = episodeList.Item(i).SelectSingleNode("FirstAired").InnerText.ToString(); if (dateSearch == originalAirDate) { seasonSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("SeasonNumber").InnerText.ToString(); episodeSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("EpisodeNumber").InnerText.ToString(); episodeNameSearch[dateMatches] = episodeList.Item(i).SelectSingleNode("EpisodeName").InnerText.ToString(); Console.WriteLine("Found episode match to original air date: '{0}' S{1}E{2}", episodeNameSearch[dateMatches], (int.Parse(seasonSearch[dateMatches])).ToString("D2"), (int.Parse(episodeSearch[dateMatches])).ToString("D2")); dateMatches++; } } // Check to see how many matches were found if (dateMatches <= 0) // No Matches Found, so maybe the air date was wrong { Console.WriteLine("No Episodes found for Original Air Date {0}", originalAirDate); Console.Write("Manually choose episode from list? [y]/n: "); res = Console.ReadLine(); bool chooseEpisode; if (res.Equals("") || res.Equals("y") || res.Equals("Y")) { chooseEpisode = true; } else { chooseEpisode = false; } // Show all the episodes found if (chooseEpisode) { seasonSearch = new string[episodeCount]; episodeSearch = new string[episodeCount]; episodeNameSearch = new string[episodeCount]; for (int i = 0; i < episodeCount; i++) { seasonSearch[i] = episodeList.Item(i).SelectSingleNode("SeasonNumber").InnerText.ToString(); episodeSearch[i] = episodeList.Item(i).SelectSingleNode("EpisodeNumber").InnerText.ToString(); episodeNameSearch[i] = episodeList.Item(i).SelectSingleNode("EpisodeName").InnerText.ToString(); Console.WriteLine(" " + (i + 1).ToString() + " : '{0}' S{1}E{2}", episodeNameSearch[i], (int.Parse(seasonSearch[i])).ToString("D2"), (int.Parse(episodeSearch[i])).ToString("D2")); } // Ask user to select a show or 0 to skip Console.Write("Select an Episode to use or enter 0 to skip [0]: "); res = Console.ReadLine(); if (res.Equals("")) { episodeIndex = -1; } else { episodeIndex = int.Parse(res) - 1; } // Check if > 0 to see if the user picked a series if (episodeIndex > -1) { Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndex], (int.Parse(seasonSearch[episodeIndex])).ToString("D2"), (int.Parse(episodeSearch[episodeIndex])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndex])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[episodeIndex])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndex]; foundEpisode = true; } else { Console.WriteLine("Ignoring Episode Search"); foundEpisode = false; } } else { foundEpisode = false; } } else if (dateMatches == 1) // Found one match { seasonNumber = (int.Parse(seasonSearch[0])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[0])).ToString("D2"); foundEpisode = true; } else // Found multiple matches { Console.WriteLine("Found Multiple Episodes: {0}", dateMatches); // Show all the episodes found for (int i = 0; i < dateMatches; i++) { Console.WriteLine(" " + (i + 1).ToString() + " : '{0}' S{1}E{2}", episodeNameSearch[i], (int.Parse(seasonSearch[i])).ToString("D2"), (int.Parse(episodeSearch[i])).ToString("D2")); } // Ask user to select a show or 0 to skip Console.Write("Select an Episode to use, 'cXX..X' to combine multipart (ie: c124) or enter 0 to skip [1]: "); res = Console.ReadLine(); if (res.Equals("")) { episodeIndex = 0; } else { // Check if selected single episode or multipart if (res.Length == 1) { episodeIndex = int.Parse(res) - 1; } else { // Set a flag for multiple episodes multipart = true; // Check if c, if not set episodeIndex to -1 if (res[0].Equals('c')) { // Parse out the selections char[] episodes = res.Substring(1).ToCharArray(); for (int i = 0; i < episodes.Length; i++) { // Parse out the index int episodeIndexNumber = int.Parse(episodes[i].ToString()) - 1; // Look up the episode numbers if (i == 0) { episodeNumber = (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2"); } else { episodeNumber = episodeNumber + "-" + (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2"); } // Show what has been used Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndexNumber], (int.Parse(seasonSearch[episodeIndexNumber])).ToString("D2"), (int.Parse(episodeSearch[episodeIndexNumber])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndexNumber])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndexNumber]; } } else { episodeIndex = -1; } } } // Check if > 0 to see if the user picked a series if (episodeIndex > -1 && !multipart) { Console.WriteLine("Using '{0}' S{1}E{2}'", episodeNameSearch[episodeIndex], (int.Parse(seasonSearch[episodeIndex])).ToString("D2"), (int.Parse(episodeSearch[episodeIndex])).ToString("D2")); seasonNumber = (int.Parse(seasonSearch[episodeIndex])).ToString("D2"); episodeNumber = (int.Parse(episodeSearch[episodeIndex])).ToString("D2"); //episodeTitle = episodeNameSearch[episodeIndex]; foundEpisode = true; } else if (multipart) { foundEpisode = true; } else { Console.WriteLine("Ignoring Episode Search"); foundEpisode = false; } } } // Move file to new filename format and delete original file if user wants since I have everything now if (hasChannel && rename && foundSeries && seriesID != null && foundEpisode) { string extension = filename.Substring(filename.LastIndexOf(".")); string filenameNoExt = filename.Remove(filename.LastIndexOf(".")); string path = filename.Remove(filename.LastIndexOf("\\") + 1); seriesName = Renamer.replaceSpecialChars(seriesName); episodeTitle = Renamer.replaceSpecialChars(episodeTitle); string newfilenameNoExt = path + seriesName + ".S" + seasonNumber + "E" + episodeNumber + "." + episodeTitle; newfilename = newfilenameNoExt + extension; if (!File.Exists(newfilename)) { if (simMode) { Console.WriteLine("SIMULATING Creating {0}.", newfilename); } else { // Add SxxExx to Episode Description if it doesn't exist foreach (PVSProperty pvp in mediafile.Properties) { if (pvp.Name.Equals("EpisodeDescription")) { string episodeDescription = pvp.Value; if (!(Regex.IsMatch(episodeDescription, "[Ss]+([0-9]+)+[Ee]+([0-9]+)"))) { episodeDescription = "S" + seasonNumber + "E" + episodeNumber + " - " + episodeDescription; pvp.Value = episodeDescription; } library.EditMedia(auth, @filename, mediafile); break; } } // Copy all files with this filename // Copy main video file //System.IO.File.Copy(@filename, @newfilename); while (IsFileLocked(new FileInfo(@filename))) { ; } System.IO.File.Move(@filename, @newfilename); // Copy chapters xml file string tempsource = filename + ".chapters.xml"; string tempdest = newfilename + ".chapters.xml"; if (File.Exists(tempsource)) { //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); } // Copy edl file tempsource = filenameNoExt + ".edl"; tempdest = newfilenameNoExt + ".edl"; if (File.Exists(tempsource)) { //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); } // Copy txt file tempsource = filenameNoExt + ".txt"; tempdest = newfilenameNoExt + ".txt"; if (File.Exists(tempsource)) { //System.IO.File.Copy(@tempsource, @tempdest); System.IO.File.Move(@tempsource, @tempdest); } // Copy log file tempsource = filenameNoExt + ".log"; tempdest = newfilenameNoExt + ".log"; if (File.Exists(tempsource)) { //System.IO.File.Copy(@tempsource, tempdest); System.IO.File.Move(@tempsource, @tempdest); } // Wait for library to be uploaded if changing the watched flag if (watchedFlag.Equals("True")) { // Check if new file is in library PVSPropertyBag newfile = null; Console.WriteLine("Waiting for Library to update"); while (newfile == null) { try { newfile = library.GetMediaByFullName(auth, @newfilename); Thread.Sleep(500); } catch (Exception e) { Console.Write("."); }; } Console.WriteLine(""); // Maintain the Watched flag library.SetUserSpecificProperty(auth, @newfilename, "Watched", watchedFlag); library.EditMedia(auth, @newfilename, mediafile); } } } else { Console.WriteLine("File {0} Exists. Ignoring changes.", newfilename); /* * if (simMode) * Console.WriteLine("SIMULATING Deleting {0} if the user requested.", filename); * else * { * // Ask user to delete the original * Console.Write("Delete the original file? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * // Delete Main Video File * FileInfo file = new FileInfo(filename); * if (file.IsReadOnly) * { * Console.Write("File is Read Only, override and delete? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * file.IsReadOnly = false; * System.IO.File.Delete(@filename); * } * } * else * System.IO.File.Delete(@filename); * * // Delete Chapters XML file * string tempsource = filename + ".chapters.xml"; * if (File.Exists(tempsource)) * { * file = new FileInfo(tempsource); * if (file.IsReadOnly) * { * Console.Write("File is Read Only, override and delete? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * file.IsReadOnly = false; * System.IO.File.Delete(@tempsource); * } * } * else * System.IO.File.Delete(@tempsource); * } * * // Delete EDL file * tempsource = filenameNoExt + ".edl"; * if (File.Exists(tempsource)) * { * file = new FileInfo(tempsource); * if (file.IsReadOnly) * { * Console.Write("File is Read Only, override and delete? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * file.IsReadOnly = false; * System.IO.File.Delete(@tempsource); * } * } * else * System.IO.File.Delete(@tempsource); * } * * // Delete TXT file * tempsource = filenameNoExt + ".txt"; * if (File.Exists(tempsource)) * { * file = new FileInfo(tempsource); * if (file.IsReadOnly) * { * Console.Write("File is Read Only, override and delete? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * file.IsReadOnly = false; * System.IO.File.Delete(@tempsource); * } * } * else * System.IO.File.Delete(@tempsource); * } * * // Delete LOG file * tempsource = filenameNoExt + ".log"; * if (File.Exists(tempsource)) * { * file = new FileInfo(tempsource); * if (file.IsReadOnly) * { * Console.Write("File is Read Only, override and delete? [y]/n: "); * res = Console.ReadLine(); * if (res.Equals("y") || res.Equals("Y") || res.Equals("")) * { * file.IsReadOnly = false; * System.IO.File.Delete(@tempsource); * } * } * else * System.IO.File.Delete(@tempsource); * } * } * } */ } if (!unattended) { Console.WriteLine("-----------PRESS ANY KEY TO CONTINUE-----------"); Console.ReadLine(); } } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } Console.WriteLine("---------------------------------------\n"); } //Logoff the BeyondTV server Console.WriteLine("Finished...logging off"); manager.Logoff(auth); Console.ReadLine(); }