您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

388 行
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. try {
  65. conn_ = MySQL.GetConnection(mysql_param);
  66. parking_credit_card_agencies_spotID_dao_ = new ParkingCreditCardAgenciesSpotIDDAO(conn_);
  67. daito_credit_store_ = new DaitoCreitDataStore(conn_);
  68. zeus_credit_store_ = new ZeusCreditDataStore(conn_);
  69. itec_credit_store_ = new ItecCreditDataStore(conn_);
  70. hello_techno_credit_store_ = new HelloTechnoCreditDataStore(conn_);
  71. daito_qr_store_ = new DaitoQRDataStore(conn_);
  72. } catch (Exception e) {
  73. logger_.Error("DB接続失敗");
  74. logger_.Error(e.Message);
  75. return "DBへのコネクト失敗";
  76. }
  77. // サイトごとにコントローラーを用意する。
  78. MakeConttollers();
  79. // 各コントローラーを起動する。
  80. foreach (var web_controller in web_controller_list_) {
  81. var ret = HandleWebController(web_controller);
  82. if (ret == Code.ResultCode.NG) {
  83. logger_.Error($"処理失敗 {web_controller.GetCreditAgent().ToString()}");
  84. returnable = "処理失敗";
  85. }
  86. }
  87. // ブラウザの終了
  88. if (driver_ != null) {
  89. driver_.Quit();
  90. }
  91. // 終了
  92. logger_.Info("処理成功");
  93. return returnable;
  94. }
  95. private void MakeConttollers() {
  96. driver_ = DriverFactory.GetDriver();
  97. // CREVAS
  98. {
  99. var controller = new DaitoController(driver_);
  100. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  101. controller.SetParkingDic(dic);
  102. web_controller_list_.Add(controller);
  103. credit_datastore_map_.Add(controller.GetCreditAgent(), daito_credit_store_);
  104. qr_datastore_map_.Add(controller.GetCreditAgent(), daito_qr_store_);
  105. }
  106. // Zeus
  107. {
  108. var controller = new ZeusController(driver_);
  109. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  110. controller.SetParkingDic(dic);
  111. web_controller_list_.Add(controller);
  112. credit_datastore_map_.Add(controller.GetCreditAgent(), zeus_credit_store_);
  113. }
  114. // Itec
  115. {
  116. var controller = new ItecController(driver_);
  117. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  118. controller.SetParkingDic(dic);
  119. web_controller_list_.Add(controller);
  120. credit_datastore_map_.Add(controller.GetCreditAgent(), itec_credit_store_);
  121. }
  122. // HelloTechno
  123. {
  124. var controller = new HelloTechnoController(driver_);
  125. var dic = parking_credit_card_agencies_spotID_dao_.GetDictionary(controller.GetCreditAgent());
  126. controller.SetParkingDic(dic);
  127. web_controller_list_.Add(controller);
  128. credit_datastore_map_.Add(controller.GetCreditAgent(), hello_techno_credit_store_);
  129. }
  130. }
  131. private Code.ResultCode HandleWebController(WebController web_controller) {
  132. Code.ResultCode result_code = Code.ResultCode.OK;
  133. try {
  134. // 各ダウンロードディレクトリをクリーンする。
  135. CreanDirectries();
  136. // カード会社を特定する。
  137. Code.CreditAgent agent = web_controller.GetCreditAgent();
  138. logger_.Info($"ダウンロード開始 対象:{agent}");
  139. // 履歴を参照する。
  140. var history = history_dao_.GetHistory(agent);
  141. // 履歴から取得範囲を特定する。
  142. (var from, var to) = GetFromTo(agent, history);
  143. logger_.Info($"取得範囲 {from.ToString("yyyy/MM/dd")} ~ {to.ToString("yyyy/MM/dd")}");
  144. // ログイン情報を取得
  145. var login_info = GetLoginInfo(agent);
  146. // ログインを開始
  147. result_code = web_controller.Login(login_info);
  148. if (result_code != Code.ResultCode.OK) {
  149. throw new Exception("ログイン失敗");
  150. }
  151. logger_.Info("ログイン成功");
  152. // ダウンロード開始
  153. result_code = web_controller.Download(from, to);
  154. if (result_code != Code.ResultCode.OK) {
  155. throw new Exception("ダウンロード失敗");
  156. }
  157. logger_.Info("ダウンロード成功");
  158. // ログアウト
  159. result_code = web_controller.Logout();
  160. if (result_code != Code.ResultCode.OK) {
  161. throw new Exception("ログアウト失敗");
  162. }
  163. logger_.Info("ログアウト成功");
  164. // データ保存
  165. int delete_count_credit = 0;
  166. int delete_count_qr = 0;
  167. transaction_ = conn_.BeginTransaction();
  168. // ロード画面の表示
  169. var load_html_path = Path.GetFullPath(@"static\html\load.html");
  170. driver_.Navigate().GoToUrl($"file://{load_html_path}");
  171. // データリストの取得
  172. var credit_info_list = web_controller.GetCreditCSVDataList();
  173. var qr_info_list = web_controller.GetQRCSVDataList();
  174. // クレジット
  175. if (0 < credit_info_list.Count) {
  176. ShowTotalCount(credit_info_list.Count);
  177. var store = credit_datastore_map_[agent];
  178. delete_count_credit = store.Delete(from, to);
  179. var current_count = 0;
  180. ShowCurrentCount(current_count);
  181. var chunk_data_list = credit_info_list.Select((CreditCSVData data, int index) => new { data, index })
  182. .GroupBy(x => x.index / save_chunk_num_)
  183. .Select(g => g.Select(r => r.data));
  184. foreach (var data_list in chunk_data_list) {
  185. var list = data_list.ToList();
  186. store.Save(list);
  187. current_count += list.Count;
  188. ShowCurrentCount(current_count);
  189. }
  190. }
  191. // QR
  192. if (0 < qr_info_list.Count) {
  193. ShowTotalCount(qr_info_list.Count);
  194. var store = qr_datastore_map_[agent];
  195. delete_count_qr = store.Delete(from, to);
  196. var current_count = 0;
  197. ShowCurrentCount(current_count);
  198. var chunk_data_list = qr_info_list.Select((QRCSVData data, int index) => new { data, index })
  199. .GroupBy(x => x.index / save_chunk_num_)
  200. .Select(g => g.Select(r => r.data));
  201. foreach (var data_list in chunk_data_list) {
  202. var list = data_list.ToList();
  203. store.Save(list);
  204. current_count += list.Count;
  205. ShowCurrentCount(current_count);
  206. }
  207. }
  208. // コミット処理
  209. transaction_.Commit();
  210. logger_.Info($"削除件数 CREDIT:{delete_count_credit}");
  211. logger_.Info($"削除件数 QR: {delete_count_qr}");
  212. logger_.Info($"登録件数 CREDIT:{credit_info_list.Count}");
  213. logger_.Info($"登録件数 QR :{qr_info_list.Count}");
  214. web_controller.Archive(GetArchiveFilename(agent, DateTime.Now));
  215. // 履歴の登録
  216. history_dao_.Save(agent, DateTime.Now);
  217. logger_.Info($"ダウンロード終了 対象:{agent}");
  218. } catch (Exception e) {
  219. // ロールバック処理
  220. logger_.Error(e.Message);
  221. if (transaction_ != null) {
  222. transaction_.Rollback();
  223. }
  224. transaction_ = null;
  225. return Code.ResultCode.NG;
  226. }
  227. transaction_ = null;
  228. return Code.ResultCode.OK;
  229. }
  230. /// <summary>
  231. /// データ取得範囲を特定する。<br/>
  232. /// </summary>
  233. /// <param name="history"></param>
  234. /// <returns></returns>
  235. private (DateTime, DateTime) GetFromTo(Code.CreditAgent agent, List<History> history) {
  236. DateTime from, to;
  237. if (agent == Code.CreditAgent.Zeus) {
  238. // Zeusの場合は、データが修正されるケースがあるため
  239. // 期間を制御する
  240. // 前回取得日から1か月遡る。
  241. // var prev_date = DateTime.Now.AddMonths(-1);
  242. // from = new DateTime(prev_date.Year, prev_date.Month, 1);
  243. // to = from.AddMonths(1).AddDays(-1);
  244. var now_date = DateTime.Now.Date;
  245. from = now_date.AddMonths(-1);
  246. to = now_date;
  247. } else {
  248. var now_date = DateTime.Now.Date;
  249. from = now_date.AddDays(-20);
  250. to = now_date;
  251. if (history.Count != 0) {
  252. var prev_date = history[0].date;
  253. if (from < prev_date) {
  254. from = prev_date.Date;
  255. }
  256. }
  257. }
  258. return (from, to);
  259. }
  260. /// <summary>
  261. /// コンフィグファイルよりログイン情報を取得する。
  262. /// </summary>
  263. /// <param name="agent"></param>
  264. /// <returns></returns>
  265. private LoginInfo GetLoginInfo(Code.CreditAgent agent) {
  266. var login_info = new LoginInfo();
  267. String sesction = $"LOGIN_INFO_{agent.ToString()}";
  268. login_info.user_name = config_.Read(sesction, "user");
  269. if (login_info.user_name.Length == 0) {
  270. throw new Exception($"ログイン情報不足 host {agent.ToString()}");
  271. }
  272. login_info.password = config_.Read(sesction, "password");
  273. if (login_info.password.Length == 0) {
  274. throw new Exception($"ログイン情報不足 password {agent.ToString()}");
  275. }
  276. return login_info;
  277. }
  278. private String GetArchiveFilename(Code.CreditAgent agent, DateTime now) {
  279. return $"{agent}_{now.ToString("yyyyMMddHHmmss")}.zip";
  280. }
  281. private void CreanDirectries() {
  282. var dir_download = new DirectoryInfo(DriverFactory.GetDownloadDir());
  283. foreach (var file in dir_download.GetFiles()) {
  284. file.Delete();
  285. }
  286. var tmp_download = new DirectoryInfo(DriverFactory.GetTmpDownloadDir());
  287. foreach (var file in tmp_download.GetFiles()) {
  288. file.Delete();
  289. }
  290. }
  291. private void ShowTotalCount(int num) {
  292. driver_.ExecuteScript($"setTotal({num})");
  293. }
  294. private void ShowCurrentCount(int num) {
  295. driver_.ExecuteScript($"setCount({num})");
  296. }
  297. }
  298. }