Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

395 linhas
14KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Reflection;
  5. using System.Linq;
  6. using OpenQA.Selenium;
  7. using OpenQA.Selenium.Chrome;
  8. using OpenQA.Selenium.Support.UI;
  9. using SeleniumExtras.WaitHelpers;
  10. using CSVDownloader.File;
  11. using CSVDownloader.Store;
  12. using CSVDownloader.Store.CreditCSVData;
  13. using CSVDownloader.Store.QRCSVData;
  14. using CSVDownloader.Web;
  15. using MySql.Data.MySqlClient;
  16. namespace CSVDownloader {
  17. class Program {
  18. static void Main(string[] args) {
  19. // 作業ディレクトリを実行ファイルに合わせる。
  20. var exe_path = Assembly.GetEntryAssembly().Location;
  21. var exe_directory_path = Path.GetDirectoryName(exe_path);
  22. Directory.SetCurrentDirectory(exe_directory_path);
  23. var controller = new Controller();
  24. String ret = controller.Start();
  25. if (ret.Length != 0) {
  26. // エラー検知
  27. Console.WriteLine(ret);
  28. Console.WriteLine("エラー発生 詳細はログを参照");
  29. Environment.Exit(1);
  30. }
  31. }
  32. }
  33. class Controller {
  34. private log4net.ILog logger_ = log4net.LogManager.GetLogger("");
  35. private List<WebController> web_controller_list_ = new List<WebController>();
  36. private HistoryDAO history_dao_;
  37. private ParkingCreditCardAgenciesSpotIDDAO parking_credit_card_agencies_spotID_dao_;
  38. private DaitoCreitDataStore daito_credit_store_;
  39. private ZeusCreditDataStore zeus_credit_store_;
  40. private ItecCreditDataStore itec_credit_store_;
  41. private HelloTechnoCreditDataStore hello_techno_credit_store_;
  42. private DaitoQRDataStore daito_qr_store_;
  43. private IConfigReader config_;
  44. private ChromeDriver driver_;
  45. private MySqlConnection conn_;
  46. private MySqlTransaction transaction_;
  47. private Dictionary<Code.CreditAgent, CreditCSVDataStore> credit_datastore_map_ = new Dictionary<Code.CreditAgent, CreditCSVDataStore>();
  48. private Dictionary<Code.CreditAgent, QRCSVDataStore> qr_datastore_map_ = new Dictionary<Code.CreditAgent, QRCSVDataStore>();
  49. private int save_chunk_num_ = 100;
  50. public String Start() {
  51. Console.WriteLine("★★★★★★自動CSVダウンロード 起動★★★★★");
  52. logger_.Info("★★★★★★自動CSVダウンロード 起動★★★★★");
  53. String returnable = "";
  54. // 各種ストアを用意
  55. history_dao_ = new HistoryDAO();
  56. config_ = new ConfigReader("config/config.ini");
  57. var mysql_param = new MySqlConnectionParameter() {
  58. host = "192.168.0.28",
  59. port = 3306,
  60. database = "ypark",
  61. user = "ypuser2",
  62. password = "ypp@ssw0rd2"
  63. };
  64. //var mysql_param = new MySqlConnectionParameter() {
  65. // host = "localhost",
  66. // port = 3306,
  67. // database = "yp",
  68. // user = "docker",
  69. // password = "docker",
  70. //};
  71. try {
  72. conn_ = MySQL.GetConnection(mysql_param);
  73. parking_credit_card_agencies_spotID_dao_ = new ParkingCreditCardAgenciesSpotIDDAO(conn_);
  74. daito_credit_store_ = new DaitoCreitDataStore(conn_);
  75. zeus_credit_store_ = new ZeusCreditDataStore(conn_);
  76. itec_credit_store_ = new ItecCreditDataStore(conn_);
  77. hello_techno_credit_store_ = new HelloTechnoCreditDataStore(conn_);
  78. daito_qr_store_ = new DaitoQRDataStore(conn_);
  79. } catch (Exception e) {
  80. logger_.Error("DB接続失敗");
  81. logger_.Error(e.Message);
  82. return "DBへのコネクト失敗";
  83. }
  84. // サイトごとにコントローラーを用意する。
  85. MakeConttollers();
  86. // 各コントローラーを起動する。
  87. foreach (var web_controller in web_controller_list_) {
  88. var ret = HandleWebController(web_controller);
  89. if (ret == Code.ResultCode.NG) {
  90. logger_.Error($"処理失敗 {web_controller.GetCreditAgent().ToString()}");
  91. returnable = "処理失敗";
  92. }
  93. }
  94. // ブラウザの終了
  95. if (driver_ != null) {
  96. driver_.Quit();
  97. }
  98. // 終了
  99. logger_.Info("処理成功");
  100. return returnable;
  101. }
  102. private void MakeConttollers() {
  103. driver_ = DriverFactory.GetDriver();
  104. // CREVAS
  105. {
  106. var controller = new DaitoController(driver_);
  107. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  108. controller.SetParkingDic(dic);
  109. web_controller_list_.Add(controller);
  110. credit_datastore_map_.Add(controller.GetCreditAgent(), daito_credit_store_);
  111. qr_datastore_map_.Add(controller.GetCreditAgent(), daito_qr_store_);
  112. }
  113. // Zeus
  114. {
  115. var controller = new ZeusController(driver_);
  116. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  117. controller.SetParkingDic(dic);
  118. web_controller_list_.Add(controller);
  119. credit_datastore_map_.Add(controller.GetCreditAgent(), zeus_credit_store_);
  120. }
  121. // Itec
  122. {
  123. var controller = new ItecController(driver_);
  124. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  125. controller.SetParkingDic(dic);
  126. web_controller_list_.Add(controller);
  127. credit_datastore_map_.Add(controller.GetCreditAgent(), itec_credit_store_);
  128. }
  129. // HelloTechno
  130. {
  131. var controller = new HelloTechnoController(driver_);
  132. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  133. controller.SetParkingDic(dic);
  134. web_controller_list_.Add(controller);
  135. credit_datastore_map_.Add(controller.GetCreditAgent(), hello_techno_credit_store_);
  136. }
  137. }
  138. private Code.ResultCode HandleWebController(WebController web_controller) {
  139. Code.ResultCode result_code = Code.ResultCode.OK;
  140. try {
  141. // 各ダウンロードディレクトリをクリーンする。
  142. CreanDirectries();
  143. // カード会社を特定する。
  144. Code.CreditAgent agent = web_controller.GetCreditAgent();
  145. logger_.Info($"ダウンロード開始 対象:{agent}");
  146. // 履歴を参照する。
  147. var history = history_dao_.GetHistory(agent);
  148. // 履歴から取得範囲を特定する。
  149. (var from, var to) = GetFromTo(agent, history);
  150. logger_.Info($"取得範囲 {from.ToString("yyyy/MM/dd")} ~ {to.ToString("yyyy/MM/dd")}");
  151. // ログイン情報を取得
  152. var login_info = GetLoginInfo(agent);
  153. // ログインを開始
  154. result_code = web_controller.Login(login_info);
  155. if (result_code != Code.ResultCode.OK) {
  156. throw new Exception("ログイン失敗");
  157. }
  158. logger_.Info("ログイン成功");
  159. // ダウンロード開始
  160. result_code = web_controller.Download(from, to);
  161. if (result_code != Code.ResultCode.OK) {
  162. throw new Exception("ダウンロード失敗");
  163. }
  164. logger_.Info("ダウンロード成功");
  165. // ログアウト
  166. result_code = web_controller.Logout();
  167. if (result_code != Code.ResultCode.OK) {
  168. throw new Exception("ログアウト失敗");
  169. }
  170. logger_.Info("ログアウト成功");
  171. // データ保存
  172. int delete_count_credit = 0;
  173. int delete_count_qr = 0;
  174. transaction_ = conn_.BeginTransaction();
  175. // ロード画面の表示
  176. var load_html_path = Path.GetFullPath(@"static\html\load.html");
  177. driver_.Navigate().GoToUrl($"file://{load_html_path}");
  178. // データリストの取得
  179. var credit_info_list = web_controller.GetCreditCSVDataList();
  180. var qr_info_list = web_controller.GetQRCSVDataList();
  181. // クレジット
  182. if (0 < credit_info_list.Count) {
  183. ShowTotalCount(credit_info_list.Count);
  184. var store = credit_datastore_map_[agent];
  185. delete_count_credit = store.Delete(from, to);
  186. var current_count = 0;
  187. ShowCurrentCount(current_count);
  188. var chunk_data_list = credit_info_list.Select((CreditCSVData data, int index) => new { data, index })
  189. .GroupBy(x => x.index / save_chunk_num_)
  190. .Select(g => g.Select(r => r.data));
  191. foreach (var data_list in chunk_data_list) {
  192. var list = data_list.ToList();
  193. store.Save(list);
  194. current_count += list.Count;
  195. ShowCurrentCount(current_count);
  196. }
  197. }
  198. // QR
  199. if (0 < qr_info_list.Count) {
  200. ShowTotalCount(qr_info_list.Count);
  201. var store = qr_datastore_map_[agent];
  202. delete_count_qr = store.Delete(from, to);
  203. var current_count = 0;
  204. ShowCurrentCount(current_count);
  205. var chunk_data_list = qr_info_list.Select((QRCSVData data, int index) => new { data, index })
  206. .GroupBy(x => x.index / save_chunk_num_)
  207. .Select(g => g.Select(r => r.data));
  208. foreach (var data_list in chunk_data_list) {
  209. var list = data_list.ToList();
  210. store.Save(list);
  211. current_count += list.Count;
  212. ShowCurrentCount(current_count);
  213. }
  214. }
  215. // コミット処理
  216. transaction_.Commit();
  217. logger_.Info($"削除件数 CREDIT:{delete_count_credit}");
  218. logger_.Info($"削除件数 QR: {delete_count_qr}");
  219. logger_.Info($"登録件数 CREDIT:{credit_info_list.Count}");
  220. logger_.Info($"登録件数 QR :{qr_info_list.Count}");
  221. web_controller.Archive(GetArchiveFilename(agent, DateTime.Now));
  222. // 履歴の登録
  223. history_dao_.Save(agent, DateTime.Now);
  224. logger_.Info($"ダウンロード終了 対象:{agent}");
  225. } catch (Exception e) {
  226. // ロールバック処理
  227. logger_.Error(e.Message);
  228. if (transaction_ != null) {
  229. transaction_.Rollback();
  230. }
  231. transaction_ = null;
  232. return Code.ResultCode.NG;
  233. }
  234. transaction_ = null;
  235. return Code.ResultCode.OK;
  236. }
  237. /// <summary>
  238. /// データ取得範囲を特定する。<br/>
  239. /// </summary>
  240. /// <param name="history"></param>
  241. /// <returns></returns>
  242. private (DateTime, DateTime) GetFromTo(Code.CreditAgent agent, List<History> history) {
  243. DateTime from, to;
  244. if (agent == Code.CreditAgent.Zeus) {
  245. // Zeusの場合は、データが修正されるケースがあるため
  246. // 期間を制御する
  247. // 前回取得日から1か月遡る。
  248. // var prev_date = DateTime.Now.AddMonths(-1);
  249. // from = new DateTime(prev_date.Year, prev_date.Month, 1);
  250. // to = from.AddMonths(1).AddDays(-1);
  251. var now_date = DateTime.Now.Date;
  252. from = now_date.AddMonths(-1);
  253. to = now_date;
  254. } else {
  255. var now_date = DateTime.Now.Date;
  256. from = now_date.AddDays(-20);
  257. to = now_date;
  258. if (history.Count != 0) {
  259. var prev_date = history[0].date;
  260. if (from < prev_date) {
  261. from = prev_date.Date;
  262. }
  263. }
  264. }
  265. return (from, to);
  266. }
  267. /// <summary>
  268. /// コンフィグファイルよりログイン情報を取得する。
  269. /// </summary>
  270. /// <param name="agent"></param>
  271. /// <returns></returns>
  272. private LoginInfo GetLoginInfo(Code.CreditAgent agent) {
  273. var login_info = new LoginInfo();
  274. String sesction = $"LOGIN_INFO_{agent.ToString()}";
  275. login_info.user_name = config_.Read(sesction, "user");
  276. if (login_info.user_name.Length == 0) {
  277. throw new Exception($"ログイン情報不足 host {agent.ToString()}");
  278. }
  279. login_info.password = config_.Read(sesction, "password");
  280. if (login_info.password.Length == 0) {
  281. throw new Exception($"ログイン情報不足 password {agent.ToString()}");
  282. }
  283. return login_info;
  284. }
  285. private String GetArchiveFilename(Code.CreditAgent agent, DateTime now) {
  286. return $"{agent}_{now.ToString("yyyyMMddHHmmss")}.zip";
  287. }
  288. private void CreanDirectries() {
  289. var dir_download = new DirectoryInfo(DriverFactory.GetDownloadDir());
  290. foreach (var file in dir_download.GetFiles()) {
  291. file.Delete();
  292. }
  293. var tmp_download = new DirectoryInfo(DriverFactory.GetTmpDownloadDir());
  294. foreach (var file in tmp_download.GetFiles()) {
  295. file.Delete();
  296. }
  297. }
  298. private void ShowTotalCount(int num) {
  299. driver_.ExecuteScript($"setTotal({num})");
  300. }
  301. private void ShowCurrentCount(int num) {
  302. driver_.ExecuteScript($"setCount({num})");
  303. }
  304. }
  305. }