zoukankan      html  css  js  c++  java
  • Extract Stylish styles and save as JSON format

    Introduction

    Stylish is a easy browser extension/plugin for users to customizing the web page styling using CSS/3. It is available in Google Chrome, Firefox, Safari, Opera, and many Chromium-based browsers and really easy to hide the annoying ads out of sight.(different from ad-blocker). but the most abominable is that it doesn't provide a export/import feature.

    Background

    The Stylish extension for Google Chrome or Chromium-based browsers lacks export/import feature. This article is to introduce a way to extract the saved styles in Stylish as Json to a file for backing up.

    Using the code

    The Stylish extension located at Library/Application Support/Google/Chrome/Default/Extensions/fjnbnpbmkenffdnngjfgmeleoegfcffe.

    The files for storage of the saved styles are JS files. The storage-websql.js file is a controller to store the styles into SQLite3 database file using Javascript and WebSQL tech. The storage.js is to store the data using local storage IndexedDB.

    The CSS code, name and url submitted are processed and stored to database named stylish. [ the mapping of dbname and the data file is specified in the Databases.db in Default/databases/. Databases.db is a SQLite3 db file.]. The data file is in the folder databases/chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0 as specified in field origin. And the data file is named a number as specified by id in table Databases, which stores all the databases mapping used by JS.

    ➜  databases sqlite3 Databases.db
    SQLite version 3.7.17 2013-05-20 00:56:22
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
    sqlite> .tables
    Databases  meta
    sqlite> .explain
    sqlite> select * from Databases;
    id    origin         name  desc  esti
    ----  -------------  ----  ----  ----
    1     chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0  stylish  Stylish Styles  5242880
    4     chrome-extension_dhdgffkkebhmkfjojejmpbldmpobfkfo_0  tmStorage  TM Storage  31457280
    10    https_passport.weibo.com_0  ufp         1024
    11    https_bbs.fudan.edu.cn_0  PersistJS Test  Persistent database test.  204800
    12    https_bbs.fudan.edu.cn_0  https___bbs_fudan_edu_cn_bbs  Persistent storage for https___bbs_fudan_edu_cn_bbs  204800
    

    The databases/chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0/1 is a SQLite3 db file, which, in my case, contains nothing. So the data is not saved in this db file.

    Another location for storage is Default/IndexedDB/, which also has a folder named chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0

    001

    While all the data, the styles user saved, are in this file, but it's encrypted. If you open it using Sublime Text 3, it may looks like:

    002

    So I checked the parser, storage.js and found something useful.

    1. The getDatabase uses var dbOpenRequest = window.indexedDB.open("stylish", 2) to get the db object.
    2. on success, parse e.target.result to callback function
    3. in function getStyles, getDatabase def is called.
    4. the result of db.transaction(["styles"], "readonly") then tx.objectStore("styles") is the data.
    5. I checked the results of each step and finally all is clear.
    6. open the manage page of Stylish and open the Console and run the following code in it.
    var db, dbOpenRequest = window.indexedDB.open("stylish", 3); // change to 2 if 3 failed
    dbOpenRequest.onsuccess = function(e) {
      db = e.target.result;
    };
    var tx = db.transaction(["styles"], "readwrite");
    var os = tx.objectStore("styles");
    var all = [];
    os.openCursor().onsuccess = function(event) {
      var cursor = event.target.result;
      if (cursor) {
        var s = cursor.value
        s.id = cursor.key
        all.push(cursor.value);
        cursor.continue();
      }
    };
    

    And then

    for(var i=0;i< all.length;i++){
      var cur = all[i];
      console.log(JSON.parse()cur.name,cur.sections[0].code,cur.sections[0].domains,cur.sections[0].regexps,cur.sections[0].urlPrefixes,cur.sections[0].urls)
    }
    // or 
    console.log(JSON.stringify(all));
    // This is better
    

    The result,
    [ The name is the description of a style, all the properties of sections are the CSS code and the rules you specified ]

    [
        {
            "originalMd5": "",
            "updateUrl": "",
            "enabled": true,
            "name": "有道词典",
            "id": 2,
            "md5Url": "",
            "sections": [
                {
                    "regexps": [
                        ".*youdao\.com.*"
                    ],
                    "urlPrefixes": [],
                    "urls": [],
                    "domains": [],
                    "code": "#topImgAd,
    #Ads,
    #ads,
    #baidu-adv,
    #follow{
        display:none!important;
        float:none;
      }
    #results-contents{
    	inherit!important;
    }
    #results,
    #collinsResult .ol .collinsMajorTrans{
    	100%;
        float:none;
    }"
                }
            ],
            "url": "",
            "method": "saveStyle"
        },
        {
            "originalMd5": "",
            "updateUrl": "",
            "enabled": true,
            "name": "cnet.com",
            "id": 3,
            "md5Url": "",
            "sections": [
                {
                    "regexps": [],
                    "urlPrefixes": [],
                    "urls": [],
                    "domains": [
                        "cnet.com"
                    ],
                    "code": "#adunit,
    #videoPromo,
    #mpu-plus-top-5738382253301,
    #leader-top-5738382253301
    .ad-mpu-plus-top{
        display: none!important;
    }
    
    iframe,
    .ad-leader-top>div, .ad-leader-top>iframe, .ad-leader-top>table, .ad-leader-plus-top>div, .ad-leader-plus-top>iframe, .ad-leader-plus-top>table, .ad-leader-middle>div, .ad-leader-middle>iframe, .ad-leader-middle>table, .ad-leader-middle2>div, .ad-leader-middle2>iframe, .ad-leader-middle2>table, .ad-leader-bottom>div, .ad-leader-bottom>iframe, .ad-leader-bottom>table, .ad-leader-inc>div, .ad-leader-inc>iframe, .ad-leader-inc>table{
    	display: none!important;
    }
    "
                }
            ],
            "url": "",
            "method": "saveStyle"
        },
        {
            "originalMd5": "",
            "updateUrl": "",
            "enabled": true,
            "name": "沪江英语",
            "id": 4,
            "md5Url": "",
            "sections": [
                {
                    "regexps": [],
                    "urlPrefixes": [],
                    "urls": [],
                    "domains": [
                        "hjenglish.com",
                        "hujiang.com"
                    ],
                    "code": ".lamu_banner,
    .top_banner,
    .fix_questionnaire_btn,
    .animated,
    .bounceIn,
    .wx_entrance_box,
    .daily_tasks_list,
    .pass_add_ad1,
    .add_ban_y_sign,
    .bottomActive1212,
    .news_overly,
    .news_overly_c,
    .footer_go_top,
    #footer-ft,
    .sub-qr-box,
    .sub-qr-bubble-big,
    .header_board_tip,
    .header_board_tip2{
        display:none!important;
    }
    "
                }
            ],
            "url": "",
            "method": "saveStyle"
        },
        {
            "originalMd5": "",
            "updateUrl": "",
            "enabled": true,
            "name": "今日头条",
            "id": 5,
            "md5Url": "",
            "sections": [
                {
                    "regexps": [],
                    "urlPrefixes": [],
                    "urls": [],
                    "domains": [
                        "toutiao.com"
                    ],
                    "code": "#pagelet-iad,
    #pagelet-hotpgc,
    #pagelet-hotgallery,
    #pagelet-hotvideo,
    #pagelet-tbad,
    .dtag,
    .hotgallery_show{
    display:none!important;
    }"
                }
            ],
            "url": "",
            "method": "saveStyle"
        }
    ]
    

    backup

    to back up the data regularly, just archive the folder chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0 under IndexedDB using 7z or tar and mv it to iCloud or Dropbox/baiduyun/360yun ... to sync and cron.

    #!/bin/bash
    dest=$HOME"/YunPan/iMac 20160501/Google Chrome/Stylish/"
    path=$HOME"/Library/Application Support/Google/Chrome/Default/IndexedDB"
    
    ext="chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0.indexeddb.leveldb"
    dt=$(date +%Y,%m,%d-%H,%M,%S)
    
    
    filename='ggc_stylish_'$dt'.7z'
    cd "$path"
    /usr/local/bin/7z a "$filename" "$ext"
    if [[ $? != 0 ]];then
        echo "$dt Error with 7z." >> "${dest}backup.log"
        exit
    fi
    mv "$filename" "$dest"
    if [[ $? != 0 ]];then
        echo "$dt Error with mv." >> "${dest}backup.log"
        exit
    fi
    cd "$dest"
    echo "$dt Done with bu." >> "backup.log"
    
    # file default.cron
    ## weekly 6:30am
    30 6 * * 1 /Users/ruili/Bin/cron.d/scripts/ggc_stylish_weekly.sh
    

    run crontab default.cron and crontab -l

  • 相关阅读:
    solrCloud设置Tomcat jvm内存解决内存溢出的问题
    JAVA 将图片转换为Base64编码
    希望这是一个新的开始,也是一个好的开端
    最全华为鸿蒙 HarmonyOS 开发资料汇总
    iPhone X适配方案
    前端程序员经常忽视的一个JavaScript面试题
    vs for Mac 升级后编译原项目提示找不到“.NETFramework,Version=v5.0”的引用程序集
    使用FastReport的BarCode2D控件生成含中文的PDF417条形码
    vs for Mac中的启用Entity Framework Core .NET命令行工具
    64位Windows7升级IE11后无法启动的解决办法
  • 原文地址:https://www.cnblogs.com/raybiolee/p/5870348.html
Copyright © 2011-2022 走看看