Greasy Fork

Greasy Fork is available in English.

Pixiv save image with name format

Save pixiv image with custom name format

当前为 2018-06-30 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Pixiv save image with name format
// @namespace    https://blog.maple3142.net/
// @version      0.1
// @description  Save pixiv image with custom name format
// @author       maple3142
// @match        https://www.pixiv.net/member_illust.php?mode=medium&illust_id=*
// @connect      pximg.net
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict'
    const FILENAME_TEMPLATE='{{title}}-{{userName}}-{{id}}'

    const $=s=>document.querySelector(s)
    const $$=s=>[...document.querySelectorAll(s)]
    const elementmerge = (a , b ) => {
        Object.keys(b).forEach(k => {
            if (typeof b[k] === 'object') elementmerge(a[k], b[k])
            else if(k in a)a[k] = b[k]
            else a.setAttribute(k,b[k])
        })
    }
    const $el = (s, o) => {
        const el = document.createElement(s)
        elementmerge(el, o)
        return el
    }
    const debounce=delay=>fn=>{
        let de=false
        return (...args)=>{
            if(de)return
            de=true
            fn(...args)
            setTimeout(()=>(de=false),delay)
        }
    }
    const download=(url,fname)=>{
        const a=$el('a',{href:url,download:fname||true})
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
    }
    const gmxhr=o=>new Promise((res,rej)=>GM_xmlhttpRequest({...o,onload:res,onerror:rej}))

    function main(){
        const params=new URLSearchParams(location.search)
        const getIllustData=(id=params.get('illust_id'))=>fetch(`/ajax/illust/${id}`,{ credentials: 'same-origin' }).then(r=>r.json()).then(r=>r.body)
        const saveImage=(format=FILENAME_TEMPLATE,id=params.get('illust_id'))=>{
            getIllustData(id).then(data=>{
                const fname=format.replace(/{{(\w+?)}}/g,(m,g1)=>data[g1])
                const url=data.urls.original
                const ext=url.split('/').pop().split('.').pop()
                return Promise.all([fname+'.'+ext,gmxhr({method:'GET',url,responseType:'blob',headers:{Referer:'https://www.pixiv.net/'}})])
            }).then(([f,xhr])=>{
                const url=URL.createObjectURL(xhr.response)
                download(url,f)
                URL.revokeObjectURL(xhr.response)
            })
        }
        const observer=new MutationObserver(debounce(10)(mut=>{
            const menu=$('ul[role=menu]')
            if(!menu)return
            const n=menu.children.length
            const item=$el('li',{role:'menuitem',onclick:()=>saveImage()})
            item.className=menu.children[n-2].className
            const text=$el('span',{textContent:'⬇'})
            item.appendChild(text)
            menu.insertBefore(item,menu.children[n-1])
        }))
        const start=()=>observer.observe($('.sticky'),{childList:true,subtree:true})
        if(!$('.sticky'))setTimeout(start,1000)
        else start()
        if(!unsafeWindow.__$maple3142$_savePivivImage)Object.defineProperty(unsafeWindow,'__$maple3142$_savePivivImage',{
            get: ()=>saveImage,
            enumerable: false
        })
    }

    //ajax change
    let lasturl
    setInterval(()=>{
        if(location.href==lasturl)return
        lasturl=location.href
        main()
    },1000)
})()