PixivUserBatchDownload icon indicating copy to clipboard operation
PixivUserBatchDownload copied to clipboard

可否有一个“根据作者UID来匹配本地作者文件夹”的功能

Open mafeichang opened this issue 4 years ago • 8 comments

用了一年多,这个插件真的很好用,主要还是能够自己写规则,非常感谢作者

用到现在有一个比较困扰我的问题就是P站作者文件夹的创建,你也知道P站作者真的隔三差五就改一下名字,每次都要自己搜一下UID再看看本地保存的作者名和最新作者名是不是一样才能去下载,要是不一致就会新建一个作者名文件夹去重复下载了。

当然如果本地文件夹是只采取UID纯数字的文件夹来表示的话是没有问题的,但是这又不方便记录,纯数字文件夹很难想起哪个作者对应哪个UID。

就算我再把过滤规则写得再长,总会有些作者名是不使用任何分隔符直接在后面加上摊位名的,或者写上小消息的(我还看过把摊位名摆前面然后加冒号再接作者名的……)

所以我是想能不能读取本地下载目录下的文件夹目录(单层),然后去匹配文件夹的UID,匹配成功则以该文件夹为路径进行下载,无有效匹配则新建文件夹。

这样起码不会同一个作者出现好几个文件夹,导致重复下载。 我对浏览器插件不熟,不清楚能否对本地目录进行读取,或者可以以手动的方式输入本地目录list ?

再次非常感谢作者

mafeichang avatar Apr 01 '20 04:04 mafeichang

很抱歉,这个功能 PUBD 自身从技术上无法实现。 PUBD 自身只有浏览器网页内部权限,无法获取任何本地路径。PUBD 将下载路径交给Aria2后,工作就结束了。

替代方式:

  1. 不使用user.name,而使用user.account,账户名是不容易经常更改的(但还是可以随时修改),而且缺点就是都是英文。
  2. 使用switch来针对某些作者返回特定字符串。
    switch(user.id)
    {
      case 3896348:
        '枫谷剑仙';
      case 61513:
        'ideolo';
      default: //其他一般规则
        user.name.split(/[@@★]/)[0];
    }
    
    以上是代码原理,具体写成掩码,如果多的话就很长了。
  3. 实现3.x版本的实验性功能,参见:自定义文件夹
    使用文本输出模式,生成Desktop.ini,使其在Windows系统下可以显示伪名。
    但是因为这个功能不是很完美,所以5.x我没有加入。目前的文本输出模式并不好处理成Desktop.ini
  4. 自己利用“Aria2的下载完成后调用脚本”功能来实现。
    https://aria2.github.io/manual/en/html/aria2c.html#cmdoption-on-download-complete

你说说你的想法?

Mapaler avatar Apr 01 '20 08:04 Mapaler

很抱歉,这个功能 PUBD 自身从技术上无法实现。 PUBD 自身只有浏览器网页内部权限,无法获取任何本地路径。PUBD 将下载路径交给Aria2后,工作就结束了。

替代方式:

  1. 不使用user.name,而使用user.account,账户名是不容易经常更改的(但还是可以随时修改),而且缺点就是都是英文。

  2. 使用switch来针对某些作者返回特定字符串。

    switch(user.id)
    {
      case 3896348:
        '枫谷剑仙';
      case 61513:
        'ideolo';
      default: //其他一般规则
        user.name.split(/[@@★]/)[0];
    }
    

    以上是代码原理,具体写成掩码,如果多的话就很长了。

  3. 实现3.x版本的实验性功能,参见:自定义文件夹 使用文本输出模式,生成Desktop.ini,使其在Windows系统下可以显示伪名。 但是因为这个功能不是很完美,所以5.x我没有加入。目前的文本输出模式并不好处理成Desktop.ini

  4. 自己利用“Aria2的下载完成后调用脚本”功能来实现。 https://aria2.github.io/manual/en/html/aria2c.html#cmdoption-on-download-complete

你说说你的想法?

谢谢答复

方案3 这种方法我头次看见,不清楚这个伪名可否被搜索到(everything等本地搜索软件),如果可以被搜索到名字的话确实是一种解决方法 方案4 因为是在下载前进行预判文件夹是否存在(如果存在的话就可以利用ARIA2的不下载已存在的文件这一功能了,省得重复下载)所以可能不太适合

我的想法跟方案2比较接近,就是将“作者名”+"UID"以文本方式(key-value的list)载入再用JS格式化成键值对。 伪代码:

list = {'<UID>':'<画师名>', '<UID2>':'<画师名2>'}
if UID in list:
    folder_name = list['UID'] + UID
else:
    folder_name = user.name.split(/[@@★]/)[0]

其实就是想要脚本自带一个“画师文件夹路径”的自定义掩码设置吧,以文本格式导入画师名和UID,再格式化输出文件夹路径。

写着写着发现好像是能自己写来着……就是800多个画师写起来太长了……

mafeichang avatar Apr 02 '20 03:04 mafeichang

Screenshot_2020-04-02-11-35-45 方法3其实可能你每天都有见到,只是你不知道而已,XP年代就是这样了。但是我就注意到“附件”里的“记事本”真实文件名是Notepad.lnk
这个只有Windows才识别,其他第三方资源管理器就现原形了。

Screenshot_2020-04-02-11-33-42 当然这个名称也是无法被搜索到的。


至于方法2,JS可以这样写

var usernameRedirect = [];
usernameRedirect[10000] = '1万';
usernameRedirect[100000] = '10万';
usernameRedirect[1000000] = '100万';
usernameRedirect[10000000] = '1000万';
usernameRedirect[100000000] = '1亿';
console.log('数组本身 %o,9999号:%o,1万号:%o'
            ,usernameRedirect
            ,usernameRedirect[9999]
            ,usernameRedirect[10000]
           );
//建立数组后,调用就只需要这一行代码
//usernameRedirect[userid] ? usernameRedirect[userid] : 没有定义的其他操作模式
var userid = 10000;
console.log(usernameRedirect[userid] ? usernameRedirect[userid] : userid);
var userid = 9999;
console.log(usernameRedirect[userid] ? usernameRedirect[userid] : userid);

这是输出结果 Screenshot_2020-04-02-11-49-14

就是先建立一个空数组,然后直接定义多个数组名[用户ID]=用户名,就好了,空白的地方会直接返回undefined的,布尔判断为false。

Mapaler avatar Apr 02 '20 03:04 Mapaler

未来的计划,下个大版本我会取消目前的掩码书写方式,改用ES6原生的模板字符串,这样可以方便的书写函数而不需要写我自己的转义符。和目前的掩码差不多,但少数可能需要进行小修改。

看了你的这个需求,我考虑废除自定义掩码,变成用一个多行输入框直接输入所有自定义数组、函数等。

Mapaler avatar Apr 02 '20 03:04 Mapaler

未来的计划,下个大版本我会取消目前的掩码书写方式,改用ES6原生的模板字符串,这样可以方便的书写函数而不需要写我自己的转义符。和目前的掩码差不多,但少数可能需要进行小修改。

看了你的这个需求,我考虑废除自定义掩码,变成用一个多行输入框直接输入所有自定义数组、函数等。

确实自定义掩码单行的话易读性是不太好,有时手滑删掉1个字符之后没找着哪里缺漏了。

你给的数组解决方法很棒,方便维护,我的问题就到此为此了,非常感谢你。

mafeichang avatar Apr 02 '20 04:04 mafeichang

确实自定义掩码单行的话易读性是不太好,有时手滑删掉1个字符之后没找着哪里缺漏了。

我这几年这在编其他程序的过程中发现的,整个程序现在写的话也会有很多地方代码不一样。只不过我现在都还没搞明白 JS 的类继承,要不然还可以再进一步。买的基础书半年了才翻到局部变量那里。

Mapaler avatar Apr 02 '20 04:04 Mapaler

建立一块代码区域的实现方式怎么做比较好?

  1. 第一种,直接执行所有代码,好处是不会JS也容易学JS理解。缺点是如果可能覆盖全局变量。
    eval(用户代码);
    //实现为这样
    var 全局变量 = 任何内容;
    function 全局函数() {
        函数内容
    }
    //使用时
    `我的自定义代码${全局函数(全局变量)}`
    
  2. 第二种,在对象里执行代码,好处是可以限定用户代码全部收集在一个对象里。缺点是写起来多了一个对象名比较麻烦。
    var userObj = {
       eval(用户代码);
    };
    //实现为这样
    var userObj = {
        自定义变量: 任何内容,
        自定义函数: function() {
            函数内容
        }
    }
    //使用时
    `我的自定义代码${userObj.自定义函数(userObj.自定义变量)}`
    
  3. 第三种,使用自定义函数来代替自定义掩码。
    var 自定义函数 = new Function('user', 'illust', 'page', 用户代码);
    //实现为这样
    var 多图ID = new Function('user', 'illust', 'page', 'return (illust.page_count>1 || illust.type=="ugoira") ? "/"+illust.id : ""');
    //使用时
    `我的自定义代码${多图ID(user,illust,page)}`
    

Mapaler avatar Apr 03 '20 08:04 Mapaler

Screenshot_2020-04-03-16-12-24 如果在外部先定义自定义函数,那么在函数内部就调用不了 'user', 'illust', 'page' 了,但是在内部再每次去生成一次函数,又感觉对性能有影响。

Mapaler avatar Apr 03 '20 08:04 Mapaler