PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/0.14.x/src/MDownloader.WPF/Bootstrapper.cs

#
C# | 317 lines | 267 code | 50 blank | 0 comment | 4 complexity | da421439adff0f1386ddb39ac727c751 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Reflection;
  7. using System.Text;
  8. using Html.Downloader.Engine;
  9. using Html.Downloader.Engine.Classifying;
  10. using Html.Downloader.Engine.Configuring;
  11. using Html.Downloader.Engine.Impl;
  12. using MDownloader.Extensibility;
  13. using MDownloader.Hostings;
  14. using MDownloader.Hostings.Common;
  15. using MDownloader.Hostings.Core;
  16. using Melon.Commons.AutoUpdate;
  17. using Melon.Commons.AutoUpdate.CodePlex;
  18. using Melon.Commons.Configuration;
  19. using Melon.Commons.Configuration.Impl;
  20. using Melon.Commons.Configuration.Updates;
  21. using Melon.Commons.Diagnostics;
  22. using Melon.Commons.Diagnostics.Impl;
  23. using Melon.Commons.Diagnostics.Mantis;
  24. using Melon.Commons.Downloader;
  25. using Melon.Commons.Downloader.Captchas;
  26. using Melon.Commons.Downloader.Captchas.Ocr;
  27. using Melon.Commons.Downloader.Captchas.User;
  28. using Melon.Commons.Downloader.History;
  29. using Melon.Commons.IoC;
  30. using Melon.Commons.IoC.Impl;
  31. using Melon.Commons.Logging;
  32. using Melon.Commons.Logging.Impl;
  33. using Melon.Commons.Repository;
  34. using Melon.Commons.Repository.Impl;
  35. using Melon.Commons.Resources;
  36. using Melon.Commons.Resources.Embedded;
  37. namespace MDownloader.WPF
  38. {
  39. internal sealed class Bootstrapper : IServiceContainerBootstrapper
  40. {
  41. #region Constants
  42. private static string ApplicationDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"adma\MDownloader");
  43. private static RepositoryPointcut ConfigurationPointcut = new RepositoryPointcut("Configuration.xml");
  44. private static RepositoryPointcut HistoryPointcut = new RepositoryPointcut("History.xml");
  45. private static RepositoryPointcut Configuration_V1_V2 = new RepositoryPointcut("Configuration.V1.V2.xslt");
  46. private static RepositoryPointcut Configuration_V2_V3 = new RepositoryPointcut("Configuration.V2.V3.xslt");
  47. private static RepositoryPointcut Configuration_V3_V4 = new RepositoryPointcut("Configuration.V3.V4.xslt");
  48. private static RepositoryPointcut Configuration_V4_V5 = new RepositoryPointcut("Configuration.V4.V5.xslt");
  49. private static RepositoryPointcut Configuration_V5_V6 = new RepositoryPointcut("Configuration.V5.V6.xslt");
  50. private static RepositoryPointcut Configuration_V6_V7 = new RepositoryPointcut("Configuration.V6.V7.xslt");
  51. private static RepositoryPointcut Configuration_V7_V8 = new RepositoryPointcut("Configuration.V7.V8.xslt");
  52. #endregion
  53. #region IServiceContainerBootstrapper Members
  54. public IServiceContainer InitializeServiceContainer()
  55. {
  56. var container = new ServiceContainer();
  57. container.RegisterService(x => Bootstrapper.CreateRepositoryService());
  58. container.RegisterService(x => Bootstrapper.CreateResourceService());
  59. container.RegisterService(x => Bootstrapper.CreateApplicationInfoService());
  60. container.RegisterService(x => Bootstrapper.CreateLoggingService());
  61. container.RegisterService(x => Bootstrapper.CreateConfigurationService(x));
  62. container.RegisterService(x => Bootstrapper.CreateRecognitionService(x));
  63. container.RegisterService(x => Bootstrapper.CreateFileHostingService(x));
  64. container.RegisterService(x => Bootstrapper.CreateHistoryService(x));
  65. container.RegisterService(x => Bootstrapper.CreateAutoUpdateService(x));
  66. container.RegisterService(x => Bootstrapper.CreateFeedbackService());
  67. container.RegisterService(x => Bootstrapper.CreateClassificationService());
  68. container.RegisterService(x => Bootstrapper.CreateProxyService(x));
  69. container.RegisterService(x => Bootstrapper.CreateModuleService(x));
  70. container.RegisterService(x => Bootstrapper.CreateEngineService(x));
  71. ServicePointManager.DefaultConnectionLimit = 4;
  72. return container;
  73. }
  74. #endregion
  75. #region Private Members
  76. private static IApplicationInfoService CreateApplicationInfoService()
  77. {
  78. return new AssemblyApplicationInfoService(typeof(Bootstrapper).Assembly);
  79. }
  80. private static ILoggingManager CreateLoggingService()
  81. {
  82. return new InMemoryLoggingManager();
  83. }
  84. private static IConfigurationService<Configuration> CreateConfigurationService(IServiceContainer container)
  85. {
  86. var repository = container.GetService<IRepositoryService>();
  87. var assembly = new AssemblyRepositoryService(typeof(Bootstrapper).Assembly);
  88. var service = new FileBasedConfigurationService<Configuration>(repository, Bootstrapper.ConfigurationPointcut);
  89. service.SetDefaultVersion(1);
  90. service.SetCurrentVersion(8);
  91. service.AddUpdater(1, 2, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V1_V2)));
  92. service.AddUpdater(2, 3, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V2_V3)));
  93. service.AddUpdater(3, 4, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V3_V4)));
  94. service.AddUpdater(4, 5, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V4_V5)));
  95. service.AddUpdater(5, 6, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V5_V6)));
  96. service.AddUpdater(6, 7, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V6_V7)));
  97. service.AddUpdater(7, 8, new XsltUpdater(assembly.GetReadStream(Bootstrapper.Configuration_V7_V8)));
  98. return service;
  99. }
  100. private static IHostingsService CreateFileHostingService(IServiceContainer container)
  101. {
  102. var history = container.GetService<IHistoryService>();
  103. var logger = container.GetService<ILoggingManager>();
  104. var recognizer = container.GetService<IRecognitionPerformer>();
  105. var service = new HostingsService
  106. {
  107. CaptchaCallback = new CaptchaCallbackAdapter(recognizer)
  108. };
  109. service.Initialize(container);
  110. service.Downloaded += (sender, args) => history.Register(Constants.DownloadHistoryLineId, args.Bytes.ToString(), new HistoryTag(args.Provider.Id.ToString()), new HistoryTag(args.Target.Id.ToString()));
  111. service.Uploaded += (sender, args) => history.Register(Constants.UploadHistoryLineId, args.Bytes.ToString(), new HistoryTag(args.Provider.Id.ToString()), new HistoryTag(args.Target.Id.ToString()));
  112. service.WaitingStarted += (sender, args) => Bootstrapper.OnProviderWaitingStarted(logger, args);
  113. service.WaitingCompleted += (sender, args) => Bootstrapper.OnProviderWaitingCompleted(logger, args);
  114. service.CaptchaArrived += (sender, args) => Bootstrapper.OnCaptchaArrived(logger, args);
  115. service.CaptchaRecognized += (sender, args) => Bootstrapper.OnCaptchaRecognized(logger, args);
  116. return service;
  117. }
  118. private static IHistoryService CreateHistoryService(IServiceContainer container)
  119. {
  120. var repository = container.GetService<IRepositoryService>();
  121. var pointcut = Bootstrapper.HistoryPointcut;
  122. var serializer = new HistoryXmlSerializer();
  123. var service = new HistoryService(repository, pointcut, serializer);
  124. service.Create(Constants.DownloadHistoryLineId, "Downloaded bytes");
  125. service.Create(Constants.UploadHistoryLineId, "Uploaded bytes");
  126. return service;
  127. }
  128. public static IRecognitionPerformer CreateRecognitionService(IServiceContainer container)
  129. {
  130. var service = new RecognitionService();
  131. var control = container.GetComponent<IMultiCaptchaControl>(Constants.UserCaptchaRecognitionControl);
  132. var tessnet = AppDomain.CurrentDomain.BaseDirectory + "tessnet2_32.dll";
  133. if (File.Exists(tessnet))
  134. service.AddRecognizer(new OcrRecognizer());
  135. if (control != null)
  136. service.AddRecognizer(new UserRecognizer(control));
  137. return service;
  138. }
  139. private static IAutoUpdateService CreateAutoUpdateService(IServiceContainer container)
  140. {
  141. var info = container.GetService<IApplicationInfoService>();
  142. var current = info.GetVersion();
  143. var project = "mdownloader";
  144. return new CodePlexRssAutoUpdateService(project, current);
  145. }
  146. private static IRepositoryService CreateRepositoryService()
  147. {
  148. if (!Directory.Exists(Bootstrapper.ApplicationDataFolder))
  149. Directory.CreateDirectory(Bootstrapper.ApplicationDataFolder);
  150. return new FolderRepositoryService(Bootstrapper.ApplicationDataFolder);
  151. }
  152. private static IResourceService CreateResourceService()
  153. {
  154. return new EmbeddedResourceService(typeof(Bootstrapper).Assembly);
  155. }
  156. private static IFeedbackService CreateFeedbackService()
  157. {
  158. var server = @"http://adma.uuuq.com/mantis/api/soap/mantisconnect.php";
  159. return new MantisFeedbackService(server, String.Empty, String.Empty, "MDownloader");
  160. }
  161. private static IClassificationService CreateClassificationService()
  162. {
  163. return new ClassificationService();
  164. }
  165. private static IHostingProxyProvider CreateProxyService(IServiceContainer container)
  166. {
  167. var configuration = container.GetService<IConfigurationService<Configuration>>();
  168. return new HostingProxyProvider(configuration);
  169. }
  170. private static IModuleService CreateModuleService(IServiceContainer container)
  171. {
  172. var assembly = Assembly.Load("MDownloader.Extensibility.Modules");
  173. return new MDownloader.Extensibility.Core.ModuleService(assembly, container);
  174. }
  175. private static IEngineService CreateEngineService(IServiceContainer container)
  176. {
  177. var factory = new DownloaderFactory();
  178. var service = factory.Create(container);
  179. return service;
  180. }
  181. private static void OnProviderWaitingStarted(ILogger logger, WaitingEventArgs e)
  182. {
  183. var targetTag = new LogTag(e.Target.Id.ToString(), e.Target.Name);
  184. var providerTag = new LogTag(e.Provider.Id.ToString(), e.Provider.Name.ToString());
  185. var source = Constants.Hostings.Tag(targetTag, providerTag);
  186. var level = LogLevel.Info;
  187. var message = String.Format("Waiting {0} seconds...", e.Period.TotalSeconds);
  188. logger.Log(source, level, message);
  189. }
  190. private static void OnProviderWaitingCompleted(ILogger logger, WaitingEventArgs e)
  191. {
  192. var targetTag = new LogTag(e.Target.Id.ToString(), e.Target.Name);
  193. var providerTag = new LogTag(e.Provider.Id.ToString(), e.Provider.Name.ToString());
  194. var source = Constants.Hostings.Tag(targetTag, providerTag);
  195. var level = LogLevel.Info;
  196. var message = String.Format("Waiting {0} seconds completed.", e.Period.TotalSeconds);
  197. logger.Log(source, level, message);
  198. }
  199. private static void OnCaptchaArrived(ILogger logger, CaptchaEventArgs e)
  200. {
  201. var targetTag = new LogTag(e.Target.Id.ToString(), e.Target.Name);
  202. var providerTag = new LogTag(e.Provider.Id.ToString(), e.Provider.Name.ToString());
  203. var source = Constants.Hostings.Tag(targetTag, providerTag);
  204. var level = LogLevel.Info;
  205. var message = String.Format("Recognizing captcha...");
  206. var imageAttachment = new LogAttachment("Captcha", e.Image, "jpg");
  207. logger.Log(source, level, message, imageAttachment);
  208. }
  209. private static void OnCaptchaRecognized(ILogger logger, CaptchaEventArgs e)
  210. {
  211. var targetTag = new LogTag(e.Target.Id.ToString(), e.Target.Name);
  212. var providerTag = new LogTag(e.Provider.Id.ToString(), e.Provider.Name.ToString());
  213. var source = Constants.Hostings.Tag(targetTag, providerTag);
  214. var level = LogLevel.Info;
  215. var message = String.Format("Recognizing captcha completed; captcha='{0}'.", e.Text);
  216. var imageAttachment = new LogAttachment("Captcha", e.Image, "jpg");
  217. var textAttachment = new LogAttachment("Text", Encoding.UTF8.GetBytes(e.Text), "txt");
  218. logger.Log(source, level, message, imageAttachment, textAttachment);
  219. }
  220. #endregion
  221. private sealed class CaptchaCallbackAdapter : ICaptchaCallback
  222. {
  223. private sealed class RecognizerCallbackAdapter : IRecognitionCallback
  224. {
  225. #region Private Fields
  226. private readonly ICaptchaDescriptor descriptor;
  227. #endregion
  228. #region Constructors
  229. public RecognizerCallbackAdapter(ICaptchaDescriptor descriptor)
  230. {
  231. this.descriptor = descriptor;
  232. }
  233. #endregion
  234. #region IRecognitionCallback Members
  235. public char[] GetValidCharacters()
  236. {
  237. return this.descriptor.GetAvailableChars();
  238. }
  239. public byte[] Sharpen(byte[] data)
  240. {
  241. return this.descriptor.Sharpen(data);
  242. }
  243. public bool Verify(string text, double confidence)
  244. {
  245. return this.descriptor.Verify(text, confidence);
  246. }
  247. #endregion
  248. }
  249. #region Private Fields
  250. private readonly IRecognitionPerformer recognizer;
  251. #endregion
  252. #region Constructors
  253. public CaptchaCallbackAdapter(IRecognitionPerformer recognizer)
  254. {
  255. this.recognizer = recognizer;
  256. }
  257. #endregion
  258. #region ICaptchaCallback Members
  259. public string Recognize(bool auto, byte[] image, ICaptchaDescriptor descriptor)
  260. {
  261. var mode = auto ? RecognizerType.Quick : RecognizerType.All;
  262. return this.recognizer.Recognize(mode, image, new RecognizerCallbackAdapter(descriptor)).Text;
  263. }
  264. #endregion
  265. }
  266. }
  267. }