分类 语言编程 下的文章

概况

家里的NAS是我主要文件存储系统,Aria2作为日常常用下载工具也一同部署在上面。

该Aria2以docker容器的形式部署,这样可以带来更好的独立性以便于日常维护。由于众所周知的原因,尝试过一段时间通过openwrt对其进行留学分流,但效果不是太理想。总会发生偶发性的偷跑流量情况,且会损失部分下载速度。为避免钱袋受到伤害,最终还是把Aria2设置为直连方式下载。

aria2NG

直连方式也带来一个问题:部分种子在墙外被限制直连,若直接将链接地址发送到Aria2,是无法被正确下载的。每次遇到这种情况,我只能先通过浏览器把种子文件下载下来后,再通过Aria2NG发种子发送到Aria2进行下载,显得比较繁琐。Aria2NG也有一个问题:每次只能上传一个种子。如果有多个种子文件,操作就显得相当机械繁琐而无趣。我想,能不能一步到位直接把下载好的种子文件统一推送到Aria2自行下载呢?搜索了一下,果然有老哥为此建了个项目,该项目是通过xmlrpc的方式管理Aria2,但缺少密钥验证功能。因此我拿该大佬的项目改了一下,以支持密钥验证方式。有需要的朋友可以直接抄下作业。

实现我需求的思路主要是两个部分,第一部分是脚本处理,第二部分是系统快捷键的部署(我的是MacOS,win部分可能需要一些系统快捷键软件支持才能实现)。

批量提交BT文件到Aria2

脚本

import xmlrpc.client
import xmlrpc
import os
import argparse

def handle(s, btFile, token):
    print('handle bittorrent file: ', str(btFile))
    token = "token:" + token
    ret=s.aria2.addTorrent(token,xmlrpc.client.Binary(open(btFile, mode='rb').read()),[],{'pause':'true'})
    print("add bt: ",str(ret))
    waiting = s.aria2.tellWaiting(token,0, 1000,
                              ["gid", "totalLength", "completedLength", "uploadSpeed", "downloadSpeed", "connections",
                               "numSeeders", "seeder", "status", "errorCode", "verifiedLength",
                               "verifyIntegrityPending", "files", "bittorrent", "infoHash"])
    for w in waiting:
        gid=w['gid']
        if gid!=ret:
            continue
        #print(w['gid'],w['files'])
        # max-selection strategy
        maxLen=0
        maxFPath=''
        maxFIndex='0'
        for f in w['files']:
            #print(f['length'],f['path'])
            if int(f['length'])>maxLen:
                maxLen=int(f['length'])
                maxFPath=f['path']
                maxFIndex=f['index']
        print('max file: ',str(maxLen),maxFIndex,str(maxFPath))
        # max-selection strategy end
        cret=s.aria2.changeOption(token,gid,{'select-file':maxFIndex})# select multiple files example: 'select-file':'5,6,7,8'
        print('select file: ',cret)
        tret=s.aria2.tellStatus(token,gid)
        print('after selection: ', tret['files'][int(maxFIndex)-1])
        uret=s.aria2.unpause(token,gid)
        print('unpause: ',uret)
    print('over: ',str(btFile))



if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.description = 'bt批量导入aria2,并选择文件大小最大的文件进行下载'
    parser.add_argument("server", help="like: http://192.168.3.99:6800", type=str)
    parser.add_argument("token", help="验证密钥", type=str)
    parser.add_argument("dir", help="存放种子目录", type=str)
    args = parser.parse_args()
    s = xmlrpc.client.ServerProxy(args.server+"/rpc")
    flist=os.listdir(args.dir)
    for i in range(0, len(flist)):
        if flist[i].endswith(".torrent"):
            btFile = os.path.join(args.dir, flist[i])
            if os.path.isfile(btFile):
                handle(s,btFile, args.token)
    print("Done")

使用方法

把上述代码保存为bb2a.py,需要使用Python3运行。

帮助(Help):

python3 bb2a.py --help

启动(Start to Add):

python3 bb2a.py <server> <token> <bt-dir>

参数(parameters):

server      如(like): http://192.168.3.99:6800
token       验证密钥:设置在Aria2配置文件的密钥
bt-dir      bt文件的目录(the dir of your bittorrents)

例子(example):

python3 /path/to/bb2a.py http://192.168.1.100:6800 123456 /home/root/bts/

MacOS增加快捷指令

command + 空格,在快捷运行窗口输入“快捷指令”打开系统的快捷指令模块。点击窗口右上角➕新增一个快捷指令。
新增快速指令1.png

按照下图方式创建快捷指令内容
新增快速指令2.png

参考shell内容如下,请按照自己配置情况修改相关参数。sleep 3是暂停3秒。后面的rm命令是顺便删除下载目录中的bt种子文件。

python3 /Users/ccchen/autobt/bb2a.py http://192.168.12.5:6800 123456 /Volumes/FAT12T/down2025/
sleep 3
rm -f  /Volumes/FAT12T/down2025/*.torrent

按窗口右上角的详情按钮,设置快捷指令的允许执行shell权限。
新增快速指令3.png

最后给快捷指令设置快捷键.我设置的快捷键是“Ctrl + Option + W”这个组合键。
新增快速指令4.png

完结

到此,所有配置已完成。只要下载bt种子到对应的目录。完毕后按快捷键“Ctrl + Option + W”,脚本便自动将该目录中所有种子文件发送到aria2进行下载。同时会把下载目录中对应的种子清理掉。


前些天把主机的PHP版本升级到8.0。博客程序typecho也升级到1.2

typecho上一个稳定版本已经是5年前的事情了。在免费项目中,这类更新速度一般会被假定为濒死或死亡项目。附着的插件和模板项目也日渐式微。我使用熊猫的模板和部分插件现在也不更新了。升级typecho后,直接500错误。

期待已死亡项目的作者会给新程序做更新匹配?不太可能。眼下只有自己动手这条路子了。

于是,我断断续续花了点时间把不兼容的模板和插件进行匹配更改,顺道也把有一段时间没有接触的PHP新版本特性给补全一下。

这次更新还让我想起前段时间的一个小事情。

事情的经过是这样的:

前段时间单位有个同事联系我,让我维护一个大约10年前开发的小项目。项目主要是为实现部门一个简单的需求。因为这需求实在太小,我选择用自己最熟悉的PHP方案,并独立完成了开发。这次问题也不大,只是当初没有设想那么长远,字段设置范围超限了,不算大问题。

这同事半新人,科班出身,应该不会在这问题遇到困难。但,这同事表示自己不会PHP,还来了一句(原话):“现在谁还会用PHP开发程序啊?”我思索了一下这同事的话,好像对又好像不对,然后回答说:哦,是啊。

我现在虽然用PHP的情况不多。不过,“PHP是最好的编程语言”(不接受任何辩驳)。


TimeMachine.png

过去一段时间,家里路由配置一直是“主iKuai,旁koolshare”组合。这个组合已经稳定工作有2年多时间。

由于koolshare维护状态已经进入“濒死”阶段,为保障家里网络服务稳定,于是决定对这路由系统进行改造。

简单研判了一下,决定选择”主ROS,旁openWRT“方案。

母机是PVE,这样搭配很速度就撸出来。为节省资源,我把原来omv主机删掉,把MacOS的备份系统直接转移到openWRT上。

按照官方提供的配置方案顺利部署好AFP服务器。不过问题来了。无论我使用MacOS的网络模块还是用ssh的方式连接openWRT的afp能连接,但是无法验证登录。

检查了afp的log文件,没有发现异常。琢磨半天是不是类似SMB协议那样需要有个用户账户转换问题。翻遍AFP的官方文档,没能找到解决方案。

谷歌爬文半天也未能找到解决方案。准备重做omv之际,我重新看了一下afp的log文件,发现登录过程只记录了很简单的一句:

{afp_dsi.c:108} (note:AFPDaemon): AFP statistics: 0.06 KB read, 0.06 KB written}

然后查找AFP文档发现默认的log等级比较简单,没有记录debug内容于是修改afp.conf文件的log level:

[Global]
; Global server settings
log file = /var/log/afpd.log
log level = default:maxdebug uamsdaemon:maxdebug afpdaemon:maxdebug
afp interfaces = br-lan

再次测试登录afp,然后查看log文件发现问题所在:

PAM DHX2: libgcrypt versions mismatch
由于libgcrypt缺失,造成无法使用PAM验证登录。

在ssh中直接执行

   opkg update && opkg install libgcrypt

片刻安装成功,重启afp,并重新测试登录afp。这次,密码验证成功,顺利登录。

最后测试MacOS的TimeMachine备份也正常了。


最近打算部署一个小项目。由于预算原因,便宜购置了台微型VPS。微型VPS带来的麻烦事是:内存拮据和IO效率不行,只能使用较低版本的MySQL数据服务器。本来想使用Drupal作为脚本程序,MySQL数据库服务版本太低无法适配。

之后对比了多个方案,最终选择直接部署基于Django框架的CMS程序Wagtail。

wagtail.png

本地调试Python用台式电脑还凑合。不过,MBP由于内存本来就比较吃紧,还拖个内存大户MySQL就显得有点累赘了。SQLite虽然是Django自带能开箱即用,不过管理显得有点麻烦,也比较吃IO。综上,我把MySQL服务器部署在家里的NAS上,方便不同设备进行调试。

我本机没有安装MySQL,所以也没有自带Python连接MySQL的驱动。Django自带的django.db.backends.mysql模块默认是使用MySQL Client进行连接的。网上的教程来来去去都是教你怎么样把MySQL Client给安装上去。无论是Brew方式安装还是通过官方的安装包安装,都需要先安装MySQL。对于Brew,系统还提示我使用的是Big Sur版本的系统,可能遭遇不可预计的缺陷。

不管三七二十一,撸上再说。结果,得益于GFW的作用,到安装MySQL的环节,老死下载不下来。实在受不了这样的折腾,心想MySQL这样流行的数据库服务器,不可能没有官方的Python驱动的。于是在MySQL的官方查询了一下,果然有官方的驱动,名字叫”MySQL Connector/Python"。真是踏破铁鞋无觅处,得来全不费工夫。

直接用pip给装上。

    pip install mysql-connector-python

不一会儿功夫,顺利安装上。顺便配置好Django的连接信息:

    import mysql.connector

    DATABASES = {
        'default': {
            'ENGINE': 'mysql.connector.django',
            'NAME': 'dbname',
            'USER': 'dbuser',
            'PASSWORD': '123456',
            'HOST': '192.168.11.240',
            'PORT': 3306,
        }
    }

重建一下数据,顺利启动项目。

这次在安装MySQL Client上浪费了点时间,真的学艺不精到处是坑。


由于好奇心重而且比较贪玩,喜欢尝试不同的东西。也为便于记录生活,很久前我还部署了一个专门用于存放手机随手拍照片的博客。该博客是基于WordPress系统,地址:https://www.ccchen.com

因为访问量非常低,而且也不想再倒腾备案的事情。所以,我决定让它留在linode上,毕竟还有4个多月的免费使用时间呢:D。

今天抽空把digitalocean上的系统删掉,顺便把linode上的WordPress修整了一下。主要是作提高访问速度和风格简单的修正处理。

1、图片用了又拍云的免费CDN加速功能。为了节省系统资源没有用外接插件,直接在风格的模板函数文件functions.php头部加入了下面的代码。有需要的朋友可以参考一下,把CDN_HOST的值替换你的cdn地址即可。

    //将本地图片地址替换为CDN地址
    define('CDN_HOST','//ccchen.gdcn.net');
    add_filter('the_content','z_cdn_content');
    function z_cdn_content($content){
        return str_replace(home_url().'/wp-content/uploads', CDN_HOST.'/wp-content/uploads', $content);
        }
        add_filter('wp_get_attachment_url','z_get_attachment_url',10,2);
    function z_get_attachment_url($url, $post_id){
        return str_replace(home_url(), CDN_HOST, $url);
        }
    add_filter( 'post_thumbnail_html', 'cdn_post_image_html', 10, 3 ); 
    function cdn_post_image_html( $html, $post_id, $post_image_id ) {  
        return str_replace(home_url(), CDN_HOST, $html); 
    }  
    
    //强行插入特色图片
    
    function wpforce_featured() {
        global $post;
        $already_has_thumb = has_post_thumbnail($post->ID);
        if (!$already_has_thumb)  {
            $attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
            if ($attached_image) {
                foreach ($attached_image as $attachment_id => $attachment) {
                    set_post_thumbnail($post->ID, $attachment_id);
                }
            } else {
                set_post_thumbnail($post->ID, '414');
            }
        }
    }  //end function
    add_action('the_post', 'wpforce_featured');
    add_action('save_post', 'wpforce_featured');
    add_action('draft_to_publish', 'wpforce_featured');
    add_action('new_to_publish', 'wpforce_featured');
    add_action('pending_to_publish', 'wpforce_featured');
    add_action('future_to_publish', 'wpforce_featured');

2、使用cloudflare加速普通文件访问速度,解决linode间歇断流问题。在页面规则(Page Rules)里面按照下图配置一个缓存规则即可。有需要的可以参考一下。
cloudflare

个人主观感受,还是有比较明显的提速效果。

以上。