/// <summary> /// 部分別PV取得 /// </summary> /// <param name="title"></param> /// <param name="daily"></param> public void AnalyzePartPv(DB.Title title, DB.DailyScore daily) { AnalyzingLockContext(() => { if ((daily == null) || (daily.PageView == 0) || (daily.Series == 1)) { return; //見るまでもないやつ(PV=0または1話しかない) } if (daily.PartPvChecked) { return; //取得済みならもうしない } var waitFor = LastKasasagiDate.AddSeconds(KasasagiIntervalSec); var waitMsec = (waitFor - DateTime.Now).TotalMilliseconds; if (waitMsec > 0) { DebugReport.Log(this, $"kasasagi wait {waitMsec}"); System.Threading.Thread.Sleep((int)waitMsec); } var narou = new NarouAPI(); var useKasasagi = narou.GetPartPvData(title, daily); if (useKasasagi) { LastKasasagiDate = DateTime.Now; } }); }
static void Main() { bool update = false; foreach (var arg in Environment.GetCommandLineArgs()) { if (arg == "-update") { update = true; } } if (update) { DebugReport.LogArrival += (s, a) => { using (var f = System.IO.File.AppendText("log.txt")) { f.WriteLine(a.Message); } }; DebugReport.Log(null, "CUI Update Start."); var analyzer = new Analyzer(); analyzer.UpdateAllStoredUser(); DebugReport.Log(null, "CUI Update End."); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new NPVAMain()); } }
/// <summary> /// ぶっ壊れキャッシュ(準備中の物)を削除 /// </summary> /// <returns></returns> /// <remarks> /// メンテナンス用。通常はぶっ壊れキャッシュは保存もされないが、Kasasagi仕様変更でぶっ壊れ判定に失敗した後などに使う。 /// </remarks> public void DeleteAllInvalidCache() { foreach (var file in Directory.GetFiles("cache")) { var txt = File.ReadAllText(file); if (txt.Contains(PreparingMarker)) { File.Delete(file); DebugReport.Log(this, $"delete invalid cache {file}"); } } }
/// <summary> /// 現在のデータをセーブ /// </summary> public void Save() { lock (lockObj) { var path = Path.Combine(StoragePath, $"{authorInfo.ID}.xml"); if (!Directory.Exists(StoragePath)) { DebugReport.Log(this, $"DB folder Created {path}"); Directory.CreateDirectory(StoragePath); } authorInfo.Save(path); DebugReport.Log(this, $"Author DB wrote {path}"); } }
/// <summary> /// PVデータ取り込み(タイトル・月指定) /// </summary> /// <param name="title"></param> /// <param name="year"></param> /// <param name="month"></param> public void GetPVData(DB.Title title, int year, int month, bool useCache) { AnalyzingLockContext(() => { var waitFor = LastKasasagiDate.AddSeconds(KasasagiIntervalSec); var waitMsec = (waitFor - DateTime.Now).TotalMilliseconds; if (waitMsec > 0) { DebugReport.Log(this, $"kasasagi wait {waitMsec}"); System.Threading.Thread.Sleep((int)waitMsec); } var narou = new NarouAPI(); var useKasasagi = narou.UpdatePVData(title, year, month, useCache); if (useKasasagi) { LastKasasagiDate = DateTime.Now; } }); }
/// <summary> /// Yamlの作品情報を作品情報オブジェクトに変換 /// </summary> /// <param name="node"></param> /// <returns>作品情報オブジェクト</returns> private DB.Title YamlMapToTitleObj(YamlMappingNode node) { if (node == null) { return(null); } var t = new DB.Title { ID = GetStringFromYamlMap(node, "ncode"), Name = GetStringFromYamlMap(node, "title"), Author = GetStringFromYamlMap(node, "writer"), FirstUp = GetDateFromYamlMap(node, "general_firstup"), LastUp = GetDateFromYamlMap(node, "general_lastup"), LastCheck = DateTime.Now }; var score = new DB.DailyScore { Series = GetIntFromYamlMap(node, "general_all_no"), Size = GetIntFromYamlMap(node, "length"), ConversationRatio = GetIntFromYamlMap(node, "kaiwaritu"), Impressions = GetIntFromYamlMap(node, "impression_cnt"), Reviews = GetIntFromYamlMap(node, "review_cnt"), Votes = GetIntFromYamlMap(node, "all_hyoka_cnt"), VoteScore = GetIntFromYamlMap(node, "all_point"), Bookmarks = GetIntFromYamlMap(node, "fav_novel_cnt"), DailyPoint = GetIntFromYamlMap(node, "daily_point"), WeeklyPoint = GetIntFromYamlMap(node, "weekly_point"), MonthlyPoint = GetIntFromYamlMap(node, "monthly_point"), QuarterPoint = GetIntFromYamlMap(node, "quarter_point"), YearPoint = GetIntFromYamlMap(node, "yearly_point"), Points = GetIntFromYamlMap(node, "global_point"), Date = t.LastCheck.Date }; DebugReport.Log(this, $"REST get info {t.ID} {t.Name}"); t.Score.Add(score); return(t); }
/// <summary> /// 指定IDのデータをロード /// </summary> /// <param name="id"></param> /// <returns></returns> public bool Load(string id) { lock (lockObj) { var path = Path.Combine(StoragePath, $"{id}.xml"); if (File.Exists(path)) { using (var f = new StreamReader(path)) { var ser = new XmlSerializer(typeof(DB.Author)); var auth = ser.Deserialize(f) as DB.Author; if (auth != null) { authorInfo = auth; DebugReport.Log(this, $"Author DB Loaded {path}"); return(true); } } } DebugReport.Log(this, $"Author DB Load failed {path}"); } return(false); }
/// <summary> /// Kasasagiにリクエスト /// </summary> /// <param name="cacheFile"></param> /// <param name="apiUrl"></param> /// <returns></returns> private string RequestKasasagi(string cacheFile, string apiUrl, Func <string, bool> error) { var client = new HttpClient(); client.DefaultRequestHeaders.Add("User-Agent", UserAgent); var task = client.GetAsync(apiUrl); if (task.Result.IsSuccessStatusCode) { var contentReadTask = task.Result.Content.ReadAsStringAsync(); var html = contentReadTask.Result; if (error(html)) { //この時はキャッシュ保存しない DebugReport.Log(this, $"kasasagi failed {apiUrl}"); return(""); } else { //キャッシュ保存する。 //データが安定していない当月分(と3日までは先月分も)は残さないほうが運用が楽かも DebugReport.Log(this, $"kasasagi succeeded {apiUrl}"); if (!Directory.Exists(CachePath)) { Directory.CreateDirectory(CachePath); } File.WriteAllText(cacheFile, html); } return(html); } else { DebugReport.Log(this, $"kasasagi {task.Result.ReasonPhrase} {apiUrl}"); } return(""); }
/// <summary> /// ログ消去 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnLogClear_Click(object sender, EventArgs e) { lstLog.Items.Clear(); DebugReport.LogClear(); }