Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

338 lignes
9.9KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. using System.IO;
  6. using System.IO.Compression;
  7. using OpenQA.Selenium;
  8. using OpenQA.Selenium.Chrome;
  9. using OpenQA.Selenium.Support.UI;
  10. using CSVDownloader.Code;
  11. using CSVDownloader.Store.CreditCSVData;
  12. using CSVDownloader.Store.QRCSVData;
  13. using CSVDownloader.Store.ElectronicMoneyDataStore;
  14. using ExpectedConditions = OpenQA.Selenium.Support.UI.ExpectedConditions;
  15. namespace CSVDownloader.Web {
  16. abstract class WebController {
  17. protected log4net.ILog logger_ = log4net.LogManager.GetLogger("");
  18. protected ChromeDriver driver_;
  19. protected WebDriverWait wait_;
  20. private const int interval_milisec_ = 1000;
  21. protected CreditAgent agent_;
  22. /// <summary>
  23. /// 駐車場名とSpotIDのマッピング
  24. /// </summary>
  25. protected IDictionary<String, String> dic_;
  26. public WebController(ChromeDriver driver) {
  27. driver_ = driver;
  28. wait_ = new WebDriverWait(driver_, TimeSpan.FromSeconds(10));
  29. }
  30. public virtual void SetParkingDic(IDictionary<String, String> dic) {
  31. dic_ = dic;
  32. }
  33. public CreditAgent GetCreditAgent() {
  34. return agent_;
  35. }
  36. public string GetCreditAgentCode() {
  37. return CreditAgenciesMap.GetID(agent_);
  38. }
  39. abstract public ResultCode Login(LoginInfo login_info);
  40. abstract public ResultCode Download(DateTime from, DateTime to);
  41. abstract public ResultCode Logout();
  42. public ResultCode Archive(String archive_filename) {
  43. logger_.Info("アーカイブ開始");
  44. var dir_name = "archive";
  45. if (!Directory.Exists(dir_name)) {
  46. Directory.CreateDirectory(dir_name);
  47. }
  48. String target = @$"{dir_name}\{archive_filename}";
  49. logger_.Info($"{target}");
  50. if (System.IO.File.Exists(target)) {
  51. logger_.Info($"上書き:{target}");
  52. System.IO.File.Delete(target);
  53. }
  54. ZipFile.CreateFromDirectory("download", target);
  55. logger_.Info("アーカイブ終了");
  56. return ResultCode.OK;
  57. }
  58. public virtual List<CreditCSVData> GetCreditCSVDataList() {
  59. return new List<CreditCSVData>();
  60. }
  61. public virtual List<QRCSVData> GetQRCSVDataList() {
  62. return new List<QRCSVData>();
  63. }
  64. public virtual List<ElectronicMoneyCSVData> GetElectronicMoneyCSVDataList() {
  65. return new List<ElectronicMoneyCSVData>();
  66. }
  67. /// <summary>
  68. /// 実行対象日か判定する
  69. /// </summary>
  70. public virtual bool IsWorkDate() {
  71. return true;
  72. }
  73. protected void Click(String xpath, bool wait = true) {
  74. if (wait) {
  75. var ele = wait_.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpath)));
  76. ele.Click();
  77. } else {
  78. var ele = driver_.FindElementByXPath(xpath);
  79. ele.Click();
  80. }
  81. Console.WriteLine($"Click {xpath}");
  82. Wait(interval_milisec_);
  83. }
  84. protected void Click(IWebElement ele) {
  85. ele.Click();
  86. Wait(interval_milisec_);
  87. }
  88. protected void Send(String xpath, String value, bool enter = false) {
  89. var ele = wait_.Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));
  90. ele.SendKeys(value);
  91. if (enter) {
  92. ele.SendKeys(OpenQA.Selenium.Keys.Enter);
  93. }
  94. Wait(interval_milisec_);
  95. }
  96. protected void Clear(String xpath) {
  97. var ele = wait_.Until(ExpectedConditions.ElementExists(By.XPath(xpath)));
  98. ele.Clear();
  99. Wait(interval_milisec_);
  100. }
  101. protected void Select(String xpath, String value) {
  102. try {
  103. var ele = wait_.Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));
  104. var select = new SelectElement(ele);
  105. var options = select.Options;
  106. select.SelectByValue(value);
  107. Wait(interval_milisec_);
  108. } catch (Exception e) {
  109. Console.WriteLine($" Select failed xpath:{xpath} value:{value}");
  110. throw e;
  111. }
  112. }
  113. /// <summary>
  114. /// ダウンロードを開始したファイルを完了まで監視する
  115. /// 完了後はダウンロード完了ディレクトリに移動する
  116. /// </summary>
  117. /// <returns></returns>
  118. protected void WaitForDownload(String filename) {
  119. String tmpdownload_dir = DriverFactory.GetTmpDownloadDir();
  120. String download_dir = DriverFactory.GetDownloadDir();
  121. int limit_start = 0;
  122. long last_size = 0;
  123. String complete_filename = "";
  124. while (true) {
  125. var dir = new DirectoryInfo(tmpdownload_dir);
  126. var files = dir.GetFiles();
  127. if (files.Length != 0) {
  128. var file = files[0];
  129. if (file.Name.Contains(".crdownload") || file.Name.Contains(".tmp")) {
  130. // ダウンロード継続
  131. last_size = file.Length;
  132. logger_.Info($"ダウンロード監視中:{file.Name} size:{file.Length}");
  133. } else if (file.Length == last_size) {
  134. // ダウンロード完了
  135. logger_.Info($"ダウンロード完了:{file.Name} size:{file.Length}");
  136. complete_filename = file.Name;
  137. break;
  138. } else {
  139. // ダウンロード継続
  140. last_size = file.Length;
  141. logger_.Info($"ダウンロード監視中:{file.Name} size:{file.Length}");
  142. }
  143. } else {
  144. // ファイルが存在しない場合は、一定回数リトライし
  145. // 規定回数存在しない場合は失敗とする。
  146. if (10 < limit_start) {
  147. throw new Exception("ダウンロード開始失敗");
  148. }
  149. logger_.Info($"ダウンロード開始待ち");
  150. limit_start++;
  151. }
  152. Wait(500);
  153. }
  154. // ファイルの移動
  155. String source_filename = $@"{tmpdownload_dir}\{complete_filename}";
  156. String dest_filename = $@"{download_dir}\{filename}";
  157. System.IO.File.Move(source_filename, dest_filename, true);
  158. }
  159. protected void Wait(int milisec) {
  160. Thread.Sleep(milisec);
  161. }
  162. protected String GetSpotID(String parking_name) {
  163. if (!dic_.ContainsKey(parking_name)) {
  164. throw new ArgumentException();
  165. }
  166. return dic_[parking_name];
  167. }
  168. protected class CSVConfig {
  169. public bool header = false;
  170. public List<String> remove_char = new List<string>();
  171. }
  172. protected List<String[]> ReadCsv(String csvpath, CSVConfig config, Encoding enc) {
  173. var list = new List<String[]>();
  174. var fs = new FileStream(csvpath, FileMode.Open);
  175. var data = new byte[fs.Length];
  176. fs.Read(data, 0, data.Length);
  177. fs.Close();
  178. var content = enc.GetString(data);
  179. var lines = content.Split("\n");
  180. bool header_skip = config.header;
  181. foreach (var line in lines) {
  182. var tmpline = line;
  183. line.Trim();
  184. // 空の行はスキップ
  185. if (line.Length == 0) {
  186. continue;
  187. }
  188. // ヘッダー行のスキップ制御
  189. if (header_skip) {
  190. header_skip = false;
  191. continue;
  192. }
  193. // 囲み文字の削除
  194. if (config.remove_char != null) {
  195. foreach (var remove_char in config.remove_char) {
  196. tmpline = tmpline.Replace(remove_char, "");
  197. }
  198. }
  199. var values = tmpline.Split(",");
  200. var elements = new String[values.Length];
  201. int index = 0;
  202. foreach (var ele in values) {
  203. elements[index++] = ele.Trim();
  204. }
  205. list.Add(elements);
  206. }
  207. return list;
  208. }
  209. /// <summary>
  210. /// デフォルトのフレームにもどる
  211. /// </summary>
  212. protected void SwitchToFrame() {
  213. driver_.SwitchTo().DefaultContent();
  214. }
  215. /// <summary>
  216. /// フレームを切り替える。
  217. /// </summary>
  218. /// <param name="xpath"></param>
  219. protected void SwitchToFrame(String xpath) {
  220. var frame = wait_.Until(ExpectedConditions.ElementExists(By.XPath(xpath)));
  221. driver_.SwitchTo().Frame(frame);
  222. }
  223. /// <summary>
  224. /// 空の可能性があるソースをDateTimeへ変換する際、Null許容型として変換する。
  225. /// </summary>
  226. /// <param name="source"></param>
  227. /// <returns></returns>
  228. protected DateTime? GetDateTime(String source) {
  229. if (source != null && 0 < source.Length) {
  230. return DateTime.Parse(source);
  231. } else {
  232. return null;
  233. }
  234. }
  235. protected void CloseAlert() {
  236. try {
  237. var alert = wait_.Until(ExpectedConditions.AlertIsPresent());
  238. alert.Accept();
  239. } catch (Exception) {
  240. logger_.Info("アラート表示なし");
  241. return;
  242. }
  243. }
  244. }
  245. }