Beispiel #1
0
        public void Set(DB.Author author, DB.Title title, DB.DailyScore daily)
        {
            var s = new StringBuilder();

            if (author != null)
            {
                s.AppendLine($"{author.Name}[{author.ID}]");
            }
            if (title != null)
            {
                s.AppendLine($"{title.Name}");
                s.AppendLine($"{title.ID} since {title.FirstUp:yyyy/MM/dd}");
            }
            if (daily != null)
            {
                Text = daily.Date.ToString("yyyy/MM/dd");
                s.AppendLine($"{daily.PageView} pv.");
                if (daily.HasScoreInfo)
                {
                }
                if (daily.PartPvChecked)
                {
                    s.AppendLine("[部位別PV取得済]");
                }
                txtEvent.Text = daily.Event;
            }
            lblInfo.Text = s.ToString();
        }
Beispiel #2
0
 /// <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;
         }
     });
 }
Beispiel #3
0
        /// <summary>
        /// kasasagiのスクレイピング
        /// </summary>
        /// <param name="title">作品</param>
        /// <param name="html">コンテンツ</param>
        /// <param name="isUnique">ユニークのデータか?</param>
        private void parsePvHTML(DB.Title title, string html, bool isUnique)
        {
            var regTable = new Regex("\\<table class=\"access_per_day\"\\>(.+?)\\</table\\>", RegexOptions.Singleline);
            var regDate  = new Regex("(\\d+)年(\\d+)月(\\d+)日");
            var regView  = new Regex("\\<td class=\"item\"\\>([\\d,]+)人?\\</td\\>.+?\\<div class=\"(pc|mobile|smp)\"", RegexOptions.Singleline);
            var matches  = regTable.Matches(html);

            foreach (Match match in matches)
            {
                var dayTable = match.Groups[1].Value;
                var dm       = regDate.Match(dayTable);
                if (dm.Success)
                {
                    var date   = new DateTime(int.Parse(dm.Groups[1].Value), int.Parse(dm.Groups[2].Value), int.Parse(dm.Groups[3].Value));
                    var tempPv = new DB.DailyScore();
                    tempPv.Date = date;
                    var vms = regView.Matches(dayTable);
                    foreach (Match vm in vms)
                    {
                        var ns = vm.Groups[1].Value;
                        ns = ns.Replace(",", "");
                        var pv  = int.Parse(ns);
                        var cls = vm.Groups[2].Value;
                        setPv(isUnique, tempPv, pv, cls);
                    }
                    //作品データにマージ
                    title.AddPageView(tempPv, isUnique);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// スコアデータ登録
        /// </summary>
        /// <param name="dailyValue"></param>
        /// <remarks>
        /// この機能は、ロードした作品データにPVデータをマージするための物なので、REST-API分のデータはノータッチ。
        /// </remarks>
        public void AddPageView(DailyScore pv, bool isUnique)
        {
            //探す日付
            var findDate = pv.Date.Date;

            //おんなじ日付があるか探す
            for (var i = 0; i < Score.Count; i++)
            {
                if (Score[i].Date.Date == findDate)
                {
                    //同じ日→マージ
                    if (isUnique)
                    {
                        Score[i].MergeUniquePageView(pv);
                    }
                    else
                    {
                        Score[i].MergePageView(pv);
                    }
                    return;
                }
                else if (Score[i].Date.Date > findDate)
                {
                    //過ぎた→インサート
                    Score.Insert(i, pv);
                    return;
                }
            }
            //最期に足す(普通はUpdate時のScoreデータがあるのでここには来ない)
            Score.Add(pv);
        }
Beispiel #5
0
 /// <summary>
 /// ユニークPV部分のマージ
 /// </summary>
 /// <param name="pv"></param>
 public void MergeUniquePageView(DailyScore pv)
 {
     if (Date.Date != pv.Date.Date)
     {
         throw new InvalidOperationException("Date Mismatch");
     }
     PCUnique         = pv.PCUnique;
     MobileUnique     = pv.MobileUnique;
     SmartPhoneUnique = pv.SmartPhoneUnique;
 }
Beispiel #6
0
        /// <summary>
        /// PV部分のマージ
        /// </summary>
        /// <param name="pv"></param>
        public void MergePageView(DailyScore pv)
        {
            if (Date.Date != pv.Date.Date)
            {
                throw new InvalidOperationException("Date Mismatch");
            }

            PC         = pv.PC;
            Mobile     = pv.Mobile;
            SmartPhone = pv.SmartPhone;
            //ユニークは別HTMLから取るので別関数です
        }
Beispiel #7
0
        /// <summary>
        /// PVを加算
        /// </summary>
        /// <param name="days">何日分?(負なら全部)</param>
        /// <returns></returns>
        /// <remarks>加算結果</remarks>
        public DailyScore SumUpPv(int days)
        {
            var score = new DailyScore();
            var last  = days < 0 ? new DateTime() : LatestScore.Date.Date.AddDays(-days);

            foreach (var s in Score)
            {
                if (s.Date.Date >= last)
                {
                    score.PC               += s.PC;
                    score.PCUnique         += s.PCUnique;
                    score.Mobile           += s.Mobile;
                    score.MobileUnique     += s.MobileUnique;
                    score.SmartPhone       += s.SmartPhone;
                    score.SmartPhoneUnique += s.SmartPhoneUnique;
                }
            }
            return(score);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <summary>
        /// 作品データ表示
        /// </summary>
        /// <param name="title"></param>
        public void Arrange(DB.Title title)
        {
            ArrangedAuthor = null;
            ArrangedTitle  = title;

            chDate.Text = "Date";
            lvDisplay.BeginUpdate();
            lvDisplay.Items.Clear();
            var mobileColumnWidth = 0;

            //総計
            {
                var item = new ListViewItem("total");
                var pv   = new DB.DailyScore
                {
                    PC               = title.Score.Sum(x => x.PC),
                    PCUnique         = title.Score.Sum(x => x.PCUnique),
                    Mobile           = title.Score.Sum(x => x.Mobile),
                    MobileUnique     = title.Score.Sum(x => x.MobileUnique),
                    SmartPhone       = title.Score.Sum(x => x.SmartPhone),
                    SmartPhoneUnique = title.Score.Sum(x => x.SmartPhoneUnique)
                };
                if (pv.Mobile != 0)
                {
                    mobileColumnWidth = DefaultMobileColumnWidth;
                }
                var score = title.LatestScore;
                registorScoreInfo(pv, score, null, item);

                lvDisplay.Items.Add(item);
            }
            //個別(逆順)
            foreach (var score in (title.Score as IEnumerable <DB.DailyScore>).Reverse())
            {
                var item = new ListViewItem(score.Date.ToString("yyyy/MM/dd"));
                registorScoreInfo(score, score, null, item);
                lvDisplay.Items.Add(item);
            }

            lvDisplay.Columns[indexOfMobileColumn].Width = mobileColumnWidth;
            lvDisplay.EndUpdate();
        }
Beispiel #10
0
        /// <summary>
        /// 部分別PVを解析
        /// </summary>
        /// <param name="title"></param>
        /// <param name="date"></param>
        /// <param name="html"></param>
        private void parsePartPvHTML(DB.DailyScore score, string html)
        {
            if (string.IsNullOrEmpty(html))
            {
                return;
            }
            score.PartPv        = new List <DB.PartPv>();
            score.PartPvChecked = true;
            var reg = new Regex(@">第(\d+)部分:(\d+)人");

            MatchCollection ms = reg.Matches(html);

            foreach (Match m in ms)
            {
                var p  = int.Parse(m.Groups[1].Value);
                var pv = int.Parse(m.Groups[2].Value);
                score.PartPv.Add(new DB.PartPv {
                    Part = p, PageView = pv
                });
            }
        }
Beispiel #11
0
        /// <summary>
        /// スコア部分のマージ
        /// </summary>
        /// <param name="score"></param>
        public void MergeScore(DailyScore score)
        {
            if (Date.Date != score.Date.Date)
            {
                throw new InvalidOperationException("Date Mismatch");
            }

            Series            = score.Series;
            Size              = score.Size;
            ConversationRatio = score.ConversationRatio;
            Impressions       = score.Impressions;
            Reviews           = score.Reviews;
            Votes             = score.Votes;
            VoteScore         = score.VoteScore;
            Bookmarks         = score.Bookmarks;
            DailyPoint        = score.DailyPoint;
            WeeklyPoint       = score.WeeklyPoint;
            MonthlyPoint      = score.MonthlyPoint;
            QuarterPoint      = score.QuarterPoint;
            YearPoint         = score.YearPoint;
            Points            = score.Points;
        }
Beispiel #12
0
        /// <summary>
        /// 1日データに値を設定
        /// </summary>
        /// <param name="isUnique"></param>
        /// <param name="tempPv"></param>
        /// <param name="pv"></param>
        /// <param name="cls"></param>
        private void setPv(bool isUnique, DB.DailyScore tempPv, int pv, string cls)
        {
            switch (cls)
            {
            case "pc":
                if (isUnique)
                {
                    tempPv.PCUnique = pv;
                }
                else
                {
                    tempPv.PC = pv;
                }
                break;

            case "mobile":
                if (isUnique)
                {
                    tempPv.MobileUnique = pv;
                }
                else
                {
                    tempPv.Mobile = pv;
                }
                break;

            case "smp":
                if (isUnique)
                {
                    tempPv.SmartPhoneUnique = pv;
                }
                else
                {
                    tempPv.SmartPhone = pv;
                }
                break;
            }
        }
Beispiel #13
0
        /// <summary>
        /// 部位別PVデータ取得
        /// </summary>
        /// <param name="title">どの作品の</param>
        /// <param name="daily">いつ?</param>
        /// <remarks>
        /// ユニークが出てからしか更新されず、以降データ変動しない(と思われる)ので常にキャッシュが有効。
        /// そもそもPVがない日は取れないので、当日のScoreがないときは何もせずに帰る。
        /// </remarks>
        public bool GetPartPvData(DB.Title title, DB.DailyScore daily)
        {
            if (title == null)
            {
                return(false);
            }
            if (daily == null)
            {
                return(false);
            }
            var date = daily.Date;

            bool useKasasagi = false;
            var  dt          = date.ToString("yyyy-MM-dd");
            var  url         = $"{KasasagiPartPv}{title.ID}/?date={dt}";
            var  cacheFile   = $"KasasagiP{title.ID}{date.Year:0000}{date.Month:00}{date.Day:00}.html";

            cacheFile = Path.Combine(CachePath, cacheFile);

            string html = null;

            if (File.Exists(cacheFile))
            {
                html = File.ReadAllText(cacheFile);
            }
            if (html == null)
            {
                useKasasagi = true;
                html        = RequestKasasagi(cacheFile, url, x => x.Contains(PreparingMarker) || x.Contains(PartPvNotPreparedMarker));
            }

            //パースする
            parsePartPvHTML(daily, html);

            return(useKasasagi);
        }
Beispiel #14
0
        /// <summary>
        /// 1項目分追加
        /// </summary>
        /// <param name="pv">PVデータを含むやつ</param>
        /// <param name="score">スコアデータを含むやつ</param>
        /// <param name="item">追加する対象ンリストビューアイテム</param>
        private static void registorScoreInfo(DB.DailyScore pv, DB.DailyScore score, DB.DailyScore diffScore, ListViewItem item)
        {
            item.Tag = score;
            item.UseItemStyleForSubItems = false;

            if (pv != null)
            {
                setPvColumnData(item, pv.PC, pv.PCUnique);
                setPvColumnData(item, pv.Mobile, pv.MobileUnique);
                setPvColumnData(item, pv.SmartPhone, pv.SmartPhoneUnique);
                setPvColumnData(item, pv.PageView, pv.UniquePageView);
            }
            else
            {
                item.SubItems.Add("no data");
                item.SubItems.Add("no data");
                item.SubItems.Add("no data");
                item.SubItems.Add("no data");
            }
            if (score.HasScoreInfo)
            {
                if ((diffScore == null) || (!diffScore.HasScoreInfo))
                {
                    //通常表示モード
                    if (score.Votes == 0)
                    {
                        item.SubItems.Add("none");
                    }
                    else
                    {
                        var voteScore = score.VoteAverage;
                        item.SubItems.Add($"{voteScore:0.0}({score.Votes}人)");
                    }
                    item.SubItems.Add($"{score.Bookmarks}");
                    item.SubItems.Add($"{score.Impressions}");
                    item.SubItems.Add($"{score.Reviews}");
                    item.SubItems.Add($"{score.DailyPoint}");
                    item.SubItems.Add($"{score.WeeklyPoint}");
                    item.SubItems.Add($"{score.MonthlyPoint}");
                    item.SubItems.Add($"{score.QuarterPoint}");
                    item.SubItems.Add($"{score.YearPoint}");
                    item.SubItems.Add($"{score.Points}");
                    item.SubItems.Add($"{score.Series}");
                    item.SubItems.Add($"{score.Size:#,0}");
                }
                else
                {
                    //比較表示モード
                    var signed = "+#,0;-#,0; ";
                    item.SubItems.Add($"{(score.VoteAverage - diffScore.VoteAverage).ToString("+#,0.0;-#,0.0")}({(score.Votes - diffScore.Votes).ToString("+#,0;-#,0;±0")}人)");
                    item.SubItems.Add($"{(score.Bookmarks - diffScore.Bookmarks).ToString(signed)}");
                    item.SubItems.Add($"{(score.Impressions - diffScore.Impressions).ToString(signed)}");
                    item.SubItems.Add($"{(score.Reviews - diffScore.Reviews).ToString(signed)}");
                    item.SubItems.Add($"{(score.DailyPoint - diffScore.DailyPoint).ToString(signed)}");
                    item.SubItems.Add($"{(score.WeeklyPoint - diffScore.WeeklyPoint).ToString(signed)}");
                    item.SubItems.Add($"{(score.MonthlyPoint - diffScore.MonthlyPoint).ToString(signed)}");
                    item.SubItems.Add($"{(score.QuarterPoint - diffScore.QuarterPoint).ToString(signed)}");
                    item.SubItems.Add($"{(score.YearPoint - diffScore.YearPoint).ToString(signed)}");
                    item.SubItems.Add($"{(score.Points - diffScore.Points).ToString(signed)}");
                    item.SubItems.Add($"{(score.Series - diffScore.Series).ToString(signed)}");
                    item.SubItems.Add($"{(score.Size - diffScore.Size).ToString(signed)}");
                }
            }
            else
            {
                for (var i = 0; i < DailyColumnWidth; i++)
                {
                    item.SubItems.Add("");
                }
            }
            item.SubItems.Add($"{score.Event}");
        }