「ブログランキング」と「グラフ」の更新時刻がかなり異なる 

この2日ほど、朝の「アクセス解析」の状態を観察して来ましたが、7時半前後に「ブログランキング」が更新され、「グラフ」更新よりかなり早い事が判りました。

 

 

これまでは「グラフ」更新を調べて更新済を「報告」するコードで、これは簡単で確実に判定ができる方法でした。「ブログランキング」には時刻の表示が無いため、判定が少し難しいのです。

 

しかし、「グラフ」と「ブログランキング」とでは、更新時刻に半時間もの差があるので、ここは失敗を恐れずに、「ブログランキング」更新を「報告」するコードを試作しました。

 

 

 

「ブログランキング」の更新を判定する 

ランキング順位を記録する Cookie「Awake_last」を用意します。 このCookieは、有効期限を 22hに設定します。

 

===============================

● Cookieの「Awake_updated」を読み、それが存在すれば「更新済の表示」

 

●「Awake_updated」が無い場合は、以下の作業をする

 (「Awake_updated」は有効期限2hで、更新を確認した時に発行される)

 

◎ ランキング順位の2個の表示数を繋いで変数「compare」に取得

 (2個の表示数を繋ぐのは、順位の変化を確かに反映させるため)

 

◎ Cookieの「Awake_last」を読み、前回に記録された「compare」と比較

 

 ➔ 値が異なっていたら「更新」が行われたと判定する

   ▪「更新済の表示」

   ▪「Awake_updated」を登録する

    (これにより「更新済の表示」を2h 継続させる)

 

 ➔ 値が同じ場合は何もしない

 ➔ 「Awake_last」がない場合は、管理トップを 22h 以上開いていない

        これは判定不能なので、何もしない

 

◎「Awake_last」に、現在の「compare」の値を登録する

 

===============================

 

「管理トップ」を開く度に「Awake」が起動し、上の処理が1回だけ実行されます。

 

Cookie「Awake_last」は「更新」を判断する指標で、「管理トップ」を開く度に更新保存するだけで充分でしょう。 これにランキング表示を記録し、値が変化したかを調べます。 判定は「管理トップ」を開いた時に行いますが、ページを開いたまま放置していると、更新があってもページ表示に反映せず、このツールも気付けません。

 

24h以前のランキング表示は、必ず前日の更新を経ているので、それと比較すると常に「更新あり」になります。 更新を判定する指標は、前日のランキング表示に限る必要があるわけです。 ここから、余裕を見て過去 22h以内の「Awake_last」しか、判定に使われない様にします。 Cookieの有効期限を設定して、22時間以前の登録は消してしまいます。

 

この方式によって、最後に「管理トップ」を開いたのが 22hより前の場合は、判定が出来ません。 その場合、もし更新が行われていても判断不能です。 もっとも、「グラフ」の日付から判定する既存の機能は働いています。 つまり「ブログランキング」の更新を判定する機能を、既存の判定機能がバックアップする事になります。

 

◎ 上記ダイアグラムのコードを実装しましたが、思い通りに機能するかはこれからテストになります。

 

 

 

 「ブログランキング」の更新の表示

「グラフ」より先に更新されるので、更新直後に「管理トップ」を開くと、「ブログランキング部」の背景色はグレーのままです。「ランキング順位」が更新された事をユーザーに気付かせるために、下の様に、順位表示部分だけを「白背景」にし、余り目立ちませんが、数字の色も元の緑から青に変えています。

 

 

この「更新済」の表示は、更新が判定されてから2時間続きます。 極端なハイライト配色ではなく、半時間後に「グラフ部」が「更新済」になった後は、自然に溶け込むと思います。「更新」が2つの段階で行われるのに沿って、いちはやくそれをユーザーに気付かせるデザインです。

 

 

 

「Awake」を使用するには  

このツールは Chrome / Edge / Firefox の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。

 

❶「Tampermonkey」を導入します

使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。 以下のページに簡単な導入の説明があるので参照ください。

 

 

❷「Tampermonkey」にスクリプトを登録します

●「Tampermonkey」の「」マークの「新規スクリプト」タブを開きます。

 

 

 

●「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白になった編集枠に 下のコードをコピー&ペーストします。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

● 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。

 

 

〔 Awake 〕 ver. 1.0

 

// ==UserScript==
// @name         Awake
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  アクセスレポートの更新を背景色で表示・解析ページを「今日」で開く
// @author       Ameba Blog User
// @match        https://blog.ameba.jp/ucs/analysis*
// @match        https://blog.ameba.jp/ucs/top*
// @grant        none
// ==/UserScript==


let path=document.location.pathname;
if(path=='/ucs/top.do'){ // 管理トップ で実行

    let realtime=document.querySelector('.accessAnalysis__dailyAccess');
    if(realtime){
        realtime.style.cursor='pointer';
        realtime.onclick=function(event){
            if(!event.shiftKey){
                window.location.href='https://blog.ameba.jp/ucs/analysis/analysis.do?unit=today'; }
            else{
                window.location.href='https://blog.ameba.jp/ucs/analysis/analysis_page.do?unit=today'; }}

        document.onkeydown=function(event){
            if(event.shiftKey){
                realtime.classList.add('shift'); }}

        document.onkeyup=function(event){
            if(!event.shiftKey){
                realtime.classList.remove('shift'); }}


        let style_icon=
            '<style>.accessAnalysis__dailyAccess { position: relative; outline-offset: -1px; } '+
            '.accessAnalysis__dailyAccess:before { content: "\\EA57"; color: #2196f3; '+
            'font-family: ameba-symbols; font-size: 32px; position: absolute; top: 2px; left: 12px; } '+
            '.accessAnalysis__dailyAccess.shift:after { content: "記事別"; '+
            'position: absolute; top: 43px; left: 16px; font: bold 16px Meiryo; } '+
            '.accessAnalysis__dailyAccess:hover { outline: 1px solid #2196f3; } '+
            '.spui-LinkButton--neutral { display: none; } '+
            '#contents .accessAnalysis__summary { background: #efefef; } '+
            '</style>';
        realtime.insertAdjacentHTML('afterbegin', style_icon); }


    setTimeout(()=>{
        new_report1();
        new_report_rank();
    }, 500); // ページを開いてからのタイミング

} // 管理トップ で実行




if(path.indexOf('analysis')!==-1){ // アクセス解析ページ全体
    let target0=document.querySelector('#root > div');
    let monitor0=new MutationObserver(page_change);
    monitor0.observe(target0, { childList: true });

    page_change();

    function page_change(){
        let path=document.location.pathname;
        if(path.indexOf('analysis.do')!==-1){ // アクセス解析トップ
            clear_disp();
            setTimeout(()=>{
                new_report2();
            }, 500); // ページを開いてからのタイミング


            let realtime=document.querySelector('.p-realtimeAccess');
            if(realtime){
                realtime.style.cursor='pointer';
                realtime.onclick=function(event){
                    if(!event.shiftKey){
                        window.location.href='https://blog.ameba.jp/ucs/top.do'; }
                    else{
                        window.location.href='https://blog.ameba.jp/ucs/analysis/analysis_page.do?unit=today'; }}

                document.onkeydown=function(event){
                    if(event.shiftKey){
                        realtime.classList.add('shift'); }}

                document.onkeyup=function(event){
                    if(!event.shiftKey){
                        realtime.classList.remove('shift'); }}

                let style_icon=
                    '<style>.p-realtimeAccess { position: relative; } '+
                    '.p-realtimeAccess:before { content: "\\EA31"; color: #009688; '+
                    'font-family: ameba-symbols; font-size: 32px; position: absolute; left: 10px; } '+
                    '.p-realtimeAccess.shift:before { content: "\\EA57"; color: #2196f3; } '+
                    '.p-realtimeAccess.shift:after { content: "記事別"; '+
                    'position: absolute; top: 40px; left: 14px; font: bold 16px Meiryo; } '+
                    '.p-realtimeAccess:hover { outline: 1px solid #2196f3; outline-offset: -1px; } '+
                    '.p-analysisSummary { background: #efefef; }'+
                    '</style>';
                realtime.insertAdjacentHTML('afterbegin', style_icon); }

        } // アクセス解析トップ


        if(path.indexOf('analysis_page.do')!==-1){ // 記事別アクセス数ページ
            let target=document.querySelector('#root section');
            let monitor=new MutationObserver(count_do);
            monitor.observe(target, { childList: true });

            count_do();
        } // 記事別アクセス数ページ

    } // page_change()
} // アクセス解析ページ全体




function new_report1(){
    let graph_term=document.querySelector('.accessAnalysis__graphHeadingTerm');
    if(graph_term){
        let accsess_text=graph_term.textContent.split('〜')[1];
        let day=accsess_text.slice(0, -3).split('/')[1];

        let date=new Date();
        date.setDate(date.getDate() -1); // 昨日の日付を取得
        let yesterday=date.getDate();
        if(day==yesterday){
            let access_panel=document.querySelector('.accessAnalysis__summary');
            access_panel.style.background='#ffff'; }}}



function new_report_rank(){
    if(get_cookie('Awake_updated')==1){ // Cookie 「updated」をチェック Age 2h 🟢
        disp_updated(); } // 更新後の2hはハイライト表示

    else{
        let compare='';
        let GRnum=document.querySelector('.accessAnalysis__summaryRankingGenreRelatedRankNumber');
        if(GRnum){
            compare+=GRnum.textContent; }
        let GAnum=document.querySelector('.accessAnalysis__summaryRankingGenreAllRankNumber');
        if(GAnum){
            compare+=GAnum.textContent; }
        let ORnum=document.querySelector('.accessAnalysis__summaryRankingOfficialRelatedRankNumber');
        if(ORnum){
            compare+=ORnum.textContent; }
        let OAnum=document.querySelector('.accessAnalysis__summaryRankingOfficialAllRankNumber');
        if(OAnum){
            compare+=OAnum.textContent; }

        let last=get_cookie('Awake_last');
        if(last!=0 && compare!=''){
            if(last!=compare){ // 更新後の判定 Cookie 「updated」を登録 Age 2h 🟢
                document.cookie='Awake_updated=1; Max-Age=7200';
                disp_updated(); }}
        else{ // 22h以内に管理トップを開いていない or compareの取得に失敗した場合
            ; } // 判定不能

        if(compare!=''){ // Cookie「Awake_last」更新 Age 22h 🟢
            document.cookie='Awake_last='+compare+'; Max-Age=79200'; }

    } // 最後の更新を確認後から2h以降は、このチェックを起動ごとに行う


    function disp_updated(){
        let panel_G=document.querySelector('.accessAnalysis__summaryRankingGenre');
        if(panel_G){
            panel_G.style.filter='hue-rotate(45deg)';
            panel_G.style.background='#fff'; }
        let panel_O=document.querySelector('.accessAnalysis__summaryRankingOfficial');
        if(panel_O){
            panel_O.style.filter='hue-rotate(45deg)';
            panel_O.style.background='#fff'; }}


    function get_cookie(name){
        let cookie_req=document.cookie.split('; ').find(row=>row.startsWith(name));
        if(cookie_req){
            if(cookie_req.split('=')[1]==null){
                return 0; }
            else{
                return cookie_req.split('=')[1]; }}
        if(!cookie_req){
            return 0; }}

} // new_report_rank()



function new_report2(){
    let access_title=document.querySelector('.p-analysisSummary__access__title');
    if(access_title){
        let accsess_text=access_title.textContent.match(/\(.*\)/).toString();
        let day=accsess_text.match(/\/.*/).toString().replace(/[^0-9]/g, '');

        let date=new Date();
        date.setDate(date.getDate() -1); // 昨日の日付を取得
        let yesterday=date.getDate();

        if(day==yesterday){
            let access_panel=document.querySelector('.p-analysisSummary');
            access_panel.style.background='#fff'; }}}



function count_do(){
    clear_disp();

    let retry=0;
    let interval=setInterval(more_open, 1000);
    function more_open(){
        retry++;
        if(retry>20){ // リトライ制限 20回 4sec
            clearInterval(interval);
            alert("全てのリスト情報を開かずに合計しました"); }

        let more=document.querySelector('.p-accessGraph__moreLinkBtn--center');
        if(more){
            more.click(); }
        if(!more){
            clearInterval(interval);
            page_count(); }}


    function page_count(){
        let line_count=0;
        let num_count=0;
        let p_count=document.querySelectorAll('.p-accessGraphItem__count');
        for(let k=0; k<p_count.length; k++){
            line_count+=1;
            let line_item_disp=p_count[k].textContent.replace(/[^0-9]/g, '');
            num_count+=parseInt(line_item_disp, 10); }

        let disp=document.createElement('div');
        disp.setAttribute("id", 'add_access');
        disp.innerHTML=
            '参照された記事数:'+ line_count +' アクセス数合計:'+ num_count;

        let style=document.createElement('style');
        style.innerHTML=
            '#add_access { position: fixed; top: 100px; right: calc(50% - 405px); '+
            'padding: 4px 15px 2px; font: normal 16px Meiryo; z-index: 10; '+
            'border: 1px solid #009688; background: #fff; '+
            'box-shadow: 2px 3px 6px rgb(170, 170, 170,  0.4); }';

        if(line_count==100){
            style.innerHTML=
                '#add_access { position: fixed; top: 100px; right: calc(50% - 405px); '+
                'padding: 4px 15px 2px; font: normal 16px Meiryo; z-index: 10; '+
                'border: 1px solid red; background: #fff; '+
                'box-shadow: 2px 3px 6px rgb(170, 170, 170,  0.4); }'; }

        disp.appendChild(style);

        clear_disp();
        document.querySelector('body').appendChild(disp);

    } // page_count()
} // count_do()



function clear_disp(){
    if(document.querySelector('#add_access')){
        document.querySelector('#add_access').remove(); }}


 

 

 

「Awake」最新版について 

旧いバージョンの「Awake」は、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。 最新バージョンへのリンクは、以下のページのリンクリストから探せます。