OpenSubtitles.cs 156 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550
  1. /* This file is part of OpenSubtitles Handler
  2. A library that handle OpenSubtitles.org XML-RPC methods.
  3. Copyright © Ala Ibrahim Hadid 2013
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using System;
  16. using System.Text;
  17. using System.Collections.Generic;
  18. using System.IO;
  19. using System.Threading;
  20. using System.Threading.Tasks;
  21. using OpenSubtitlesHandler.Console;
  22. using XmlRpcHandler;
  23. namespace OpenSubtitlesHandler
  24. {
  25. /// <summary>
  26. /// The core of the OpenSubtitles Handler library. All members are static.
  27. /// </summary>
  28. public sealed class OpenSubtitles
  29. {
  30. private static string XML_PRC_USERAGENT = "";
  31. // This is session id after log in, important value and MUST be set by LogIn before any other call.
  32. private static string TOKEN = "";
  33. /// <summary>
  34. /// Set the useragent value. This must be called before doing anything else.
  35. /// </summary>
  36. /// <param name="agent">The useragent value</param>
  37. public static void SetUserAgent(string agent)
  38. {
  39. XML_PRC_USERAGENT = agent;
  40. }
  41. /*Session handling*/
  42. /// <summary>
  43. /// Send a LogIn request, this must be called before anything else in this class.
  44. /// </summary>
  45. /// <param name="userName">The user name of OpenSubtitles</param>
  46. /// <param name="password">The password</param>
  47. /// <param name="language">The language, usally en</param>
  48. /// <returns>Status of the login operation</returns>
  49. public static IMethodResponse LogIn(string userName, string password, string language)
  50. {
  51. // Method call ..
  52. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  53. parms.Add(new XmlRpcValueBasic(userName));
  54. parms.Add(new XmlRpcValueBasic(password));
  55. parms.Add(new XmlRpcValueBasic(language));
  56. parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT));
  57. XmlRpcMethodCall call = new XmlRpcMethodCall("LogIn", parms);
  58. OSHConsole.WriteLine("Sending LogIn request to the server ...", DebugCode.Good);
  59. //File.WriteAllText(".\\request.txt", Encoding.UTF8.GetString(XmlRpcGenerator.Generate(call)));
  60. // Send the request to the server
  61. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  62. if (!response.Contains("ERROR:"))
  63. {
  64. // No error occur, get and decode the response. We expect Struct here.
  65. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  66. if (calls.Length > 0)
  67. {
  68. if (calls[0].Parameters.Count > 0)
  69. {
  70. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  71. MethodResponseLogIn re = new MethodResponseLogIn("Success", "Log in successful.");
  72. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  73. {
  74. switch (MEMBER.Name)
  75. {
  76. case "token": re.Token = TOKEN = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  77. case "seconds": re.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  78. case "status": re.Status = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  79. }
  80. }
  81. return re;
  82. }
  83. }
  84. }
  85. else
  86. {
  87. OSHConsole.WriteLine(response, DebugCode.Error);
  88. return new MethodResponseError("Fail", response);
  89. }
  90. return new MethodResponseError("Fail", "Log in failed !");
  91. }
  92. public static async Task<IMethodResponse> LogInAsync(string userName, string password, string language, CancellationToken cancellationToken)
  93. {
  94. // Method call ..
  95. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  96. parms.Add(new XmlRpcValueBasic(userName));
  97. parms.Add(new XmlRpcValueBasic(password));
  98. parms.Add(new XmlRpcValueBasic(language));
  99. parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT));
  100. XmlRpcMethodCall call = new XmlRpcMethodCall("LogIn", parms);
  101. OSHConsole.WriteLine("Sending LogIn request to the server ...", DebugCode.Good);
  102. //File.WriteAllText(".\\request.txt", Encoding.UTF8.GetString(XmlRpcGenerator.Generate(call)));
  103. // Send the request to the server
  104. var stream = await Utilities.SendRequestAsync(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT, cancellationToken)
  105. .ConfigureAwait(false);
  106. string response = Utilities.GetStreamString(stream);
  107. if (!response.Contains("ERROR:"))
  108. {
  109. // No error occur, get and decode the response. We expect Struct here.
  110. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  111. if (calls.Length > 0)
  112. {
  113. if (calls[0].Parameters.Count > 0)
  114. {
  115. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  116. MethodResponseLogIn re = new MethodResponseLogIn("Success", "Log in successful.");
  117. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  118. {
  119. switch (MEMBER.Name)
  120. {
  121. case "token": re.Token = TOKEN = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  122. case "seconds": re.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  123. case "status": re.Status = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  124. }
  125. }
  126. return re;
  127. }
  128. }
  129. }
  130. else
  131. {
  132. OSHConsole.WriteLine(response, DebugCode.Error);
  133. return new MethodResponseError("Fail", response);
  134. }
  135. return new MethodResponseError("Fail", "Log in failed !");
  136. }
  137. /// <summary>
  138. /// Log out from the server. Call this to terminate the session.
  139. /// </summary>
  140. /// <returns></returns>
  141. public static IMethodResponse LogOut()
  142. {
  143. if (TOKEN == "")
  144. {
  145. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  146. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  147. }
  148. // Method call ..
  149. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  150. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  151. XmlRpcMethodCall call = new XmlRpcMethodCall("LogOut", parms);
  152. OSHConsole.WriteLine("Sending LogOut request to the server ...", DebugCode.Good);
  153. // Send the request to the server
  154. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  155. if (!response.Contains("ERROR:"))
  156. {
  157. // No error occur, get and decode the response. We expect Struct here.
  158. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  159. if (calls.Length > 0)
  160. {
  161. if (calls[0].Parameters.Count > 0)
  162. {
  163. XmlRpcValueStruct strct = (XmlRpcValueStruct)calls[0].Parameters[0];
  164. OSHConsole.WriteLine("STATUS=" + ((XmlRpcValueBasic)strct.Members[0].Data).Data.ToString());
  165. OSHConsole.WriteLine("SECONDS=" + ((XmlRpcValueBasic)strct.Members[1].Data).Data.ToString());
  166. MethodResponseLogIn re = new MethodResponseLogIn("Success", "Log out successful.");
  167. re.Status = ((XmlRpcValueBasic)strct.Members[0].Data).Data.ToString();
  168. re.Seconds = (double)((XmlRpcValueBasic)strct.Members[1].Data).Data;
  169. return re;
  170. }
  171. }
  172. }
  173. else
  174. {
  175. OSHConsole.WriteLine(response, DebugCode.Error);
  176. return new MethodResponseError("Fail", response);
  177. }
  178. return new MethodResponseError("Fail", "Log out failed !");
  179. }
  180. /// <summary>
  181. /// keep-alive user's session, verify token/session validity
  182. /// </summary>
  183. /// <returns>Status of the call operation</returns>
  184. public static IMethodResponse NoOperation()
  185. {
  186. if (TOKEN == "")
  187. {
  188. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  189. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  190. }
  191. // Method call ..
  192. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  193. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  194. parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT, XmlRpcBasicValueType.String));
  195. XmlRpcMethodCall call = new XmlRpcMethodCall("NoOperation", parms);
  196. OSHConsole.WriteLine("Sending NoOperation request to the server ...", DebugCode.Good);
  197. // Send the request to the server
  198. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  199. if (!response.Contains("ERROR:"))
  200. {
  201. // No error occur, get and decode the response. We expect Struct here.
  202. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  203. if (calls.Length > 0)
  204. {
  205. if (calls[0].Parameters.Count > 0)
  206. {
  207. MethodResponseNoOperation R = new MethodResponseNoOperation();
  208. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  209. // To make sure response is not currepted by server, do it in loop
  210. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  211. {
  212. switch (MEMBER.Name)
  213. {
  214. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data); break;
  215. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data); break;
  216. case "download_limits":
  217. XmlRpcValueStruct dlStruct = (XmlRpcValueStruct)MEMBER.Data;
  218. foreach (XmlRpcStructMember dlmember in dlStruct.Members)
  219. {
  220. OSHConsole.WriteLine(" >" + dlmember.Name + "= " + dlmember.Data.Data.ToString());
  221. switch (dlmember.Name)
  222. {
  223. case "global_wrh_download_limit": R.global_wrh_download_limit = dlmember.Data.Data.ToString(); break;
  224. case "client_ip": R.client_ip = dlmember.Data.Data.ToString(); break;
  225. case "limit_check_by": R.limit_check_by = dlmember.Data.Data.ToString(); break;
  226. case "client_24h_download_count": R.client_24h_download_count = dlmember.Data.Data.ToString(); break;
  227. case "client_downlaod_quota": R.client_downlaod_quota = dlmember.Data.Data.ToString(); break;
  228. case "client_24h_download_limit": R.client_24h_download_limit = dlmember.Data.Data.ToString(); break;
  229. }
  230. }
  231. break;
  232. }
  233. }
  234. return R;
  235. }
  236. }
  237. }
  238. else
  239. {
  240. OSHConsole.WriteLine(response, DebugCode.Error);
  241. return new MethodResponseError("Fail", response);
  242. }
  243. return new MethodResponseError("Fail", "NoOperation call failed !");
  244. }
  245. /*Search and download*/
  246. /// <summary>
  247. /// Search for subtitle files matching your videos using either video file hashes or IMDb IDs.
  248. /// </summary>
  249. /// <param name="parameters">List of search subtitle parameters which each one represents 'struct parameter' as descriped at http://trac.opensubtitles.org/projects/opensubtitles/wiki/XmlRpcSearchSubtitles </param>
  250. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseSubtitleSearch'</returns>
  251. public static IMethodResponse SearchSubtitles(SubtitleSearchParameters[] parameters)
  252. {
  253. if (TOKEN == "")
  254. {
  255. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  256. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  257. }
  258. if (parameters == null)
  259. {
  260. OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
  261. return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
  262. }
  263. if (parameters.Length == 0)
  264. {
  265. OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
  266. return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
  267. }
  268. // Method call ..
  269. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  270. // Add token param
  271. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  272. // Add subtitle search parameters. Each one will be like 'array' of structs.
  273. XmlRpcValueArray array = new XmlRpcValueArray();
  274. foreach (SubtitleSearchParameters param in parameters)
  275. {
  276. XmlRpcValueStruct strct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  277. // sublanguageid member
  278. XmlRpcStructMember member = new XmlRpcStructMember("sublanguageid",
  279. new XmlRpcValueBasic(param.SubLangaugeID, XmlRpcBasicValueType.String));
  280. strct.Members.Add(member);
  281. // moviehash member
  282. if (param.MovieHash.Length > 0 && param.MovieByteSize > 0) {
  283. member = new XmlRpcStructMember("moviehash",
  284. new XmlRpcValueBasic(param.MovieHash, XmlRpcBasicValueType.String));
  285. strct.Members.Add(member);
  286. // moviehash member
  287. member = new XmlRpcStructMember("moviebytesize",
  288. new XmlRpcValueBasic(param.MovieByteSize, XmlRpcBasicValueType.Int));
  289. strct.Members.Add(member);
  290. }
  291. if (param.Query.Length > 0) {
  292. member = new XmlRpcStructMember("query",
  293. new XmlRpcValueBasic(param.Query, XmlRpcBasicValueType.String));
  294. strct.Members.Add(member);
  295. }
  296. if (param.Episode.Length > 0 && param.Season.Length>0) {
  297. member = new XmlRpcStructMember("season",
  298. new XmlRpcValueBasic(param.Season, XmlRpcBasicValueType.String));
  299. strct.Members.Add(member);
  300. member = new XmlRpcStructMember("episode",
  301. new XmlRpcValueBasic(param.Episode, XmlRpcBasicValueType.String));
  302. strct.Members.Add(member);
  303. }
  304. // imdbid member
  305. if (param.IMDbID.Length > 0)
  306. {
  307. member = new XmlRpcStructMember("imdbid",
  308. new XmlRpcValueBasic(param.IMDbID, XmlRpcBasicValueType.String));
  309. strct.Members.Add(member);
  310. }
  311. // Add the struct to the array
  312. array.Values.Add(strct);
  313. }
  314. // Add the array to the parameters
  315. parms.Add(array);
  316. // Call !
  317. XmlRpcMethodCall call = new XmlRpcMethodCall("SearchSubtitles", parms);
  318. OSHConsole.WriteLine("Sending SearchSubtitles request to the server ...", DebugCode.Good);
  319. // Send the request to the server
  320. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  321. if (!response.Contains("ERROR:"))
  322. {
  323. // No error occur, get and decode the response.
  324. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  325. if (calls.Length > 0)
  326. {
  327. if (calls[0].Parameters.Count > 0)
  328. {
  329. // We expect Struct of 3 members:
  330. //* the first is status
  331. //* the second is [array of structs, each one includes subtitle file].
  332. //* the third is [double basic value] represent seconds token by server.
  333. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  334. // Create the response, we'll need it later
  335. MethodResponseSubtitleSearch R = new MethodResponseSubtitleSearch();
  336. // To make sure response is not currepted by server, do it in loop
  337. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  338. {
  339. if (MEMBER.Name == "status")
  340. {
  341. R.Status = (string)MEMBER.Data.Data;
  342. OSHConsole.WriteLine("Status= " + R.Status);
  343. }
  344. else if (MEMBER.Name == "seconds")
  345. {
  346. R.Seconds = (double)MEMBER.Data.Data;
  347. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  348. }
  349. else if (MEMBER.Name == "data")
  350. {
  351. if (MEMBER.Data is XmlRpcValueArray)
  352. {
  353. OSHConsole.WriteLine("Search results: ");
  354. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  355. foreach (IXmlRpcValue subStruct in rarray.Values)
  356. {
  357. if (subStruct == null) continue;
  358. if (!(subStruct is XmlRpcValueStruct)) continue;
  359. SubtitleSearchResult result = new SubtitleSearchResult();
  360. foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
  361. {
  362. // To avoid errors of arranged info or missing ones, let's do it with switch..
  363. switch (submember.Name)
  364. {
  365. case "IDMovie": result.IDMovie = submember.Data.Data.ToString(); break;
  366. case "IDMovieImdb": result.IDMovieImdb = submember.Data.Data.ToString(); break;
  367. case "IDSubMovieFile": result.IDSubMovieFile = submember.Data.Data.ToString(); break;
  368. case "IDSubtitle": result.IDSubtitle = submember.Data.Data.ToString(); break;
  369. case "IDSubtitleFile": result.IDSubtitleFile = submember.Data.Data.ToString(); break;
  370. case "ISO639": result.ISO639 = submember.Data.Data.ToString(); break;
  371. case "LanguageName": result.LanguageName = submember.Data.Data.ToString(); break;
  372. case "MovieByteSize": result.MovieByteSize = submember.Data.Data.ToString(); break;
  373. case "MovieHash": result.MovieHash = submember.Data.Data.ToString(); break;
  374. case "MovieImdbRating": result.MovieImdbRating = submember.Data.Data.ToString(); break;
  375. case "MovieName": result.MovieName = submember.Data.Data.ToString(); break;
  376. case "MovieNameEng": result.MovieNameEng = submember.Data.Data.ToString(); break;
  377. case "MovieReleaseName": result.MovieReleaseName = submember.Data.Data.ToString(); break;
  378. case "MovieTimeMS": result.MovieTimeMS = submember.Data.Data.ToString(); break;
  379. case "MovieYear": result.MovieYear = submember.Data.Data.ToString(); break;
  380. case "SubActualCD": result.SubActualCD = submember.Data.Data.ToString(); break;
  381. case "SubAddDate": result.SubAddDate = submember.Data.Data.ToString(); break;
  382. case "SubAuthorComment": result.SubAuthorComment = submember.Data.Data.ToString(); break;
  383. case "SubBad": result.SubBad = submember.Data.Data.ToString(); break;
  384. case "SubDownloadLink": result.SubDownloadLink = submember.Data.Data.ToString(); break;
  385. case "SubDownloadsCnt": result.SubDownloadsCnt = submember.Data.Data.ToString(); break;
  386. case "SeriesEpisode": result.SeriesEpisode = submember.Data.Data.ToString(); break;
  387. case "SeriesSeason": result.SeriesSeason = submember.Data.Data.ToString(); break;
  388. case "SubFileName": result.SubFileName = submember.Data.Data.ToString(); break;
  389. case "SubFormat": result.SubFormat = submember.Data.Data.ToString(); break;
  390. case "SubHash": result.SubHash = submember.Data.Data.ToString(); break;
  391. case "SubLanguageID": result.SubLanguageID = submember.Data.Data.ToString(); break;
  392. case "SubRating": result.SubRating = submember.Data.Data.ToString(); break;
  393. case "SubSize": result.SubSize = submember.Data.Data.ToString(); break;
  394. case "SubSumCD": result.SubSumCD = submember.Data.Data.ToString(); break;
  395. case "UserID": result.UserID = submember.Data.Data.ToString(); break;
  396. case "UserNickName": result.UserNickName = submember.Data.Data.ToString(); break;
  397. case "ZipDownloadLink": result.ZipDownloadLink = submember.Data.Data.ToString(); break;
  398. }
  399. }
  400. R.Results.Add(result);
  401. OSHConsole.WriteLine(">" + result.ToString());
  402. }
  403. }
  404. else// Unknown data ?
  405. {
  406. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  407. }
  408. }
  409. }
  410. // Return the response to user !!
  411. return R;
  412. }
  413. }
  414. }
  415. else
  416. {
  417. OSHConsole.WriteLine(response, DebugCode.Error);
  418. return new MethodResponseError("Fail", response);
  419. }
  420. return new MethodResponseError("Fail", "Search Subtitles call failed !");
  421. }
  422. /// <summary>
  423. /// Download subtitle file(s)
  424. /// </summary>
  425. /// <param name="subIDS">The subtitle IDS (an array of IDSubtitleFile value that given by server as SearchSubtiles results)</param>
  426. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseSubtitleDownload' which will hold downloaded subtitles</returns>
  427. public static IMethodResponse DownloadSubtitles(int[] subIDS)
  428. {
  429. if (TOKEN == "")
  430. {
  431. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  432. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  433. }
  434. if (subIDS == null)
  435. {
  436. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  437. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  438. }
  439. if (subIDS.Length == 0)
  440. {
  441. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  442. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  443. }
  444. // Method call ..
  445. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  446. // Add token param
  447. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  448. // Add subtitle search parameters. Each one will be like 'array' of structs.
  449. XmlRpcValueArray array = new XmlRpcValueArray();
  450. foreach (int id in subIDS)
  451. {
  452. array.Values.Add(new XmlRpcValueBasic(id, XmlRpcBasicValueType.Int));
  453. }
  454. // Add the array to the parameters
  455. parms.Add(array);
  456. // Call !
  457. XmlRpcMethodCall call = new XmlRpcMethodCall("DownloadSubtitles", parms);
  458. OSHConsole.WriteLine("Sending DownloadSubtitles request to the server ...", DebugCode.Good);
  459. // Send the request to the server
  460. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  461. if (!response.Contains("ERROR:"))
  462. {
  463. // No error occur, get and decode the response.
  464. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  465. if (calls.Length > 0)
  466. {
  467. if (calls[0].Parameters.Count > 0)
  468. {
  469. // We expect Struct of 3 members:
  470. //* the first is status
  471. //* the second is [array of structs, each one includes subtitle file].
  472. //* the third is [double basic value] represent seconds token by server.
  473. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  474. // Create the response, we'll need it later
  475. MethodResponseSubtitleDownload R = new MethodResponseSubtitleDownload();
  476. // To make sure response is not currepted by server, do it in loop
  477. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  478. {
  479. if (MEMBER.Name == "status")
  480. {
  481. R.Status = (string)MEMBER.Data.Data;
  482. OSHConsole.WriteLine("Status= " + R.Status);
  483. }
  484. else if (MEMBER.Name == "seconds")
  485. {
  486. R.Seconds = (double)MEMBER.Data.Data;
  487. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  488. }
  489. else if (MEMBER.Name == "data")
  490. {
  491. if (MEMBER.Data is XmlRpcValueArray)
  492. {
  493. OSHConsole.WriteLine("Download results:");
  494. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  495. foreach (IXmlRpcValue subStruct in rarray.Values)
  496. {
  497. if (subStruct == null) continue;
  498. if (!(subStruct is XmlRpcValueStruct)) continue;
  499. SubtitleDownloadResult result = new SubtitleDownloadResult();
  500. foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
  501. {
  502. // To avoid errors of arranged info or missing ones, let's do it with switch..
  503. switch (submember.Name)
  504. {
  505. case "idsubtitlefile": result.IdSubtitleFile = (string)submember.Data.Data; break;
  506. case "data": result.Data = (string)submember.Data.Data; break;
  507. }
  508. }
  509. R.Results.Add(result);
  510. OSHConsole.WriteLine("> IDSubtilteFile= " + result.ToString());
  511. }
  512. }
  513. else// Unknown data ?
  514. {
  515. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  516. }
  517. }
  518. }
  519. // Return the response to user !!
  520. return R;
  521. }
  522. }
  523. }
  524. else
  525. {
  526. OSHConsole.WriteLine(response, DebugCode.Error);
  527. return new MethodResponseError("Fail", response);
  528. }
  529. return new MethodResponseError("Fail", "DownloadSubtitles call failed !");
  530. }
  531. public static async Task<IMethodResponse> DownloadSubtitlesAsync(int[] subIDS, CancellationToken cancellationToken)
  532. {
  533. if (TOKEN == "")
  534. {
  535. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  536. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  537. }
  538. if (subIDS == null)
  539. {
  540. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  541. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  542. }
  543. if (subIDS.Length == 0)
  544. {
  545. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  546. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  547. }
  548. // Method call ..
  549. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  550. // Add token param
  551. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  552. // Add subtitle search parameters. Each one will be like 'array' of structs.
  553. XmlRpcValueArray array = new XmlRpcValueArray();
  554. foreach (int id in subIDS)
  555. {
  556. array.Values.Add(new XmlRpcValueBasic(id, XmlRpcBasicValueType.Int));
  557. }
  558. // Add the array to the parameters
  559. parms.Add(array);
  560. // Call !
  561. XmlRpcMethodCall call = new XmlRpcMethodCall("DownloadSubtitles", parms);
  562. OSHConsole.WriteLine("Sending DownloadSubtitles request to the server ...", DebugCode.Good);
  563. // Send the request to the server
  564. var httpResponse = await Utilities.SendRequestAsync(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT, cancellationToken).ConfigureAwait(false);
  565. string response = Utilities.GetStreamString(httpResponse);
  566. if (!response.Contains("ERROR:"))
  567. {
  568. // No error occur, get and decode the response.
  569. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  570. if (calls.Length > 0)
  571. {
  572. if (calls[0].Parameters.Count > 0)
  573. {
  574. // We expect Struct of 3 members:
  575. //* the first is status
  576. //* the second is [array of structs, each one includes subtitle file].
  577. //* the third is [double basic value] represent seconds token by server.
  578. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  579. // Create the response, we'll need it later
  580. MethodResponseSubtitleDownload R = new MethodResponseSubtitleDownload();
  581. // To make sure response is not currepted by server, do it in loop
  582. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  583. {
  584. if (MEMBER.Name == "status")
  585. {
  586. R.Status = (string)MEMBER.Data.Data;
  587. OSHConsole.WriteLine("Status= " + R.Status);
  588. }
  589. else if (MEMBER.Name == "seconds")
  590. {
  591. R.Seconds = (double)MEMBER.Data.Data;
  592. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  593. }
  594. else if (MEMBER.Name == "data")
  595. {
  596. if (MEMBER.Data is XmlRpcValueArray)
  597. {
  598. OSHConsole.WriteLine("Download results:");
  599. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  600. foreach (IXmlRpcValue subStruct in rarray.Values)
  601. {
  602. if (subStruct == null) continue;
  603. if (!(subStruct is XmlRpcValueStruct)) continue;
  604. SubtitleDownloadResult result = new SubtitleDownloadResult();
  605. foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
  606. {
  607. // To avoid errors of arranged info or missing ones, let's do it with switch..
  608. switch (submember.Name)
  609. {
  610. case "idsubtitlefile": result.IdSubtitleFile = (string)submember.Data.Data; break;
  611. case "data": result.Data = (string)submember.Data.Data; break;
  612. }
  613. }
  614. R.Results.Add(result);
  615. OSHConsole.WriteLine("> IDSubtilteFile= " + result.ToString());
  616. }
  617. }
  618. else// Unknown data ?
  619. {
  620. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  621. }
  622. }
  623. }
  624. // Return the response to user !!
  625. return R;
  626. }
  627. }
  628. }
  629. else
  630. {
  631. OSHConsole.WriteLine(response, DebugCode.Error);
  632. return new MethodResponseError("Fail", response);
  633. }
  634. return new MethodResponseError("Fail", "DownloadSubtitles call failed !");
  635. }
  636. /// <summary>
  637. /// Returns comments for subtitles
  638. /// </summary>
  639. /// <param name="subIDS">The subtitle IDS (an array of IDSubtitleFile value that given by server as SearchSubtiles results)</param>
  640. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseGetComments'</returns>
  641. public static IMethodResponse GetComments(int[] subIDS)
  642. {
  643. if (TOKEN == "")
  644. {
  645. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  646. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  647. }
  648. if (subIDS == null)
  649. {
  650. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  651. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  652. }
  653. if (subIDS.Length == 0)
  654. {
  655. OSHConsole.UpdateLine("No subtitle id passed !!", DebugCode.Error);
  656. return new MethodResponseError("Fail", "No subtitle id passed"); ;
  657. }
  658. // Method call ..
  659. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  660. // Add token param
  661. parms.Add(new XmlRpcValueBasic(TOKEN));
  662. // Add subtitle search parameters. Each one will be like 'array' of structs.
  663. XmlRpcValueArray array = new XmlRpcValueArray(subIDS);
  664. // Add the array to the parameters
  665. parms.Add(array);
  666. // Call !
  667. XmlRpcMethodCall call = new XmlRpcMethodCall("GetComments", parms);
  668. OSHConsole.WriteLine("Sending GetComments request to the server ...", DebugCode.Good);
  669. // Send the request to the server
  670. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  671. if (!response.Contains("ERROR:"))
  672. {
  673. // No error occur, get and decode the response.
  674. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  675. if (calls.Length > 0)
  676. {
  677. if (calls[0].Parameters.Count > 0)
  678. {
  679. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  680. // Create the response, we'll need it later
  681. MethodResponseGetComments R = new MethodResponseGetComments();
  682. // To make sure response is not currepted by server, do it in loop
  683. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  684. {
  685. if (MEMBER.Name == "status")
  686. {
  687. R.Status = (string)MEMBER.Data.Data;
  688. OSHConsole.WriteLine("Status= " + R.Status);
  689. }
  690. else if (MEMBER.Name == "seconds")
  691. {
  692. R.Seconds = (double)MEMBER.Data.Data;
  693. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  694. }
  695. else if (MEMBER.Name == "data")
  696. {
  697. if (MEMBER.Data is XmlRpcValueArray)
  698. {
  699. OSHConsole.WriteLine("Comments results:");
  700. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  701. foreach (IXmlRpcValue commentStruct in rarray.Values)
  702. {
  703. if (commentStruct == null) continue;
  704. if (!(commentStruct is XmlRpcValueStruct)) continue;
  705. GetCommentsResult result = new GetCommentsResult();
  706. foreach (XmlRpcStructMember commentmember in ((XmlRpcValueStruct)commentStruct).Members)
  707. {
  708. // To avoid errors of arranged info or missing ones, let's do it with switch..
  709. switch (commentmember.Name)
  710. {
  711. case "IDSubtitle": result.IDSubtitle = (string)commentmember.Data.Data; break;
  712. case "UserID": result.UserID = (string)commentmember.Data.Data; break;
  713. case "UserNickName": result.UserNickName = (string)commentmember.Data.Data; break;
  714. case "Comment": result.Comment = (string)commentmember.Data.Data; break;
  715. case "Created": result.Created = (string)commentmember.Data.Data; break;
  716. }
  717. }
  718. R.Results.Add(result);
  719. OSHConsole.WriteLine("> IDSubtitle= " + result.ToString());
  720. }
  721. }
  722. else// Unknown data ?
  723. {
  724. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  725. }
  726. }
  727. }
  728. // Return the response to user !!
  729. return R;
  730. }
  731. }
  732. }
  733. else
  734. {
  735. OSHConsole.WriteLine(response, DebugCode.Error);
  736. return new MethodResponseError("Fail", response);
  737. }
  738. return new MethodResponseError("Fail", "GetComments call failed !");
  739. }
  740. /// <summary>
  741. /// Schedule a periodical search for subtitles matching given video files, send results to user's e-mail address.
  742. /// </summary>
  743. /// <param name="languageIDS">The language 3 lenght ids array</param>
  744. /// <param name="movies">The movies parameters</param>
  745. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseSearchToMail'</returns>
  746. public static IMethodResponse SearchToMail(string[] languageIDS, SearchToMailMovieParameter[] movies)
  747. {
  748. if (TOKEN == "")
  749. {
  750. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  751. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  752. }
  753. // Method call ..
  754. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  755. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  756. // Array of sub langs
  757. XmlRpcValueArray a = new XmlRpcValueArray(languageIDS);
  758. parms.Add(a);
  759. // Array of video parameters
  760. a = new XmlRpcValueArray();
  761. foreach (SearchToMailMovieParameter p in movies)
  762. {
  763. XmlRpcValueStruct str = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  764. str.Members.Add(new XmlRpcStructMember("moviehash", new XmlRpcValueBasic(p.moviehash)));
  765. str.Members.Add(new XmlRpcStructMember("moviesize", new XmlRpcValueBasic(p.moviesize)));
  766. a.Values.Add(str);
  767. }
  768. parms.Add(a);
  769. XmlRpcMethodCall call = new XmlRpcMethodCall("SearchToMail", parms);
  770. OSHConsole.WriteLine("Sending SearchToMail request to the server ...", DebugCode.Good);
  771. // Send the request to the server
  772. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  773. if (!response.Contains("ERROR:"))
  774. {
  775. // No error occur, get and decode the response.
  776. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  777. if (calls.Length > 0)
  778. {
  779. if (calls[0].Parameters.Count > 0)
  780. {
  781. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  782. // Create the response, we'll need it later
  783. MethodResponseSearchToMail R = new MethodResponseSearchToMail();
  784. // To make sure response is not currepted by server, do it in loop
  785. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  786. {
  787. switch (MEMBER.Name)
  788. {
  789. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  790. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  791. }
  792. }
  793. // Return the response to user !!
  794. return R;
  795. }
  796. }
  797. }
  798. else
  799. {
  800. OSHConsole.WriteLine(response, DebugCode.Error);
  801. return new MethodResponseError("Fail", response);
  802. }
  803. return new MethodResponseError("Fail", "SearchToMail call failed !");
  804. }
  805. /*Movies*/
  806. /// <summary>
  807. /// Search for a movie (using movie title)
  808. /// </summary>
  809. /// <param name="query">Movie title user is searching for, this is cleaned-up a bit (remove dvdrip, etc.) before searching </param>
  810. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseSubtitleSearch'</returns>
  811. public static IMethodResponse SearchMoviesOnIMDB(string query)
  812. {
  813. if (TOKEN == "")
  814. {
  815. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  816. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  817. }
  818. // Method call ..
  819. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  820. // Add token param
  821. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  822. // Add query param
  823. parms.Add(new XmlRpcValueBasic(query, XmlRpcBasicValueType.String));
  824. // Call !
  825. XmlRpcMethodCall call = new XmlRpcMethodCall("SearchMoviesOnIMDB", parms);
  826. OSHConsole.WriteLine("Sending SearchMoviesOnIMDB request to the server ...", DebugCode.Good);
  827. // Send the request to the server
  828. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  829. if (!response.Contains("ERROR:"))
  830. {
  831. // No error occur, get and decode the response.
  832. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  833. if (calls.Length > 0)
  834. {
  835. if (calls[0].Parameters.Count > 0)
  836. {
  837. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  838. // Create the response, we'll need it later
  839. MethodResponseMovieSearch R = new MethodResponseMovieSearch();
  840. // To make sure response is not currepted by server, do it in loop
  841. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  842. {
  843. if (MEMBER.Name == "status")
  844. {
  845. R.Status = (string)MEMBER.Data.Data;
  846. OSHConsole.WriteLine("Status= " + R.Status);
  847. }
  848. else if (MEMBER.Name == "seconds")
  849. {
  850. R.Seconds = (double)MEMBER.Data.Data;
  851. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  852. }
  853. else if (MEMBER.Name == "data")
  854. {
  855. if (MEMBER.Data is XmlRpcValueArray)
  856. {
  857. OSHConsole.WriteLine("Search results:");
  858. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  859. foreach (IXmlRpcValue subStruct in rarray.Values)
  860. {
  861. if (subStruct == null) continue;
  862. if (!(subStruct is XmlRpcValueStruct)) continue;
  863. MovieSearchResult result = new MovieSearchResult();
  864. foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
  865. {
  866. // To avoid errors of arranged info or missing ones, let's do it with switch..
  867. switch (submember.Name)
  868. {
  869. case "id": result.ID = (string)submember.Data.Data; break;
  870. case "title": result.Title = (string)submember.Data.Data; break;
  871. }
  872. }
  873. R.Results.Add(result);
  874. OSHConsole.WriteLine(">" + result.ToString());
  875. }
  876. }
  877. else// Unknown data ?
  878. {
  879. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  880. }
  881. }
  882. }
  883. // Return the response to user !!
  884. return R;
  885. }
  886. }
  887. }
  888. else
  889. {
  890. OSHConsole.WriteLine(response, DebugCode.Error);
  891. return new MethodResponseError("Fail", response);
  892. }
  893. return new MethodResponseError("Fail", "SearchMoviesOnIMDB call failed !");
  894. }
  895. /// <summary>
  896. /// Get movie details for given IMDb ID
  897. /// </summary>
  898. /// <param name="imdbid">http://www.imdb.com/</param>
  899. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseMovieDetails'</returns>
  900. public static IMethodResponse GetIMDBMovieDetails(string imdbid)
  901. {
  902. if (TOKEN == "")
  903. {
  904. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  905. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  906. }
  907. // Method call ..
  908. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  909. // Add token param
  910. parms.Add(new XmlRpcValueBasic(TOKEN));
  911. // Add query param
  912. parms.Add(new XmlRpcValueBasic(imdbid));
  913. // Call !
  914. XmlRpcMethodCall call = new XmlRpcMethodCall("GetIMDBMovieDetails", parms);
  915. OSHConsole.WriteLine("Sending GetIMDBMovieDetails request to the server ...", DebugCode.Good);
  916. // Send the request to the server
  917. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  918. if (!response.Contains("ERROR:"))
  919. {
  920. // No error occur, get and decode the response.
  921. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  922. if (calls.Length > 0)
  923. {
  924. if (calls[0].Parameters.Count > 0)
  925. {
  926. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  927. // Create the response, we'll need it later
  928. MethodResponseMovieDetails R = new MethodResponseMovieDetails();
  929. // To make sure response is not currepted by server, do it in loop
  930. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  931. {
  932. if (MEMBER.Name == "status")
  933. {
  934. R.Status = (string)MEMBER.Data.Data;
  935. OSHConsole.WriteLine("Status= " + R.Status);
  936. }
  937. else if (MEMBER.Name == "seconds")
  938. {
  939. R.Seconds = (double)MEMBER.Data.Data;
  940. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  941. }
  942. else if (MEMBER.Name == "data")
  943. {
  944. // We expect struct with details...
  945. if (MEMBER.Data is XmlRpcValueStruct)
  946. {
  947. OSHConsole.WriteLine("Details result:");
  948. XmlRpcValueStruct detailsStruct = (XmlRpcValueStruct)MEMBER.Data;
  949. foreach (XmlRpcStructMember dmem in detailsStruct.Members)
  950. {
  951. switch (dmem.Name)
  952. {
  953. case "id": R.ID = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  954. case "title": R.Title = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  955. case "year": R.Year = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  956. case "cover": R.CoverLink = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  957. case "duration": R.Duration = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  958. case "tagline": R.Tagline = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  959. case "plot": R.Plot = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  960. case "goofs": R.Goofs = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  961. case "trivia": R.Trivia = dmem.Data.Data.ToString(); OSHConsole.WriteLine(">" + dmem.Name + "= " + dmem.Data.Data.ToString()); break;
  962. case "cast":
  963. // this is another struct with cast members...
  964. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  965. XmlRpcValueStruct castStruct = (XmlRpcValueStruct)dmem.Data;
  966. foreach (XmlRpcStructMember castMemeber in castStruct.Members)
  967. {
  968. R.Cast.Add(castMemeber.Data.Data.ToString());
  969. OSHConsole.WriteLine(" >" + castMemeber.Data.Data.ToString());
  970. }
  971. break;
  972. case "directors":
  973. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  974. // this is another struct with directors members...
  975. XmlRpcValueStruct directorsStruct = (XmlRpcValueStruct)dmem.Data;
  976. foreach (XmlRpcStructMember directorsMember in directorsStruct.Members)
  977. {
  978. R.Directors.Add(directorsMember.Data.Data.ToString());
  979. OSHConsole.WriteLine(" >" + directorsMember.Data.Data.ToString());
  980. }
  981. break;
  982. case "writers":
  983. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  984. // this is another struct with writers members...
  985. XmlRpcValueStruct writersStruct = (XmlRpcValueStruct)dmem.Data;
  986. foreach (XmlRpcStructMember writersMember in writersStruct.Members)
  987. {
  988. R.Writers.Add(writersMember.Data.Data.ToString());
  989. OSHConsole.WriteLine("+->" + writersMember.Data.Data.ToString());
  990. }
  991. break;
  992. case "awards":
  993. // this is an array of genres...
  994. XmlRpcValueArray awardsArray = (XmlRpcValueArray)dmem.Data;
  995. foreach (XmlRpcValueBasic award in awardsArray.Values)
  996. {
  997. R.Awards.Add(award.Data.ToString());
  998. OSHConsole.WriteLine(" >" + award.Data.ToString());
  999. }
  1000. break;
  1001. case "genres":
  1002. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  1003. // this is an array of genres...
  1004. XmlRpcValueArray genresArray = (XmlRpcValueArray)dmem.Data;
  1005. foreach (XmlRpcValueBasic genre in genresArray.Values)
  1006. {
  1007. R.Genres.Add(genre.Data.ToString());
  1008. OSHConsole.WriteLine(" >" + genre.Data.ToString());
  1009. }
  1010. break;
  1011. case "country":
  1012. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  1013. // this is an array of country...
  1014. XmlRpcValueArray countryArray = (XmlRpcValueArray)dmem.Data;
  1015. foreach (XmlRpcValueBasic country in countryArray.Values)
  1016. {
  1017. R.Country.Add(country.Data.ToString());
  1018. OSHConsole.WriteLine(" >" + country.Data.ToString());
  1019. }
  1020. break;
  1021. case "language":
  1022. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  1023. // this is an array of language...
  1024. XmlRpcValueArray languageArray = (XmlRpcValueArray)dmem.Data;
  1025. foreach (XmlRpcValueBasic language in languageArray.Values)
  1026. {
  1027. R.Language.Add(language.Data.ToString());
  1028. OSHConsole.WriteLine(" >" + language.Data.ToString());
  1029. }
  1030. break;
  1031. case "certification":
  1032. OSHConsole.WriteLine(">" + dmem.Name + "= ");
  1033. // this is an array of certification...
  1034. XmlRpcValueArray certificationArray = (XmlRpcValueArray)dmem.Data;
  1035. foreach (XmlRpcValueBasic certification in certificationArray.Values)
  1036. {
  1037. R.Certification.Add(certification.Data.ToString());
  1038. OSHConsole.WriteLine(" >" + certification.Data.ToString());
  1039. }
  1040. break;
  1041. }
  1042. }
  1043. }
  1044. else// Unknown data ?
  1045. {
  1046. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  1047. }
  1048. }
  1049. }
  1050. // Return the response to user !!
  1051. return R;
  1052. }
  1053. }
  1054. }
  1055. else
  1056. {
  1057. OSHConsole.WriteLine(response, DebugCode.Error);
  1058. return new MethodResponseError("Fail", response);
  1059. }
  1060. return new MethodResponseError("Fail", "GetIMDBMovieDetails call failed !");
  1061. }
  1062. /// <summary>
  1063. /// Allows registered users to insert new movies (not stored in IMDb) to the database.
  1064. /// </summary>
  1065. /// <param name="movieName">Movie title </param>
  1066. /// <param name="movieyear">Release year </param>
  1067. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseInsertMovie'</returns>
  1068. public static IMethodResponse InsertMovie(string movieName, string movieyear)
  1069. {
  1070. if (TOKEN == "")
  1071. {
  1072. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1073. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1074. }
  1075. // Method call ..
  1076. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1077. // Add token param
  1078. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1079. // Add movieinfo struct
  1080. XmlRpcValueStruct movieinfo = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1081. movieinfo.Members.Add(new XmlRpcStructMember("moviename", new XmlRpcValueBasic(movieName)));
  1082. movieinfo.Members.Add(new XmlRpcStructMember("movieyear", new XmlRpcValueBasic(movieyear)));
  1083. parms.Add(movieinfo);
  1084. // Call !
  1085. XmlRpcMethodCall call = new XmlRpcMethodCall("InsertMovie", parms);
  1086. OSHConsole.WriteLine("Sending InsertMovie request to the server ...", DebugCode.Good);
  1087. // Send the request to the server
  1088. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1089. if (!response.Contains("ERROR:"))
  1090. {
  1091. // No error occur, get and decode the response.
  1092. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1093. if (calls.Length > 0)
  1094. {
  1095. if (calls[0].Parameters.Count > 0)
  1096. {
  1097. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1098. // Create the response, we'll need it later
  1099. MethodResponseInsertMovie R = new MethodResponseInsertMovie();
  1100. // To make sure response is not currepted by server, do it in loop
  1101. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1102. {
  1103. if (MEMBER.Name == "status")
  1104. {
  1105. R.Status = (string)MEMBER.Data.Data;
  1106. OSHConsole.WriteLine("Status= " + R.Status);
  1107. }
  1108. else if (MEMBER.Name == "seconds")
  1109. {
  1110. R.Seconds = (double)MEMBER.Data.Data;
  1111. OSHConsole.WriteLine("Seconds= " + R.Seconds);
  1112. }
  1113. else if (MEMBER.Name == "id")
  1114. {
  1115. R.ID = (string)MEMBER.Data.Data;
  1116. OSHConsole.WriteLine("ID= " + R.Seconds);
  1117. }
  1118. }
  1119. // Return the response to user !!
  1120. return R;
  1121. }
  1122. }
  1123. }
  1124. else
  1125. {
  1126. OSHConsole.WriteLine(response, DebugCode.Error);
  1127. return new MethodResponseError("Fail", response);
  1128. }
  1129. return new MethodResponseError("Fail", "InsertMovie call failed !");
  1130. }
  1131. /// <summary>
  1132. /// Inserts or updates data to tables, which are used for CheckMovieHash() and !CheckMovieHash2().
  1133. /// </summary>
  1134. /// <param name="parameters">The parameters</param>
  1135. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseInsertMovieHash'</returns>
  1136. public static IMethodResponse InsertMovieHash(InsertMovieHashParameters[] parameters)
  1137. {
  1138. if (TOKEN == "")
  1139. {
  1140. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1141. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1142. }
  1143. // Method call ..
  1144. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1145. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1146. foreach (InsertMovieHashParameters p in parameters)
  1147. {
  1148. XmlRpcValueStruct pstruct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1149. pstruct.Members.Add(new XmlRpcStructMember("moviehash", new XmlRpcValueBasic(p.moviehash)));
  1150. pstruct.Members.Add(new XmlRpcStructMember("moviebytesize", new XmlRpcValueBasic(p.moviebytesize)));
  1151. pstruct.Members.Add(new XmlRpcStructMember("imdbid", new XmlRpcValueBasic(p.imdbid)));
  1152. pstruct.Members.Add(new XmlRpcStructMember("movietimems", new XmlRpcValueBasic(p.movietimems)));
  1153. pstruct.Members.Add(new XmlRpcStructMember("moviefps", new XmlRpcValueBasic(p.moviefps)));
  1154. pstruct.Members.Add(new XmlRpcStructMember("moviefilename", new XmlRpcValueBasic(p.moviefilename)));
  1155. parms.Add(pstruct);
  1156. }
  1157. XmlRpcMethodCall call = new XmlRpcMethodCall("InsertMovieHash", parms);
  1158. OSHConsole.WriteLine("Sending InsertMovieHash request to the server ...", DebugCode.Good);
  1159. // Send the request to the server
  1160. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1161. if (!response.Contains("ERROR:"))
  1162. {
  1163. // No error occur, get and decode the response.
  1164. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1165. if (calls.Length > 0)
  1166. {
  1167. if (calls[0].Parameters.Count > 0)
  1168. {
  1169. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1170. // Create the response, we'll need it later
  1171. MethodResponseInsertMovieHash R = new MethodResponseInsertMovieHash();
  1172. // To make sure response is not currepted by server, do it in loop
  1173. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1174. {
  1175. switch (MEMBER.Name)
  1176. {
  1177. case "status":
  1178. R.Status = (string)MEMBER.Data.Data;
  1179. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1180. break;
  1181. case "seconds":
  1182. R.Seconds = (double)MEMBER.Data.Data;
  1183. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1184. break;
  1185. case "data":
  1186. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  1187. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  1188. {
  1189. switch (dataMember.Name)
  1190. {
  1191. case "accepted_moviehashes":
  1192. XmlRpcValueArray mh = (XmlRpcValueArray)dataMember.Data;
  1193. foreach (IXmlRpcValue val in mh.Values)
  1194. {
  1195. if (val is XmlRpcValueBasic)
  1196. {
  1197. R.accepted_moviehashes.Add(val.Data.ToString());
  1198. }
  1199. }
  1200. break;
  1201. case "new_imdbs":
  1202. XmlRpcValueArray mi = (XmlRpcValueArray)dataMember.Data;
  1203. foreach (IXmlRpcValue val in mi.Values)
  1204. {
  1205. if (val is XmlRpcValueBasic)
  1206. {
  1207. R.new_imdbs.Add(val.Data.ToString());
  1208. }
  1209. }
  1210. break;
  1211. }
  1212. }
  1213. break;
  1214. }
  1215. }
  1216. // Return the response to user !!
  1217. return R;
  1218. }
  1219. }
  1220. }
  1221. else
  1222. {
  1223. OSHConsole.WriteLine(response, DebugCode.Error);
  1224. return new MethodResponseError("Fail", response);
  1225. }
  1226. return new MethodResponseError("Fail", "InsertMovieHash call failed !");
  1227. }
  1228. /*Reporting and rating*/
  1229. /// <summary>
  1230. /// Get basic server information and statistics
  1231. /// </summary>
  1232. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseServerInfo'</returns>
  1233. public static IMethodResponse ServerInfo()
  1234. {
  1235. if (TOKEN == "")
  1236. {
  1237. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1238. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1239. }
  1240. // Method call ..
  1241. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1242. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1243. parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT, XmlRpcBasicValueType.String));
  1244. XmlRpcMethodCall call = new XmlRpcMethodCall("ServerInfo", parms);
  1245. OSHConsole.WriteLine("Sending ServerInfo request to the server ...", DebugCode.Good);
  1246. // Send the request to the server
  1247. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1248. if (!response.Contains("ERROR:"))
  1249. {
  1250. // No error occur, get and decode the response.
  1251. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1252. if (calls.Length > 0)
  1253. {
  1254. if (calls[0].Parameters.Count > 0)
  1255. {
  1256. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1257. // Create the response, we'll need it later
  1258. MethodResponseServerInfo R = new MethodResponseServerInfo();
  1259. // To make sure response is not currepted by server, do it in loop
  1260. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1261. {
  1262. switch (MEMBER.Name)
  1263. {
  1264. case "status":
  1265. R.Status = (string)MEMBER.Data.Data;
  1266. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1267. break;
  1268. case "seconds":
  1269. R.Seconds = (double)MEMBER.Data.Data;
  1270. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1271. break;
  1272. case "xmlrpc_version":
  1273. R.xmlrpc_version = (string)MEMBER.Data.Data;
  1274. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1275. break;
  1276. case "xmlrpc_url":
  1277. R.xmlrpc_url = (string)MEMBER.Data.Data;
  1278. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1279. break;
  1280. case "application":
  1281. R.application = (string)MEMBER.Data.Data;
  1282. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1283. break;
  1284. case "contact":
  1285. R.contact = (string)MEMBER.Data.Data;
  1286. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1287. break;
  1288. case "website_url":
  1289. R.website_url = (string)MEMBER.Data.Data;
  1290. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1291. break;
  1292. case "users_online_total":
  1293. R.users_online_total = (int)MEMBER.Data.Data;
  1294. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1295. break;
  1296. case "users_online_program":
  1297. R.users_online_program = (int)MEMBER.Data.Data;
  1298. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1299. break;
  1300. case "users_loggedin":
  1301. R.users_loggedin = (int)MEMBER.Data.Data;
  1302. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1303. break;
  1304. case "users_max_alltime":
  1305. R.users_max_alltime = (string)MEMBER.Data.Data;
  1306. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1307. break;
  1308. case "users_registered":
  1309. R.users_registered = (string)MEMBER.Data.Data;
  1310. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1311. break;
  1312. case "subs_downloads":
  1313. R.subs_downloads = (string)MEMBER.Data.Data;
  1314. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1315. break;
  1316. case "subs_subtitle_files":
  1317. R.subs_subtitle_files = (string)MEMBER.Data.Data;
  1318. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1319. break;
  1320. case "movies_total":
  1321. R.movies_total = (string)MEMBER.Data.Data;
  1322. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1323. break;
  1324. case "movies_aka":
  1325. R.movies_aka = (string)MEMBER.Data.Data;
  1326. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1327. break;
  1328. case "total_subtitles_languages":
  1329. R.total_subtitles_languages = (string)MEMBER.Data.Data;
  1330. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1331. break;
  1332. case "last_update_strings":
  1333. //R.total_subtitles_languages = (string)MEMBER.Data.Data;
  1334. OSHConsole.WriteLine(">" + MEMBER.Name + ":");
  1335. XmlRpcValueStruct luStruct = (XmlRpcValueStruct)MEMBER.Data;
  1336. foreach (XmlRpcStructMember luMemeber in luStruct.Members)
  1337. {
  1338. R.last_update_strings.Add(luMemeber.Name + " [" + luMemeber.Data.Data.ToString() + "]");
  1339. OSHConsole.WriteLine(" >" + luMemeber.Name + "= " + luMemeber.Data.Data.ToString());
  1340. }
  1341. break;
  1342. }
  1343. }
  1344. // Return the response to user !!
  1345. return R;
  1346. }
  1347. }
  1348. }
  1349. else
  1350. {
  1351. OSHConsole.WriteLine(response, DebugCode.Error);
  1352. return new MethodResponseError("Fail", response);
  1353. }
  1354. return new MethodResponseError("Fail", "ServerInfo call failed !");
  1355. }
  1356. /// <summary>
  1357. /// Report wrong subtitle file <--> video file combination
  1358. /// </summary>
  1359. /// <param name="IDSubMovieFile">Identifier of the subtitle file <--> video file combination </param>
  1360. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseReportWrongMovieHash'</returns>
  1361. public static IMethodResponse ReportWrongMovieHash(string IDSubMovieFile)
  1362. {
  1363. if (TOKEN == "")
  1364. {
  1365. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1366. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1367. }
  1368. // Method call ..
  1369. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1370. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1371. parms.Add(new XmlRpcValueBasic(IDSubMovieFile, XmlRpcBasicValueType.String));
  1372. XmlRpcMethodCall call = new XmlRpcMethodCall("ReportWrongMovieHash", parms);
  1373. OSHConsole.WriteLine("Sending ReportWrongMovieHash request to the server ...", DebugCode.Good);
  1374. // Send the request to the server
  1375. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1376. if (!response.Contains("ERROR:"))
  1377. {
  1378. // No error occur, get and decode the response.
  1379. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1380. if (calls.Length > 0)
  1381. {
  1382. if (calls[0].Parameters.Count > 0)
  1383. {
  1384. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1385. // Create the response, we'll need it later
  1386. MethodResponseReportWrongMovieHash R = new MethodResponseReportWrongMovieHash();
  1387. // To make sure response is not currepted by server, do it in loop
  1388. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1389. {
  1390. switch (MEMBER.Name)
  1391. {
  1392. case "status":
  1393. R.Status = (string)MEMBER.Data.Data;
  1394. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1395. break;
  1396. case "seconds":
  1397. R.Seconds = (double)MEMBER.Data.Data;
  1398. OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
  1399. break;
  1400. }
  1401. }
  1402. // Return the response to user !!
  1403. return R;
  1404. }
  1405. }
  1406. }
  1407. else
  1408. {
  1409. OSHConsole.WriteLine(response, DebugCode.Error);
  1410. return new MethodResponseError("Fail", response);
  1411. }
  1412. return new MethodResponseError("Fail", "ReportWrongMovieHash call failed !");
  1413. }
  1414. /// <summary>
  1415. /// This method is needed to report bad movie hash for imdbid. This method should be used for correcting wrong entries,
  1416. /// when using CheckMovieHash2. Pass moviehash and moviebytesize for file, and imdbid as new, corrected one IMDBID
  1417. /// (id number without trailing zeroes). After some reports, moviehash will be linked to new imdbid.
  1418. /// </summary>
  1419. /// <param name="moviehash">The movie hash</param>
  1420. /// <param name="moviebytesize">The movie size in bytes</param>
  1421. /// <param name="imdbid">The movie imbid</param>
  1422. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseReportWrongImdbMovie'</returns>
  1423. public static IMethodResponse ReportWrongImdbMovie(string moviehash, string moviebytesize, string imdbid)
  1424. {
  1425. if (TOKEN == "")
  1426. {
  1427. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1428. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1429. }
  1430. // Method call ..
  1431. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1432. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1433. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1434. s.Members.Add(new XmlRpcStructMember("moviehash", new XmlRpcValueBasic(moviehash)));
  1435. s.Members.Add(new XmlRpcStructMember("moviebytesize", new XmlRpcValueBasic(moviebytesize)));
  1436. s.Members.Add(new XmlRpcStructMember("imdbid", new XmlRpcValueBasic(imdbid)));
  1437. parms.Add(s);
  1438. XmlRpcMethodCall call = new XmlRpcMethodCall("ReportWrongImdbMovie", parms);
  1439. OSHConsole.WriteLine("Sending ReportWrongImdbMovie request to the server ...", DebugCode.Good);
  1440. // Send the request to the server
  1441. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1442. if (!response.Contains("ERROR:"))
  1443. {
  1444. // No error occur, get and decode the response.
  1445. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1446. if (calls.Length > 0)
  1447. {
  1448. if (calls[0].Parameters.Count > 0)
  1449. {
  1450. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1451. // Create the response, we'll need it later
  1452. MethodResponseAddComment R = new MethodResponseAddComment();
  1453. // To make sure response is not currepted by server, do it in loop
  1454. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1455. {
  1456. switch (MEMBER.Name)
  1457. {
  1458. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1459. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1460. }
  1461. }
  1462. // Return the response to user !!
  1463. return R;
  1464. }
  1465. }
  1466. }
  1467. else
  1468. {
  1469. OSHConsole.WriteLine(response, DebugCode.Error);
  1470. return new MethodResponseError("Fail", response);
  1471. }
  1472. return new MethodResponseError("Fail", "ReportWrongImdbMovie call failed !");
  1473. }
  1474. /// <summary>
  1475. /// Rate subtitles
  1476. /// </summary>
  1477. /// <param name="idsubtitle">Id of subtitle (NOT subtitle file) user wants to rate </param>
  1478. /// <param name="score">Subtitle rating, must be in interval 1 (worst) to 10 (best). </param>
  1479. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseSubtitlesVote'</returns>
  1480. public static IMethodResponse SubtitlesVote(int idsubtitle, int score)
  1481. {
  1482. if (TOKEN == "")
  1483. {
  1484. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1485. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1486. }
  1487. // Method call ..
  1488. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1489. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1490. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1491. s.Members.Add(new XmlRpcStructMember("idsubtitle", new XmlRpcValueBasic(idsubtitle)));
  1492. s.Members.Add(new XmlRpcStructMember("score", new XmlRpcValueBasic(score)));
  1493. parms.Add(s);
  1494. XmlRpcMethodCall call = new XmlRpcMethodCall("SubtitlesVote", parms);
  1495. OSHConsole.WriteLine("Sending SubtitlesVote request to the server ...", DebugCode.Good);
  1496. // Send the request to the server
  1497. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1498. if (!response.Contains("ERROR:"))
  1499. {
  1500. // No error occur, get and decode the response.
  1501. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1502. if (calls.Length > 0)
  1503. {
  1504. if (calls[0].Parameters.Count > 0)
  1505. {
  1506. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1507. // Create the response, we'll need it later
  1508. MethodResponseSubtitlesVote R = new MethodResponseSubtitlesVote();
  1509. // To make sure response is not currepted by server, do it in loop
  1510. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1511. {
  1512. switch (MEMBER.Name)
  1513. {
  1514. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1515. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1516. case "data":
  1517. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  1518. foreach (XmlRpcStructMember dataMemeber in dataStruct.Members)
  1519. {
  1520. OSHConsole.WriteLine(" >" + dataMemeber.Name + "= " + dataMemeber.Data.Data.ToString());
  1521. switch (dataMemeber.Name)
  1522. {
  1523. case "SubRating": R.SubRating = dataMemeber.Data.Data.ToString(); break;
  1524. case "SubSumVotes": R.SubSumVotes = dataMemeber.Data.Data.ToString(); break;
  1525. case "IDSubtitle": R.IDSubtitle = dataMemeber.Data.Data.ToString(); break;
  1526. }
  1527. }
  1528. break;
  1529. }
  1530. }
  1531. // Return the response to user !!
  1532. return R;
  1533. }
  1534. }
  1535. }
  1536. else
  1537. {
  1538. OSHConsole.WriteLine(response, DebugCode.Error);
  1539. return new MethodResponseError("Fail", response);
  1540. }
  1541. return new MethodResponseError("Fail", "SubtitlesVote call failed !");
  1542. }
  1543. /// <summary>
  1544. /// Add comment to a subtitle
  1545. /// </summary>
  1546. /// <param name="idsubtitle">Subtitle identifier (BEWARE! this is not the ID of subtitle file but of the whole subtitle (a subtitle can contain multiple subtitle files))</param>
  1547. /// <param name="comment">User's comment</param>
  1548. /// <param name="badsubtitle">Optional parameter. If set to 1, subtitles are marked as bad.</param>
  1549. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseAddComment'</returns>
  1550. public static IMethodResponse AddComment(int idsubtitle, string comment, int badsubtitle)
  1551. {
  1552. if (TOKEN == "")
  1553. {
  1554. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1555. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1556. }
  1557. // Method call ..
  1558. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1559. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1560. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1561. s.Members.Add(new XmlRpcStructMember("idsubtitle", new XmlRpcValueBasic(idsubtitle)));
  1562. s.Members.Add(new XmlRpcStructMember("comment", new XmlRpcValueBasic(comment)));
  1563. s.Members.Add(new XmlRpcStructMember("badsubtitle", new XmlRpcValueBasic(badsubtitle)));
  1564. parms.Add(s);
  1565. XmlRpcMethodCall call = new XmlRpcMethodCall("AddComment", parms);
  1566. OSHConsole.WriteLine("Sending AddComment request to the server ...", DebugCode.Good);
  1567. // Send the request to the server
  1568. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1569. if (!response.Contains("ERROR:"))
  1570. {
  1571. // No error occur, get and decode the response.
  1572. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1573. if (calls.Length > 0)
  1574. {
  1575. if (calls[0].Parameters.Count > 0)
  1576. {
  1577. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1578. // Create the response, we'll need it later
  1579. MethodResponseAddComment R = new MethodResponseAddComment();
  1580. // To make sure response is not currepted by server, do it in loop
  1581. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1582. {
  1583. switch (MEMBER.Name)
  1584. {
  1585. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1586. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1587. }
  1588. }
  1589. // Return the response to user !!
  1590. return R;
  1591. }
  1592. }
  1593. }
  1594. else
  1595. {
  1596. OSHConsole.WriteLine(response, DebugCode.Error);
  1597. return new MethodResponseError("Fail", response);
  1598. }
  1599. return new MethodResponseError("Fail", "AddComment call failed !");
  1600. }
  1601. /// <summary>
  1602. /// Add new request for subtitles, user must be logged in
  1603. /// </summary>
  1604. /// <param name="sublanguageid">The subtitle language id 3 length</param>
  1605. /// <param name="idmovieimdb">http://www.imdb.com/</param>
  1606. /// <param name="comment">The comment</param>
  1607. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseAddRequest'</returns>
  1608. public static IMethodResponse AddRequest(string sublanguageid, string idmovieimdb, string comment)
  1609. {
  1610. if (TOKEN == "")
  1611. {
  1612. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1613. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1614. }
  1615. // Method call ..
  1616. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1617. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1618. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  1619. s.Members.Add(new XmlRpcStructMember("sublanguageid", new XmlRpcValueBasic(sublanguageid)));
  1620. s.Members.Add(new XmlRpcStructMember("idmovieimdb", new XmlRpcValueBasic(idmovieimdb)));
  1621. s.Members.Add(new XmlRpcStructMember("comment", new XmlRpcValueBasic(comment)));
  1622. parms.Add(s);
  1623. XmlRpcMethodCall call = new XmlRpcMethodCall("AddRequest", parms);
  1624. OSHConsole.WriteLine("Sending AddRequest request to the server ...", DebugCode.Good);
  1625. // Send the request to the server
  1626. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1627. if (!response.Contains("ERROR:"))
  1628. {
  1629. // No error occur, get and decode the response.
  1630. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1631. if (calls.Length > 0)
  1632. {
  1633. if (calls[0].Parameters.Count > 0)
  1634. {
  1635. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1636. // Create the response, we'll need it later
  1637. MethodResponseAddRequest R = new MethodResponseAddRequest();
  1638. // To make sure response is not currepted by server, do it in loop
  1639. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1640. {
  1641. switch (MEMBER.Name)
  1642. {
  1643. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1644. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1645. case "data":
  1646. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  1647. foreach (XmlRpcStructMember dataMemeber in dataStruct.Members)
  1648. {
  1649. switch (dataMemeber.Name)
  1650. {
  1651. case "request_url": R.request_url = dataMemeber.Data.Data.ToString(); OSHConsole.WriteLine(">" + dataMemeber.Name + "= " + dataMemeber.Data.Data.ToString()); break;
  1652. }
  1653. }
  1654. break;
  1655. }
  1656. }
  1657. // Return the response to user !!
  1658. return R;
  1659. }
  1660. }
  1661. }
  1662. else
  1663. {
  1664. OSHConsole.WriteLine(response, DebugCode.Error);
  1665. return new MethodResponseError("Fail", response);
  1666. }
  1667. return new MethodResponseError("Fail", "AddRequest call failed !");
  1668. }
  1669. /*User interface*/
  1670. /// <summary>
  1671. /// Get list of supported subtitle languages
  1672. /// </summary>
  1673. /// <param name="language">ISO639-1 2-letter language code of user's interface language. </param>
  1674. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseGetSubLanguages'</returns>
  1675. public static IMethodResponse GetSubLanguages(string language)
  1676. {
  1677. if (TOKEN == "")
  1678. {
  1679. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1680. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1681. }
  1682. // Method call ..
  1683. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1684. parms.Add(new XmlRpcValueBasic(TOKEN));
  1685. parms.Add(new XmlRpcValueBasic(language));
  1686. XmlRpcMethodCall call = new XmlRpcMethodCall("GetSubLanguages", parms);
  1687. OSHConsole.WriteLine("Sending GetSubLanguages request to the server ...", DebugCode.Good);
  1688. // Send the request to the server
  1689. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1690. if (!response.Contains("ERROR:"))
  1691. {
  1692. // No error occur, get and decode the response.
  1693. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1694. if (calls.Length > 0)
  1695. {
  1696. if (calls[0].Parameters.Count > 0)
  1697. {
  1698. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1699. // Create the response, we'll need it later
  1700. MethodResponseGetSubLanguages R = new MethodResponseGetSubLanguages();
  1701. // To make sure response is not currepted by server, do it in loop
  1702. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1703. {
  1704. switch (MEMBER.Name)
  1705. {
  1706. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1707. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1708. case "data":// array of structs
  1709. XmlRpcValueArray array = (XmlRpcValueArray)MEMBER.Data;
  1710. foreach (IXmlRpcValue value in array.Values)
  1711. {
  1712. if (value is XmlRpcValueStruct)
  1713. {
  1714. XmlRpcValueStruct valueStruct = (XmlRpcValueStruct)value;
  1715. SubtitleLanguage lang = new SubtitleLanguage();
  1716. OSHConsole.WriteLine(">SubLanguage:");
  1717. foreach (XmlRpcStructMember langMemeber in valueStruct.Members)
  1718. {
  1719. OSHConsole.WriteLine(" >" + langMemeber.Name + "= " + langMemeber.Data.Data.ToString());
  1720. switch (langMemeber.Name)
  1721. {
  1722. case "SubLanguageID": lang.SubLanguageID = langMemeber.Data.Data.ToString(); break;
  1723. case "LanguageName": lang.LanguageName = langMemeber.Data.Data.ToString(); break;
  1724. case "ISO639": lang.ISO639 = langMemeber.Data.Data.ToString(); break;
  1725. }
  1726. }
  1727. R.Languages.Add(lang);
  1728. }
  1729. else
  1730. {
  1731. OSHConsole.WriteLine(">" + MEMBER.Name + "= " +
  1732. MEMBER.Data.Data.ToString() + " [Struct expected !]", DebugCode.Warning);
  1733. }
  1734. }
  1735. break;
  1736. }
  1737. }
  1738. // Return the response to user !!
  1739. return R;
  1740. }
  1741. }
  1742. }
  1743. else
  1744. {
  1745. OSHConsole.WriteLine(response, DebugCode.Error);
  1746. return new MethodResponseError("Fail", response);
  1747. }
  1748. return new MethodResponseError("Fail", "GetSubLanguages call failed !");
  1749. }
  1750. /// <summary>
  1751. /// Detect language for given strings
  1752. /// </summary>
  1753. /// <param name="texts">Array of strings you want language detected for</param>
  1754. /// <param name="encodingUsed">The encoding that will be used to get buffer of given strings. (this is not OS official parameter)</param>
  1755. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseDetectLanguage'</returns>
  1756. public static IMethodResponse DetectLanguage(string[] texts, Encoding encodingUsed)
  1757. {
  1758. if (TOKEN == "")
  1759. {
  1760. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1761. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1762. }
  1763. // Method call ..
  1764. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1765. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  1766. // We need to gzip texts then code them with base 24
  1767. List<string> decodedTexts = new List<string>();
  1768. foreach (string text in texts)
  1769. {
  1770. // compress
  1771. Stream str = new MemoryStream();
  1772. byte[] stringData = encodingUsed.GetBytes(text);
  1773. str.Write(stringData, 0, stringData.Length);
  1774. str.Position = 0;
  1775. byte[] data = Utilities.Compress(str);
  1776. //base 64
  1777. decodedTexts.Add(Convert.ToBase64String(data));
  1778. }
  1779. parms.Add(new XmlRpcValueArray(decodedTexts.ToArray()));
  1780. XmlRpcMethodCall call = new XmlRpcMethodCall("DetectLanguage", parms);
  1781. OSHConsole.WriteLine("Sending DetectLanguage request to the server ...", DebugCode.Good);
  1782. // Send the request to the server
  1783. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1784. if (!response.Contains("ERROR:"))
  1785. {
  1786. // No error occur, get and decode the response.
  1787. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1788. if (calls.Length > 0)
  1789. {
  1790. if (calls[0].Parameters.Count > 0)
  1791. {
  1792. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1793. // Create the response, we'll need it later
  1794. MethodResponseDetectLanguage R = new MethodResponseDetectLanguage();
  1795. // To make sure response is not currepted by server, do it in loop
  1796. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1797. {
  1798. switch (MEMBER.Name)
  1799. {
  1800. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1801. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1802. case "data":
  1803. if (MEMBER.Data is XmlRpcValueStruct)
  1804. {
  1805. OSHConsole.WriteLine(">Languages:");
  1806. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  1807. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  1808. {
  1809. DetectLanguageResult lang = new DetectLanguageResult();
  1810. lang.InputSample = dataMember.Name;
  1811. lang.LanguageID = dataMember.Data.Data.ToString();
  1812. R.Results.Add(lang);
  1813. OSHConsole.WriteLine(" >" + dataMember.Name + " (" + dataMember.Data.Data.ToString() + ")");
  1814. }
  1815. }
  1816. else
  1817. {
  1818. OSHConsole.WriteLine(">Languages ?? Struct expected but server return another type!!", DebugCode.Warning);
  1819. }
  1820. break;
  1821. }
  1822. }
  1823. // Return the response to user !!
  1824. return R;
  1825. }
  1826. }
  1827. }
  1828. else
  1829. {
  1830. OSHConsole.WriteLine(response, DebugCode.Error);
  1831. return new MethodResponseError("Fail", response);
  1832. }
  1833. return new MethodResponseError("Fail", "DetectLanguage call failed !");
  1834. }
  1835. /// <summary>
  1836. /// Get available translations for given program
  1837. /// </summary>
  1838. /// <param name="program">Name of the program/client application you want translations for. Currently supported values: subdownloader, oscar</param>
  1839. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseGetAvailableTranslations'</returns>
  1840. public static IMethodResponse GetAvailableTranslations(string program)
  1841. {
  1842. if (TOKEN == "")
  1843. {
  1844. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1845. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1846. }
  1847. // Method call ..
  1848. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1849. parms.Add(new XmlRpcValueBasic(TOKEN));
  1850. parms.Add(new XmlRpcValueBasic(program));
  1851. XmlRpcMethodCall call = new XmlRpcMethodCall("GetAvailableTranslations", parms);
  1852. OSHConsole.WriteLine("Sending GetAvailableTranslations request to the server ...", DebugCode.Good);
  1853. // Send the request to the server
  1854. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1855. if (!response.Contains("ERROR:"))
  1856. {
  1857. // No error occur, get and decode the response.
  1858. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1859. if (calls.Length > 0)
  1860. {
  1861. if (calls[0].Parameters.Count > 0)
  1862. {
  1863. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1864. // Create the response, we'll need it later
  1865. MethodResponseGetAvailableTranslations R = new MethodResponseGetAvailableTranslations();
  1866. // To make sure response is not currepted by server, do it in loop
  1867. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1868. {
  1869. switch (MEMBER.Name)
  1870. {
  1871. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1872. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1873. case "data":
  1874. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  1875. OSHConsole.WriteLine(">data:");
  1876. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  1877. {
  1878. if (dataMember.Data is XmlRpcValueStruct)
  1879. {
  1880. XmlRpcValueStruct resStruct = (XmlRpcValueStruct)dataMember.Data;
  1881. GetAvailableTranslationsResult res = new GetAvailableTranslationsResult();
  1882. res.LanguageID = dataMember.Name;
  1883. OSHConsole.WriteLine(" >LanguageID: " + dataMember.Name);
  1884. foreach (XmlRpcStructMember resMember in resStruct.Members)
  1885. {
  1886. switch (resMember.Name)
  1887. {
  1888. case "LastCreated": res.LastCreated = resMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + resMember.Name + "= " + resMember.Data.Data.ToString()); break;
  1889. case "StringsNo": res.StringsNo = resMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + resMember.Name + "= " + resMember.Data.Data.ToString()); break;
  1890. }
  1891. R.Results.Add(res);
  1892. }
  1893. }
  1894. else
  1895. {
  1896. OSHConsole.WriteLine(" >Struct expected !!", DebugCode.Warning);
  1897. }
  1898. }
  1899. break;
  1900. }
  1901. }
  1902. // Return the response to user !!
  1903. return R;
  1904. }
  1905. }
  1906. }
  1907. else
  1908. {
  1909. OSHConsole.WriteLine(response, DebugCode.Error);
  1910. return new MethodResponseError("Fail", response);
  1911. }
  1912. return new MethodResponseError("Fail", "GetAvailableTranslations call failed !");
  1913. }
  1914. /// <summary>
  1915. /// Get a translation for given program and language
  1916. /// </summary>
  1917. /// <param name="iso639">language ​ISO639-1 2-letter code </param>
  1918. /// <param name="format">available formats: [gnugettext compatible: mo, po] and [additional: txt, xml]</param>
  1919. /// <param name="program">Name of the program/client application you want translations for. (currently supported values: subdownloader, oscar)</param>
  1920. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseGetTranslation'</returns>
  1921. public static IMethodResponse GetTranslation(string iso639, string format, string program)
  1922. {
  1923. if (TOKEN == "")
  1924. {
  1925. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1926. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1927. }
  1928. // Method call ..
  1929. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1930. parms.Add(new XmlRpcValueBasic(TOKEN));
  1931. parms.Add(new XmlRpcValueBasic(iso639));
  1932. parms.Add(new XmlRpcValueBasic(format));
  1933. parms.Add(new XmlRpcValueBasic(program));
  1934. XmlRpcMethodCall call = new XmlRpcMethodCall("GetTranslation", parms);
  1935. OSHConsole.WriteLine("Sending GetTranslation request to the server ...", DebugCode.Good);
  1936. // Send the request to the server
  1937. //File.WriteAllText(".\\REQUEST_GetTranslation.xml", Encoding.ASCII.GetString(XmlRpcGenerator.Generate(call)));
  1938. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1939. if (!response.Contains("ERROR:"))
  1940. {
  1941. // No error occur, get and decode the response.
  1942. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1943. if (calls.Length > 0)
  1944. {
  1945. if (calls[0].Parameters.Count > 0)
  1946. {
  1947. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  1948. // Create the response, we'll need it later
  1949. MethodResponseGetTranslation R = new MethodResponseGetTranslation();
  1950. // To make sure response is not currepted by server, do it in loop
  1951. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  1952. {
  1953. switch (MEMBER.Name)
  1954. {
  1955. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1956. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1957. case "data": R.ContentData = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  1958. }
  1959. }
  1960. // Return the response to user !!
  1961. return R;
  1962. }
  1963. }
  1964. }
  1965. else
  1966. {
  1967. OSHConsole.WriteLine(response, DebugCode.Error);
  1968. return new MethodResponseError("Fail", response);
  1969. }
  1970. return new MethodResponseError("Fail", "GetTranslation call failed !");
  1971. }
  1972. /// <summary>
  1973. /// Check for the latest version of given application
  1974. /// </summary>
  1975. /// <param name="program">name of the program/client application you want to check. (Currently supported values: subdownloader, oscar)</param>
  1976. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseAutoUpdate'</returns>
  1977. public static IMethodResponse AutoUpdate(string program)
  1978. {
  1979. /*if (TOKEN == "")
  1980. {
  1981. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  1982. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  1983. }*/
  1984. // Method call ..
  1985. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  1986. // parms.Add(new XmlRpcValueBasic(TOKEN));
  1987. parms.Add(new XmlRpcValueBasic(program));
  1988. // parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT));
  1989. XmlRpcMethodCall call = new XmlRpcMethodCall("AutoUpdate", parms);
  1990. OSHConsole.WriteLine("Sending AutoUpdate request to the server ...", DebugCode.Good);
  1991. // Send the request to the server
  1992. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  1993. if (!response.Contains("ERROR:"))
  1994. {
  1995. // No error occur, get and decode the response.
  1996. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  1997. if (calls.Length > 0)
  1998. {
  1999. if (calls[0].Parameters.Count > 0)
  2000. {
  2001. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2002. // Create the response, we'll need it later
  2003. MethodResponseAutoUpdate R = new MethodResponseAutoUpdate();
  2004. // To make sure response is not currepted by server, do it in loop
  2005. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2006. {
  2007. switch (MEMBER.Name)
  2008. {
  2009. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2010. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2011. case "version": R.version = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2012. case "url_windows": R.url_windows = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2013. case "url_linux": R.url_linux = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2014. case "comments": R.comments = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2015. }
  2016. }
  2017. // Return the response to user !!
  2018. return R;
  2019. }
  2020. }
  2021. }
  2022. else
  2023. {
  2024. OSHConsole.WriteLine(response, DebugCode.Error);
  2025. return new MethodResponseError("Fail", response);
  2026. }
  2027. return new MethodResponseError("Fail", "AutoUpdate call failed !");
  2028. }
  2029. /*Checking*/
  2030. /// <summary>
  2031. /// Check if video file hashes are already stored in the database
  2032. /// </summary>
  2033. /// <param name="hashes">Array of video file hashes</param>
  2034. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseCheckMovieHash'</returns>
  2035. public static IMethodResponse CheckMovieHash(string[] hashes)
  2036. {
  2037. if (TOKEN == "")
  2038. {
  2039. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  2040. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  2041. }
  2042. // Method call ..
  2043. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  2044. parms.Add(new XmlRpcValueBasic(TOKEN));
  2045. parms.Add(new XmlRpcValueArray(hashes));
  2046. XmlRpcMethodCall call = new XmlRpcMethodCall("CheckMovieHash", parms);
  2047. OSHConsole.WriteLine("Sending CheckMovieHash request to the server ...", DebugCode.Good);
  2048. // Send the request to the server
  2049. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  2050. if (!response.Contains("ERROR:"))
  2051. {
  2052. // No error occur, get and decode the response.
  2053. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  2054. if (calls.Length > 0)
  2055. {
  2056. if (calls[0].Parameters.Count > 0)
  2057. {
  2058. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2059. // Create the response, we'll need it later
  2060. MethodResponseCheckMovieHash R = new MethodResponseCheckMovieHash();
  2061. // To make sure response is not currepted by server, do it in loop
  2062. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2063. {
  2064. switch (MEMBER.Name)
  2065. {
  2066. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2067. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2068. case "data":
  2069. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  2070. OSHConsole.WriteLine(">Data:");
  2071. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  2072. {
  2073. CheckMovieHashResult res = new CheckMovieHashResult();
  2074. res.Name = dataMember.Name;
  2075. OSHConsole.WriteLine(" >" + res.Name + ":");
  2076. XmlRpcValueStruct movieStruct = (XmlRpcValueStruct)dataMember.Data;
  2077. foreach (XmlRpcStructMember movieMember in movieStruct.Members)
  2078. {
  2079. switch (movieMember.Name)
  2080. {
  2081. case "MovieHash": res.MovieHash = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2082. case "MovieImdbID": res.MovieImdbID = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2083. case "MovieName": res.MovieName = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2084. case "MovieYear": res.MovieYear = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2085. }
  2086. }
  2087. R.Results.Add(res);
  2088. }
  2089. break;
  2090. }
  2091. }
  2092. // Return the response to user !!
  2093. return R;
  2094. }
  2095. }
  2096. }
  2097. else
  2098. {
  2099. OSHConsole.WriteLine(response, DebugCode.Error);
  2100. return new MethodResponseError("Fail", response);
  2101. }
  2102. return new MethodResponseError("Fail", "CheckMovieHash call failed !");
  2103. }
  2104. /// <summary>
  2105. /// Check if video file hashes are already stored in the database. This method returns matching !MovieImdbID, MovieName, MovieYear, SeriesSeason, SeriesEpisode,
  2106. /// MovieKind if available for each $moviehash, always sorted by SeenCount DESC.
  2107. /// </summary>
  2108. /// <param name="hashes">Array of video file hashes</param>
  2109. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseCheckMovieHash2'</returns>
  2110. public static IMethodResponse CheckMovieHash2(string[] hashes)
  2111. {
  2112. if (TOKEN == "")
  2113. {
  2114. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  2115. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  2116. }
  2117. // Method call ..
  2118. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  2119. parms.Add(new XmlRpcValueBasic(TOKEN));
  2120. parms.Add(new XmlRpcValueArray(hashes));
  2121. XmlRpcMethodCall call = new XmlRpcMethodCall("CheckMovieHash2", parms);
  2122. OSHConsole.WriteLine("Sending CheckMovieHash2 request to the server ...", DebugCode.Good);
  2123. // Send the request to the server
  2124. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  2125. if (!response.Contains("ERROR:"))
  2126. {
  2127. // No error occur, get and decode the response.
  2128. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  2129. if (calls.Length > 0)
  2130. {
  2131. if (calls[0].Parameters.Count > 0)
  2132. {
  2133. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2134. // Create the response, we'll need it later
  2135. MethodResponseCheckMovieHash2 R = new MethodResponseCheckMovieHash2();
  2136. // To make sure response is not currepted by server, do it in loop
  2137. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2138. {
  2139. switch (MEMBER.Name)
  2140. {
  2141. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2142. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2143. case "data":
  2144. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  2145. OSHConsole.WriteLine(">Data:");
  2146. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  2147. {
  2148. CheckMovieHash2Result res = new CheckMovieHash2Result();
  2149. res.Name = dataMember.Name;
  2150. OSHConsole.WriteLine(" >" + res.Name + ":");
  2151. XmlRpcValueArray dataArray = (XmlRpcValueArray)dataMember.Data;
  2152. foreach (XmlRpcValueStruct movieStruct in dataArray.Values)
  2153. {
  2154. CheckMovieHash2Data d = new CheckMovieHash2Data();
  2155. foreach (XmlRpcStructMember movieMember in movieStruct.Members)
  2156. {
  2157. switch (movieMember.Name)
  2158. {
  2159. case "MovieHash": d.MovieHash = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2160. case "MovieImdbID": d.MovieImdbID = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2161. case "MovieName": d.MovieName = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2162. case "MovieYear": d.MovieYear = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2163. case "MovieKind": d.MovieKind = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2164. case "SeriesSeason": d.SeriesSeason = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2165. case "SeriesEpisode": d.SeriesEpisode = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2166. case "SeenCount": d.MovieYear = movieMember.Data.Data.ToString(); OSHConsole.WriteLine(" >" + movieMember.Name + "= " + movieMember.Data.Data.ToString()); break;
  2167. }
  2168. }
  2169. res.Items.Add(d);
  2170. }
  2171. R.Results.Add(res);
  2172. }
  2173. break;
  2174. }
  2175. }
  2176. // Return the response to user !!
  2177. return R;
  2178. }
  2179. }
  2180. }
  2181. else
  2182. {
  2183. OSHConsole.WriteLine(response, DebugCode.Error);
  2184. return new MethodResponseError("Fail", response);
  2185. }
  2186. return new MethodResponseError("Fail", "CheckMovieHash2 call failed !");
  2187. }
  2188. /// <summary>
  2189. /// Check if given subtitle files are already stored in the database
  2190. /// </summary>
  2191. /// <param name="hashes">Array of subtitle file hashes (MD5 hashes of subtitle file contents) </param>
  2192. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseCheckSubHash'</returns>
  2193. public static IMethodResponse CheckSubHash(string[] hashes)
  2194. {
  2195. if (TOKEN == "")
  2196. {
  2197. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  2198. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  2199. }
  2200. // Method call ..
  2201. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  2202. parms.Add(new XmlRpcValueBasic(TOKEN));
  2203. parms.Add(new XmlRpcValueArray(hashes));
  2204. XmlRpcMethodCall call = new XmlRpcMethodCall("CheckSubHash", parms);
  2205. OSHConsole.WriteLine("Sending CheckSubHash request to the server ...", DebugCode.Good);
  2206. // Send the request to the server
  2207. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  2208. if (!response.Contains("ERROR:"))
  2209. {
  2210. // No error occur, get and decode the response.
  2211. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  2212. if (calls.Length > 0)
  2213. {
  2214. if (calls[0].Parameters.Count > 0)
  2215. {
  2216. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2217. // Create the response, we'll need it later
  2218. MethodResponseCheckSubHash R = new MethodResponseCheckSubHash();
  2219. // To make sure response is not currepted by server, do it in loop
  2220. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2221. {
  2222. switch (MEMBER.Name)
  2223. {
  2224. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2225. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2226. case "data":
  2227. OSHConsole.WriteLine(">Data:");
  2228. XmlRpcValueStruct dataStruct = (XmlRpcValueStruct)MEMBER.Data;
  2229. foreach (XmlRpcStructMember dataMember in dataStruct.Members)
  2230. {
  2231. OSHConsole.WriteLine(" >" + dataMember.Name + "= " + dataMember.Data.Data.ToString());
  2232. CheckSubHashResult r = new CheckSubHashResult();
  2233. r.Hash = dataMember.Name;
  2234. r.SubID = dataMember.Data.Data.ToString();
  2235. R.Results.Add(r);
  2236. }
  2237. break;
  2238. }
  2239. }
  2240. // Return the response to user !!
  2241. return R;
  2242. }
  2243. }
  2244. }
  2245. else
  2246. {
  2247. OSHConsole.WriteLine(response, DebugCode.Error);
  2248. return new MethodResponseError("Fail", response);
  2249. }
  2250. return new MethodResponseError("Fail", "CheckSubHash call failed !");
  2251. }
  2252. /*Upload*/
  2253. /// <summary>
  2254. /// Try to upload subtitles, perform pre-upload checking (i.e. check if subtitles already exist on server)
  2255. /// </summary>
  2256. /// <param name="subs">The subtitle parameters collection to try to upload</param>
  2257. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseTryUploadSubtitles'</returns>
  2258. public static IMethodResponse TryUploadSubtitles(TryUploadSubtitlesParameters[] subs)
  2259. {
  2260. if (TOKEN == "")
  2261. {
  2262. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  2263. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  2264. }
  2265. // Method call ..
  2266. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  2267. parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
  2268. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  2269. int i = 1;
  2270. foreach (TryUploadSubtitlesParameters cd in subs)
  2271. {
  2272. XmlRpcStructMember member = new XmlRpcStructMember("cd" + i, null);
  2273. XmlRpcValueStruct memberStruct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  2274. memberStruct.Members.Add(new XmlRpcStructMember("subhash", new XmlRpcValueBasic(cd.subhash)));
  2275. memberStruct.Members.Add(new XmlRpcStructMember("subfilename", new XmlRpcValueBasic(cd.subfilename)));
  2276. memberStruct.Members.Add(new XmlRpcStructMember("moviehash", new XmlRpcValueBasic(cd.moviehash)));
  2277. memberStruct.Members.Add(new XmlRpcStructMember("moviebytesize", new XmlRpcValueBasic(cd.moviebytesize)));
  2278. memberStruct.Members.Add(new XmlRpcStructMember("moviefps", new XmlRpcValueBasic(cd.moviefps)));
  2279. memberStruct.Members.Add(new XmlRpcStructMember("movietimems", new XmlRpcValueBasic(cd.movietimems)));
  2280. memberStruct.Members.Add(new XmlRpcStructMember("movieframes", new XmlRpcValueBasic(cd.movieframes)));
  2281. memberStruct.Members.Add(new XmlRpcStructMember("moviefilename", new XmlRpcValueBasic(cd.moviefilename)));
  2282. member.Data = memberStruct;
  2283. s.Members.Add(member);
  2284. i++;
  2285. }
  2286. parms.Add(s);
  2287. XmlRpcMethodCall call = new XmlRpcMethodCall("TryUploadSubtitles", parms);
  2288. OSHConsole.WriteLine("Sending TryUploadSubtitles request to the server ...", DebugCode.Good);
  2289. // Send the request to the server
  2290. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  2291. if (!response.Contains("ERROR:"))
  2292. {
  2293. // No error occur, get and decode the response.
  2294. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  2295. if (calls.Length > 0)
  2296. {
  2297. if (calls[0].Parameters.Count > 0)
  2298. {
  2299. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2300. // Create the response, we'll need it later
  2301. MethodResponseTryUploadSubtitles R = new MethodResponseTryUploadSubtitles();
  2302. // To make sure response is not currepted by server, do it in loop
  2303. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2304. {
  2305. switch (MEMBER.Name)
  2306. {
  2307. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2308. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2309. case "alreadyindb": R.AlreadyInDB = (int)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2310. case "data":
  2311. if (MEMBER.Data is XmlRpcValueArray)
  2312. {
  2313. OSHConsole.WriteLine("Results: ");
  2314. XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
  2315. foreach (IXmlRpcValue subStruct in rarray.Values)
  2316. {
  2317. if (subStruct == null) continue;
  2318. if (!(subStruct is XmlRpcValueStruct)) continue;
  2319. SubtitleSearchResult result = new SubtitleSearchResult();
  2320. foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
  2321. {
  2322. // To avoid errors of arranged info or missing ones, let's do it with switch..
  2323. switch (submember.Name)
  2324. {
  2325. case "IDMovie": result.IDMovie = submember.Data.Data.ToString(); break;
  2326. case "IDMovieImdb": result.IDMovieImdb = submember.Data.Data.ToString(); break;
  2327. case "IDSubMovieFile": result.IDSubMovieFile = submember.Data.Data.ToString(); break;
  2328. case "IDSubtitle": result.IDSubtitle = submember.Data.Data.ToString(); break;
  2329. case "IDSubtitleFile": result.IDSubtitleFile = submember.Data.Data.ToString(); break;
  2330. case "ISO639": result.ISO639 = submember.Data.Data.ToString(); break;
  2331. case "LanguageName": result.LanguageName = submember.Data.Data.ToString(); break;
  2332. case "MovieByteSize": result.MovieByteSize = submember.Data.Data.ToString(); break;
  2333. case "MovieHash": result.MovieHash = submember.Data.Data.ToString(); break;
  2334. case "MovieImdbRating": result.MovieImdbRating = submember.Data.Data.ToString(); break;
  2335. case "MovieName": result.MovieName = submember.Data.Data.ToString(); break;
  2336. case "MovieNameEng": result.MovieNameEng = submember.Data.Data.ToString(); break;
  2337. case "MovieReleaseName": result.MovieReleaseName = submember.Data.Data.ToString(); break;
  2338. case "MovieTimeMS": result.MovieTimeMS = submember.Data.Data.ToString(); break;
  2339. case "MovieYear": result.MovieYear = submember.Data.Data.ToString(); break;
  2340. case "SubActualCD": result.SubActualCD = submember.Data.Data.ToString(); break;
  2341. case "SubAddDate": result.SubAddDate = submember.Data.Data.ToString(); break;
  2342. case "SubAuthorComment": result.SubAuthorComment = submember.Data.Data.ToString(); break;
  2343. case "SubBad": result.SubBad = submember.Data.Data.ToString(); break;
  2344. case "SubDownloadLink": result.SubDownloadLink = submember.Data.Data.ToString(); break;
  2345. case "SubDownloadsCnt": result.SubDownloadsCnt = submember.Data.Data.ToString(); break;
  2346. case "SubFileName": result.SubFileName = submember.Data.Data.ToString(); break;
  2347. case "SubFormat": result.SubFormat = submember.Data.Data.ToString(); break;
  2348. case "SubHash": result.SubHash = submember.Data.Data.ToString(); break;
  2349. case "SubLanguageID": result.SubLanguageID = submember.Data.Data.ToString(); break;
  2350. case "SubRating": result.SubRating = submember.Data.Data.ToString(); break;
  2351. case "SubSize": result.SubSize = submember.Data.Data.ToString(); break;
  2352. case "SubSumCD": result.SubSumCD = submember.Data.Data.ToString(); break;
  2353. case "UserID": result.UserID = submember.Data.Data.ToString(); break;
  2354. case "UserNickName": result.UserNickName = submember.Data.Data.ToString(); break;
  2355. case "ZipDownloadLink": result.ZipDownloadLink = submember.Data.Data.ToString(); break;
  2356. }
  2357. }
  2358. R.Results.Add(result);
  2359. OSHConsole.WriteLine(">" + result.ToString());
  2360. }
  2361. }
  2362. else// Unknown data ?
  2363. {
  2364. OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
  2365. }
  2366. break;
  2367. }
  2368. }
  2369. // Return the response to user !!
  2370. return R;
  2371. }
  2372. }
  2373. }
  2374. else
  2375. {
  2376. OSHConsole.WriteLine(response, DebugCode.Error);
  2377. return new MethodResponseError("Fail", response);
  2378. }
  2379. return new MethodResponseError("Fail", "TryUploadSubtitles call failed !");
  2380. }
  2381. /// <summary>
  2382. /// Upload given subtitles to OSDb server
  2383. /// </summary>
  2384. /// <param name="info">The pamaters of upload method</param>
  2385. /// <returns>Status of the call operation. If the call success the response will be 'MethodResponseUploadSubtitles'</returns>
  2386. public static IMethodResponse UploadSubtitles(UploadSubtitleInfoParameters info)
  2387. {
  2388. if (TOKEN == "")
  2389. {
  2390. OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
  2391. return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
  2392. }
  2393. // Method call ..
  2394. List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
  2395. parms.Add(new XmlRpcValueBasic(TOKEN));
  2396. // Main struct
  2397. XmlRpcValueStruct s = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  2398. // Base info member as struct
  2399. XmlRpcStructMember member = new XmlRpcStructMember("baseinfo", null);
  2400. XmlRpcValueStruct memberStruct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  2401. memberStruct.Members.Add(new XmlRpcStructMember("idmovieimdb", new XmlRpcValueBasic(info.idmovieimdb)));
  2402. memberStruct.Members.Add(new XmlRpcStructMember("sublanguageid", new XmlRpcValueBasic(info.sublanguageid)));
  2403. memberStruct.Members.Add(new XmlRpcStructMember("moviereleasename", new XmlRpcValueBasic(info.moviereleasename)));
  2404. memberStruct.Members.Add(new XmlRpcStructMember("movieaka", new XmlRpcValueBasic(info.movieaka)));
  2405. memberStruct.Members.Add(new XmlRpcStructMember("subauthorcomment", new XmlRpcValueBasic(info.subauthorcomment)));
  2406. // memberStruct.Members.Add(new XmlRpcStructMember("hearingimpaired", new XmlRpcValueBasic(info.hearingimpaired)));
  2407. // memberStruct.Members.Add(new XmlRpcStructMember("highdefinition", new XmlRpcValueBasic(info.highdefinition)));
  2408. // memberStruct.Members.Add(new XmlRpcStructMember("automatictranslation", new XmlRpcValueBasic(info.automatictranslation)));
  2409. member.Data = memberStruct;
  2410. s.Members.Add(member);
  2411. // CDS members
  2412. int i = 1;
  2413. foreach (UploadSubtitleParameters cd in info.CDS)
  2414. {
  2415. XmlRpcStructMember member2 = new XmlRpcStructMember("cd" + i, null);
  2416. XmlRpcValueStruct memberStruct2 = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
  2417. memberStruct2.Members.Add(new XmlRpcStructMember("subhash", new XmlRpcValueBasic(cd.subhash)));
  2418. memberStruct2.Members.Add(new XmlRpcStructMember("subfilename", new XmlRpcValueBasic(cd.subfilename)));
  2419. memberStruct2.Members.Add(new XmlRpcStructMember("moviehash", new XmlRpcValueBasic(cd.moviehash)));
  2420. memberStruct2.Members.Add(new XmlRpcStructMember("moviebytesize", new XmlRpcValueBasic(cd.moviebytesize)));
  2421. memberStruct2.Members.Add(new XmlRpcStructMember("moviefps", new XmlRpcValueBasic(cd.moviefps)));
  2422. memberStruct2.Members.Add(new XmlRpcStructMember("movietimems", new XmlRpcValueBasic(cd.movietimems)));
  2423. memberStruct2.Members.Add(new XmlRpcStructMember("movieframes", new XmlRpcValueBasic(cd.movieframes)));
  2424. memberStruct2.Members.Add(new XmlRpcStructMember("moviefilename", new XmlRpcValueBasic(cd.moviefilename)));
  2425. memberStruct2.Members.Add(new XmlRpcStructMember("subcontent", new XmlRpcValueBasic(cd.subcontent)));
  2426. member2.Data = memberStruct2;
  2427. s.Members.Add(member2);
  2428. i++;
  2429. }
  2430. // add main struct to parameters
  2431. parms.Add(s);
  2432. // add user agent
  2433. //parms.Add(new XmlRpcValueBasic(XML_PRC_USERAGENT));
  2434. XmlRpcMethodCall call = new XmlRpcMethodCall("UploadSubtitles", parms);
  2435. OSHConsole.WriteLine("Sending UploadSubtitles request to the server ...", DebugCode.Good);
  2436. // Send the request to the server
  2437. string response = Utilities.GetStreamString(Utilities.SendRequest(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT));
  2438. if (!response.Contains("ERROR:"))
  2439. {
  2440. // No error occur, get and decode the response.
  2441. XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
  2442. if (calls.Length > 0)
  2443. {
  2444. if (calls[0].Parameters.Count > 0)
  2445. {
  2446. XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
  2447. // Create the response, we'll need it later
  2448. MethodResponseUploadSubtitles R = new MethodResponseUploadSubtitles();
  2449. // To make sure response is not currepted by server, do it in loop
  2450. foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
  2451. {
  2452. switch (MEMBER.Name)
  2453. {
  2454. case "status": R.Status = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2455. case "seconds": R.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2456. case "data": R.Data = (string)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2457. case "subtitles": R.SubTitles = (bool)MEMBER.Data.Data; OSHConsole.WriteLine(">" + MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
  2458. }
  2459. }
  2460. // Return the response to user !!
  2461. return R;
  2462. }
  2463. }
  2464. }
  2465. else
  2466. {
  2467. OSHConsole.WriteLine(response, DebugCode.Error);
  2468. return new MethodResponseError("Fail", response);
  2469. }
  2470. return new MethodResponseError("Fail", "UploadSubtitles call failed !");
  2471. }
  2472. }
  2473. }