using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.IO.Compression;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using CSVDownloader.Code;
using CSVDownloader.Store.CreditCSVData;
using CSVDownloader.Store.QRCSVData;
using CSVDownloader.Store.ElectronicMoneyDataStore;
using ExpectedConditions = OpenQA.Selenium.Support.UI.ExpectedConditions;
namespace CSVDownloader.Web {
abstract class WebController {
protected log4net.ILog logger_ = log4net.LogManager.GetLogger("");
protected ChromeDriver driver_;
protected WebDriverWait wait_;
private const int interval_milisec_ = 1000;
protected CreditAgent agent_;
///
/// 駐車場名とSpotIDのマッピング
///
protected IDictionary dic_;
public WebController(ChromeDriver driver) {
driver_ = driver;
wait_ = new WebDriverWait(driver_, TimeSpan.FromSeconds(10));
}
public virtual void SetParkingDic(IDictionary dic) {
dic_ = dic;
}
public CreditAgent GetCreditAgent() {
return agent_;
}
abstract public ResultCode Login(LoginInfo login_info);
abstract public ResultCode Download(DateTime from, DateTime to);
abstract public ResultCode Logout();
public ResultCode Archive(String archive_filename) {
logger_.Info("アーカイブ開始");
var dir_name = "archive";
if (!Directory.Exists(dir_name)) {
Directory.CreateDirectory(dir_name);
}
String target = @$"{dir_name}\{archive_filename}";
logger_.Info($"{target}");
if (System.IO.File.Exists(target)) {
logger_.Info($"上書き:{target}");
System.IO.File.Delete(target);
}
ZipFile.CreateFromDirectory("download", target);
logger_.Info("アーカイブ終了");
return ResultCode.OK;
}
public virtual List GetCreditCSVDataList() {
return new List();
}
public virtual List GetQRCSVDataList() {
return new List();
}
public virtual List GetElectronicMoneyCSVDataList() {
return new List();
}
protected void Click(String xpath, bool wait = true) {
if (wait) {
var ele = wait_.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpath)));
ele.Click();
} else {
var ele = driver_.FindElementByXPath(xpath);
ele.Click();
}
Console.WriteLine($"Click {xpath}");
Wait(interval_milisec_);
}
protected void Click(IWebElement ele) {
ele.Click();
Wait(interval_milisec_);
}
protected void Send(String xpath, String value, bool enter = false) {
var ele = wait_.Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));
ele.SendKeys(value);
if (enter) {
ele.SendKeys(OpenQA.Selenium.Keys.Enter);
}
Wait(interval_milisec_);
}
protected void Clear(String xpath) {
var ele = wait_.Until(ExpectedConditions.ElementExists(By.XPath(xpath)));
ele.Clear();
Wait(interval_milisec_);
}
protected void Select(String xpath, String value) {
try {
var ele = wait_.Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));
var select = new SelectElement(ele);
var options = select.Options;
select.SelectByValue(value);
Wait(interval_milisec_);
} catch (Exception e) {
Console.WriteLine($" Select failed xpath:{xpath} value:{value}");
throw e;
}
}
///
/// ダウンロードを開始したファイルを完了まで監視する
/// 完了後はダウンロード完了ディレクトリに移動する
///
///
protected void WaitForDownload(String filename) {
String tmpdownload_dir = DriverFactory.GetTmpDownloadDir();
String download_dir = DriverFactory.GetDownloadDir();
int limit_start = 0;
long last_size = 0;
String complete_filename = "";
while (true) {
var dir = new DirectoryInfo(tmpdownload_dir);
var files = dir.GetFiles();
if (files.Length != 0) {
var file = files[0];
if (file.Name.Contains(".crdownload") || file.Name.Contains(".tmp")) {
// ダウンロード継続
last_size = file.Length;
logger_.Info($"ダウンロード監視中:{file.Name} size:{file.Length}");
} else if (file.Length == last_size) {
// ダウンロード完了
logger_.Info($"ダウンロード完了:{file.Name} size:{file.Length}");
complete_filename = file.Name;
break;
} else {
// ダウンロード継続
last_size = file.Length;
logger_.Info($"ダウンロード監視中:{file.Name} size:{file.Length}");
}
} else {
// ファイルが存在しない場合は、一定回数リトライし
// 規定回数存在しない場合は失敗とする。
if (10 < limit_start) {
throw new Exception("ダウンロード開始失敗");
}
logger_.Info($"ダウンロード開始待ち");
limit_start++;
}
Wait(500);
}
// ファイルの移動
String source_filename = $@"{tmpdownload_dir}\{complete_filename}";
String dest_filename = $@"{download_dir}\{filename}";
System.IO.File.Move(source_filename, dest_filename, true);
}
protected void Wait(int milisec) {
Thread.Sleep(milisec);
}
protected String GetSpotID(String parking_name) {
if (!dic_.ContainsKey(parking_name)) {
throw new ArgumentException();
}
return dic_[parking_name];
}
protected class CSVConfig {
public bool header = false;
public List remove_char = new List();
}
protected List ReadCsv(String csvpath, CSVConfig config, Encoding enc) {
var list = new List();
var fs = new FileStream(csvpath, FileMode.Open);
var data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();
var content = enc.GetString(data);
var lines = content.Split("\n");
bool header_skip = config.header;
foreach (var line in lines) {
var tmpline = line;
line.Trim();
// 空の行はスキップ
if (line.Length == 0) {
continue;
}
// ヘッダー行のスキップ制御
if (header_skip) {
header_skip = false;
continue;
}
// 囲み文字の削除
if (config.remove_char != null) {
foreach (var remove_char in config.remove_char) {
tmpline = tmpline.Replace(remove_char, "");
}
}
var values = tmpline.Split(",");
var elements = new String[values.Length];
int index = 0;
foreach (var ele in values) {
elements[index++] = ele.Trim();
}
list.Add(elements);
}
return list;
}
///
/// デフォルトのフレームにもどる
///
protected void SwitchToFrame() {
driver_.SwitchTo().DefaultContent();
}
///
/// フレームを切り替える。
///
///
protected void SwitchToFrame(String xpath) {
var frame = wait_.Until(ExpectedConditions.ElementExists(By.XPath(xpath)));
driver_.SwitchTo().Frame(frame);
}
///
/// 空の可能性があるソースをDateTimeへ変換する際、Null許容型として変換する。
///
///
///
protected DateTime? GetDateTime(String source) {
if (source != null && 0 < source.Length) {
return DateTime.Parse(source);
} else {
return null;
}
}
protected void CloseAlert() {
try {
var alert = wait_.Until(ExpectedConditions.AlertIsPresent());
alert.Accept();
} catch (Exception) {
logger_.Info("アラート表示なし");
return;
}
}
}
}