OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Functions / Main.cs
1 /*  Main.cs $\r
2         \r
3            This file is part of the HandBrake source code.\r
4            Homepage: <http://handbrake.fr>.\r
5            It may be used under the terms of the GNU General Public License. */\r
6 \r
7 using System;\r
8 using System.Windows.Forms;\r
9 using System.IO;\r
10 using System.Diagnostics;\r
11 using System.Text.RegularExpressions;\r
12 using System.Collections.Generic;\r
13 using System.Xml.Serialization;\r
14 using System.Threading;\r
15 using Handbrake.EncodeQueue;\r
16 using System.Net;\r
17 \r
18 namespace Handbrake.Functions\r
19 {\r
20     static class Main\r
21     {\r
22         // Private Variables\r
23         private static readonly XmlSerializer ser = new XmlSerializer(typeof(List<Job>));\r
24 \r
25         /// <summary>\r
26         /// Calculate the duration of the selected title and chapters\r
27         /// </summary>\r
28         public static TimeSpan calculateDuration(string chapter_start, string chapter_end, Parsing.Title selectedTitle)\r
29         {\r
30             TimeSpan Duration = TimeSpan.FromSeconds(0.0);\r
31 \r
32             // Get the durations between the 2 chapter points and add them together.\r
33             if (chapter_start != "Auto" && chapter_end != "Auto")\r
34             {\r
35                 int start_chapter, end_chapter;\r
36                 int.TryParse(chapter_start, out start_chapter);\r
37                 int.TryParse(chapter_end, out end_chapter);\r
38 \r
39                 int position = start_chapter - 1;\r
40 \r
41                 if (start_chapter <= end_chapter)\r
42                 {\r
43                     if (end_chapter > selectedTitle.Chapters.Count)\r
44                         end_chapter = selectedTitle.Chapters.Count;\r
45 \r
46                     while (position != end_chapter)\r
47                     {\r
48                         TimeSpan dur = selectedTitle.Chapters[position].Duration;\r
49                         Duration = Duration + dur;\r
50                         position++;\r
51                     }\r
52                 }\r
53             }\r
54             return Duration;\r
55         }\r
56 \r
57         /// <summary>\r
58         /// Select the longest title in the DVD title dropdown menu on frmMain\r
59         /// </summary>\r
60         public static Parsing.Title selectLongestTitle(ComboBox drp_dvdtitle)\r
61         {\r
62             int current_largest = 0;\r
63             Parsing.Title title2Select;\r
64 \r
65             // Check if there are titles in the DVD title dropdown menu and make sure, it's not just "Automatic"\r
66             if (drp_dvdtitle.Items[0].ToString() != "Automatic")\r
67                 title2Select = (Parsing.Title)drp_dvdtitle.Items[0];\r
68             else\r
69                 title2Select = null;\r
70 \r
71             // So, If there are titles in the DVD Title dropdown menu, lets select the longest.\r
72             if (title2Select != null)\r
73             {\r
74                 foreach (Parsing.Title x in drp_dvdtitle.Items)\r
75                 {\r
76                     string title = x.ToString();\r
77                     if (title != "Automatic")\r
78                     {\r
79                         string[] y = title.Split(' ');\r
80                         string time = y[1].Replace("(", "").Replace(")", "");\r
81                         string[] z = time.Split(':');\r
82 \r
83                         int hours = int.Parse(z[0]) * 60 * 60;\r
84                         int minutes = int.Parse(z[1]) * 60;\r
85                         int seconds = int.Parse(z[2]);\r
86                         int total_sec = hours + minutes + seconds;\r
87 \r
88                         if (current_largest == 0)\r
89                         {\r
90                             current_largest = hours + minutes + seconds;\r
91                             title2Select = x;\r
92                         }\r
93                         else\r
94                         {\r
95                             if (total_sec > current_largest)\r
96                             {\r
97                                 current_largest = total_sec;\r
98                                 title2Select = x;\r
99                             }\r
100                         }\r
101                     }\r
102                 }\r
103             }\r
104             return title2Select;\r
105         }\r
106 \r
107         /// <summary>\r
108         /// Set's up the DataGridView on the Chapters tab (frmMain)\r
109         /// </summary>\r
110         public static DataGridView chapterNaming(DataGridView data_chpt, string chapter_end)\r
111         {\r
112             int i = 0, finish = 0;\r
113 \r
114             if (chapter_end != "Auto")\r
115                 int.TryParse(chapter_end, out finish);\r
116 \r
117             while (i < finish)\r
118             {\r
119                 int n = data_chpt.Rows.Add();\r
120                 data_chpt.Rows[n].Cells[0].Value = (i + 1);\r
121                 data_chpt.Rows[n].Cells[1].Value = "Chapter " + (i + 1);\r
122                 data_chpt.Rows[n].Cells[0].ValueType = typeof(int);\r
123                 data_chpt.Rows[n].Cells[1].ValueType = typeof(string);\r
124                 i++;\r
125             }\r
126 \r
127             return data_chpt;\r
128         }\r
129 \r
130         /// <summary>\r
131         /// Function which generates the filename and path automatically based on \r
132         /// the Source Name, DVD title and DVD Chapters\r
133         /// </summary>\r
134         public static string autoName(ComboBox drp_dvdtitle, string chapter_start, string chatper_end, string source, string dest, int format)\r
135         {\r
136             string AutoNamePath = string.Empty;\r
137             if (drp_dvdtitle.Text != "Automatic")\r
138             {\r
139                 // Get the Source Name \r
140                 string sourceName = Path.GetFileNameWithoutExtension(source);\r
141 \r
142                 // Get the Selected Title Number\r
143                 string[] titlesplit = drp_dvdtitle.Text.Split(' ');\r
144                 string dvdTitle = titlesplit[0].Replace("Automatic", "");\r
145 \r
146                 // Get the Chapter Start and Chapter End Numbers\r
147                 string chapterStart = chapter_start.Replace("Auto", "");\r
148                 string chapterFinish = chatper_end.Replace("Auto", "");\r
149                 string combinedChapterTag = chapterStart;\r
150                 if (chapterFinish != chapterStart && chapterFinish != "")\r
151                     combinedChapterTag = chapterStart + "-" + chapterFinish;\r
152 \r
153                 // Get the destination filename.\r
154                 string destination_filename;\r
155                 if (Properties.Settings.Default.autoNameFormat != "")\r
156                 {\r
157                     destination_filename = Properties.Settings.Default.autoNameFormat;\r
158                     destination_filename = destination_filename.Replace("{source}", sourceName).Replace("{title}", dvdTitle).Replace("{chapters}", combinedChapterTag);\r
159                 }\r
160                 else\r
161                     destination_filename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;\r
162 \r
163                 // Add the appropriate file extension\r
164                 if (format == 0)\r
165                     destination_filename += ".mp4";\r
166                 else if (format == 1)\r
167                     destination_filename += ".m4v";\r
168                 else if (format == 2)\r
169                     destination_filename += ".mkv";\r
170 \r
171                 // Now work out the path where the file will be stored.\r
172                 // First case: If the destination box doesn't already contain a path, make one.\r
173                 if (!dest.Contains(Path.DirectorySeparatorChar.ToString()))\r
174                 {\r
175                     // If there is an auto name path, use it...\r
176                     if (Properties.Settings.Default.autoNamePath.Trim() != "" && Properties.Settings.Default.autoNamePath.Trim() != "Click 'Browse' to set the default location")\r
177                         AutoNamePath = Path.Combine(Properties.Settings.Default.autoNamePath, destination_filename);\r
178                     else // ...otherwise, output to the source directory\r
179                         AutoNamePath = null;\r
180                 }\r
181                 else // Otherwise, use the path that is already there.\r
182                 {\r
183                     // Use the path and change the file extension to match the previous destination\r
184                     AutoNamePath = Path.Combine(Path.GetDirectoryName(dest), destination_filename);\r
185                     AutoNamePath = Path.ChangeExtension(AutoNamePath, Path.GetExtension(dest));\r
186                 }\r
187             }\r
188 \r
189             return AutoNamePath;\r
190         }\r
191 \r
192         /// <summary>\r
193         /// Get's HandBrakes version data from the CLI.\r
194         /// </summary>\r
195         /// <returns>Arraylist of Version Data. 0 = hb_version 1 = hb_build</returns>\r
196         public static void setCliVersionData()\r
197         {\r
198             String line;\r
199 \r
200             // 0 = SVN Build / Version\r
201             // 1 = Build Date\r
202             Process cliProcess = new Process();\r
203             ProcessStartInfo handBrakeCLI = new ProcessStartInfo("HandBrakeCLI.exe", " -u")\r
204                                                 {\r
205                                                     UseShellExecute = false,\r
206                                                     RedirectStandardError = true,\r
207                                                     RedirectStandardOutput = true,\r
208                                                     CreateNoWindow = true\r
209                                                 };\r
210             cliProcess.StartInfo = handBrakeCLI;\r
211 \r
212             try\r
213             {\r
214                 cliProcess.Start();\r
215                 // Retrieve standard output and report back to parent thread until the process is complete\r
216                 TextReader stdOutput = cliProcess.StandardError;\r
217 \r
218                 while (!cliProcess.HasExited)\r
219                 {\r
220                     line = stdOutput.ReadLine() ?? "";\r
221                     Match m = Regex.Match(line, @"HandBrake ([0-9.]*)(svn[0-9M]*) \([0-9]*\)");\r
222 \r
223                     if (m.Success)\r
224                     {\r
225                         string data = line.Replace("(", "").Replace(")", "").Replace("HandBrake ", "");\r
226                         string[] arr = data.Split(' ');\r
227 \r
228                         Properties.Settings.Default.hb_build = int.Parse(arr[1]);\r
229                         Properties.Settings.Default.hb_version = arr[0];\r
230                     }\r
231                     if (cliProcess.TotalProcessorTime.Seconds > 10) // Don't wait longer than 10 seconds.\r
232                     {\r
233                         Process cli = Process.GetProcessById(cliProcess.Id);\r
234                         if (!cli.HasExited)\r
235                             cli.Kill();\r
236                     }\r
237                 }\r
238             }\r
239             catch (Exception e)\r
240             {\r
241                 MessageBox.Show("Unable to retrieve version information from the CLI. \nError:\n" + e);\r
242             }\r
243         }\r
244 \r
245         /// <summary>\r
246         /// Check if the queue recovery file contains records.\r
247         /// If it does, it means the last queue did not complete before HandBrake closed.\r
248         /// So, return a boolean if true. \r
249         /// </summary>\r
250         public static Boolean check_queue_recovery()\r
251         {\r
252             try\r
253             {\r
254                 string tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");\r
255                 if (File.Exists(tempPath))\r
256                 {\r
257                     using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))\r
258                     {\r
259                         List<Job> list = ser.Deserialize(strm) as List<Job>;\r
260                         if (list != null)\r
261                             if (list.Count != 0)\r
262                                 return true;\r
263                     }\r
264                 }\r
265                 return false;\r
266             }\r
267             catch (Exception)\r
268             {\r
269                 return false; // Keep quiet about the error.\r
270             }\r
271         }\r
272 \r
273         /// <summary>\r
274         /// Get the Process ID of HandBrakeCLI for the current instance.\r
275         /// </summary>\r
276         /// <param name="before">List of processes before the new process was started</param>\r
277         /// <returns>Int - Process ID</returns>\r
278         public static int getCliProcess(Process[] before)\r
279         {\r
280             // This is a bit of a cludge. Maybe someone has a better idea on how to impliment this.\r
281             // Since we used CMD to start HandBrakeCLI, we don't get the process ID from hbProc.\r
282             // Instead we take the processes before and after, and get the ID of HandBrakeCLI.exe\r
283             // avoiding any previous instances of HandBrakeCLI.exe in before.\r
284             // Kill the current process.\r
285 \r
286             Process[] hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
287 \r
288             // Another hack. We maybe need to wait a few seconds for HandBrakeCLI to launch\r
289             if (hbProcesses.Length == 0)\r
290             {\r
291                 Thread.Sleep(2000);\r
292                 hbProcesses = Process.GetProcessesByName("HandBrakeCLI");\r
293             }\r
294 \r
295             Process hbProcess = null;\r
296             if (hbProcesses.Length > 0)\r
297                 foreach (Process process in hbProcesses)\r
298                 {\r
299                     Boolean found = false;\r
300                     // Check if the current CLI instance was running before we started the current one\r
301                     foreach (Process bprocess in before)\r
302                     {\r
303                         if (process.Id == bprocess.Id)\r
304                             found = true;\r
305                     }\r
306 \r
307                     // If it wasn't running before, we found the process we want.\r
308                     if (!found)\r
309                     {\r
310                         hbProcess = process;\r
311                         break;\r
312                     }\r
313                 }\r
314             if (hbProcess != null)\r
315                 return hbProcess.Id;\r
316 \r
317             return -1;\r
318         }\r
319 \r
320         /// <summary>\r
321         ///  Clear all the encode log files.\r
322         /// </summary>\r
323         public static void clearLogs()\r
324         {\r
325             string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
326             if (Directory.Exists(logDir))\r
327             {\r
328                 DirectoryInfo info = new DirectoryInfo(logDir);\r
329                 FileInfo[] logFiles = info.GetFiles("*.txt");\r
330                 foreach (FileInfo file in logFiles)\r
331                 {\r
332                     if (!file.Name.Contains("last_scan_log") && !file.Name.Contains("last_encode_log") && !file.Name.Contains("tmp_appReadable_log.txt"))\r
333                     {\r
334                         File.Delete(file.FullName);\r
335                     }\r
336                 }\r
337             }\r
338         }\r
339 \r
340         /// <summary>\r
341         /// Begins checking for an update to HandBrake.\r
342         /// </summary>\r
343         /// <param name="callback">The method that will be called when the check is finished.</param>\r
344         /// <param name="debug">Whether or not to execute this in debug mode.</param>\r
345         public static void BeginCheckForUpdates(AsyncCallback callback, bool debug)\r
346         {\r
347             ThreadPool.QueueUserWorkItem(new WaitCallback(delegate\r
348             {\r
349                 try\r
350                 {\r
351                     // Is this a stable or unstable build?\r
352                     string url = Properties.Settings.Default.hb_build.ToString().EndsWith("1") ? Properties.Settings.Default.appcast_unstable : Properties.Settings.Default.appcast;\r
353 \r
354                     // Initialize variables\r
355                     WebRequest request = WebRequest.Create(url);\r
356                     WebResponse response = request.GetResponse();\r
357                     AppcastReader reader = new AppcastReader();\r
358 \r
359                     // Get the data, convert it to a string, and parse it into the AppcastReader\r
360                     reader.getInfo(new StreamReader(response.GetResponseStream()).ReadToEnd());\r
361 \r
362                     // Further parse the information\r
363                     string build = reader.build;\r
364 \r
365                     int latest = int.Parse(build);\r
366                     int current = Properties.Settings.Default.hb_build;\r
367                     int skip = Properties.Settings.Default.skipversion;\r
368 \r
369                     // If the user wanted to skip this version, don't report the update\r
370                     if (latest == skip)\r
371                     {\r
372                         UpdateCheckInformation info = new UpdateCheckInformation() { NewVersionAvailable = false, BuildInformation = null };\r
373                         callback(new UpdateCheckResult(debug, info));\r
374                         return;\r
375                     }\r
376 \r
377                     // Set when the last update was\r
378                     Properties.Settings.Default.lastUpdateCheckDate = DateTime.Now;\r
379                     Properties.Settings.Default.Save();\r
380 \r
381                     UpdateCheckInformation info2 = new UpdateCheckInformation() { NewVersionAvailable = latest > current, BuildInformation = reader };\r
382                     callback(new UpdateCheckResult(debug, info2));\r
383                 }\r
384                 catch (Exception exc)\r
385                 {\r
386                     callback(new UpdateCheckResult(debug, new UpdateCheckInformation() { Error = exc }));\r
387                 }\r
388             }));\r
389         }\r
390 \r
391         /// <summary>\r
392         /// \r
393         /// </summary>\r
394         /// <param name="result"></param>\r
395         /// <returns></returns>\r
396         public static UpdateCheckInformation EndCheckForUpdates(IAsyncResult result)\r
397         {\r
398             UpdateCheckResult checkResult = (UpdateCheckResult)result;\r
399             return checkResult.Result;\r
400         }\r
401 \r
402         /// <summary>\r
403         /// Used in EndUpdateCheck() for update checking and the IAsyncResult design pattern.\r
404         /// </summary>\r
405         private class UpdateCheckResult : IAsyncResult\r
406         {\r
407             public UpdateCheckResult(object asyncState, UpdateCheckInformation info)\r
408             {\r
409                 AsyncState = asyncState;\r
410                 Result = info;\r
411             }\r
412 \r
413             /// <summary>\r
414             /// Gets whether the check was executed in debug mode.\r
415             /// </summary>\r
416             public object AsyncState { get; private set; }\r
417 \r
418             /// <summary>\r
419             /// Gets the result of the update check.\r
420             /// </summary>\r
421             public UpdateCheckInformation Result { get; private set; }\r
422 \r
423             public WaitHandle AsyncWaitHandle { get { throw new NotImplementedException(); } }\r
424             public bool CompletedSynchronously { get { throw new NotImplementedException(); } }\r
425             public bool IsCompleted { get { throw new NotImplementedException(); } }\r
426         }\r
427     }\r
428 }\r