用于bcy.net api的python接口

PyBCY的Python项目详细描述


这是cosplay网站bcy.net的python实现。测试 在Python身上。对Python3也有效

变更日志

1.2.4

修复了工作信息以base64编码格式保存的遗留问题。到 更新现有数据库,运行此Python脚本(在Python上进行测试):

importsqlite3,os,sys,json,base64savepath="/PATH/TO/DOWNLOAD/FOLDER/"InfoSQL=sqlite3.connect(os.path.join(savepath,"BCYInfo.db"))Cursor=InfoSQL.execute("SELECT Info from WorkInfo").fetchall()i=1foriteminCursor:try:print("Re-encoding "+str(i)+"/"+str(len(Cursor)))i=i+1Info=item[0]values=list()DecodedData=base64.b64decode(Info)DecodedInfo=json.loads(DecodedData)values.append(json.dumps(DecodedInfo))values.append(Info)InfoSQL.execute("UPDATE WorkInfo SET Info=? WHERE Info=?",values)except:passInfoSQL.commit()

1.2.6

强制downloadWorker使用/PATH/TO/DOWNLOAD/FOLDER/DownloadTemp/ 作为减少I/O成本的临时文件1.2.8使用后进先出队列以获得更好的效果 打开httpserver时的总体性能

1.3.2

重命名sql数据库列以获得更好的扩展性和整体性 性能。
sqlite3 BCYInfo.db ".dump 'WorkInfo'" |grep -v 'CREATE TABLE' > BCYInfodump.sql
echo "CREATE TABLE IF NOT EXISTS WorkInfo (uid STRING NOT NULL DEFAULT '',Title STRING NOT NULL DEFAULT '',cp_id STRING NOT NULL DEFAULT '',rp_id STRING NOT NULL DEFAULT '',dp_id STRING NOT NULL DEFAULT '',ud_id STRING NOT NULL DEFAULT '',post_id STRING NOT NULL DEFAULT '',Info STRING NOT NULL DEFAULT '',UNIQUE(UID,cp_id,rp_id,dp_id,ud_id,post_id) ON CONFLICT REPLACE);CREATE TABLE IF NOT EXISTS UserInfo (uid STRING,UserName STRING);CREATE TABLE IF NOT EXISTS GroupInfo (gid STRING,GroupName STRING);" > tmp.sql
sqlite3 BCYInfoNew.db < tmp.sql

sed -i.bak  's/NULL/'"'0'"'/g' ./BCYInfodump.sql
sqlite3 BCYInfoNew.db < BCYInfodump.sql
sqlite3 BCYUserNameUID.db ".dump 'GroupInfo'" |grep -v 'CREATE TABLE' > GInfo.sql
sqlite3 BCYUserNameUID.db ".dump 'UserInfo'" |grep -v 'CREATE TABLE' > UInfo.sql
sed -i.bak  's/GID/gid/g' ./GInfo.sql
sed -i.bak  's/UID/uid/g' ./UInfo.sql
sqlite3 BCYInfoNew.db < GInfo.sql
sqlite3 BCYInfoNew.db < UInfo.sql

rm BCYInfodump.sql
rm tmp.sql

然后将bcyinfonew.db重命名为bcyinfo.db,删除bcyusernameuid.db。 如果需要,请备份旧的

1.3.5

为标记添加了单独的列,其中包含JSON序列化版本 标签列表的

ALTER TABLE WorkInfo ADD COLUMN Tags STRING;

并运行python脚本:

importsqlite3,os,sys,jsonsavepath="/PATH/TO/DOWNLOAD/ROOT/"InfoSQL=sqlite3.connect(os.path.join(savepath,"BCYInfo.db"))Cursor=InfoSQL.execute("SELECT Info from WorkInfo").fetchall()i=1foriteminCursor:Info=Nonetry:print("Re-encoding "+str(i)+"/"+str(len(Cursor)))i=i+1values=list()TagList=list()raw=item[0]Info=json.loads(raw)foriteminInfo.get("post_tags",list()):TagList.append(item["tag_name"])values.append(json.dumps(TagList,separators=(',',':'),ensure_ascii=False,encoding='utf8'))values.append(raw)InfoSQL.execute("UPDATE WorkInfo SET Tags=? WHERE Info=?",values)except:InfoSQL.commit()printInforaise

1.4.0

bcycore中重命名了详细方法签名。结果:
+查询速度更快(更稳定)

这对你没有影响,除非你不使用细节 包装纸

1.4.4

sinceto关键字已添加到BCYDownloadUtils中 使用**kwargs迭代方法。这会加速列表 迭代次数

1.6.1

python3兼容

1.7.0

添加喜欢/不喜欢的工作。报告工作

1.7.1

修正encryptparam()中的问题导致非ascii字符串失败 编码

1.7.5

修复使用groupid构造的BCYDownloadUtils中的问题 标题而不是帖子ID。

importsqlite3,os,sys,json,base64,ossavepath="/PATH/TO/FOLDER"InfoSQL=sqlite3.connect(os.path.join(savepath,"BCYInfo.db"))GroupNameList=list()GroupsCursor=InfoSQL.execute("SELECT GroupName from GroupInfo").fetchall()foriteminGroupNameList:print("Found GroupName:"+item[0])GroupNameList.append(item[0])Cursor=InfoSQL.execute("SELECT uid,Title,Info from WorkInfo").fetchall()foriteminCursor:try:print("Re-encoding "+str(i)+"/"+str(len(Cursor)))UserName=InfoSQL.execute("SELECT UserName FROM UserInfo WHERE uid=?",(item[0],)).next()[0]Title=item[1]DecodedInfo=json.loads(item[2])forGNameinGroupNameList:ifTitle.beginsWith(GName+"-")and("post_id"inDecodedInfo.keys()):newTitle=GName+"-"+DecodedInfo["post_id"]InfoSQL.execute("UPDATE WorkInfo SET Title=? Title=?",(newTitle,Title,))print("Replaced "+UserName+"'s GroupWorkTitle:"+newTitle)#Move FoldersPathRoot=os.path.join(savepath,UserName)OldPath=os.path.join(PathRoot,Title)newPath=os.path.join(PathRoot,newTitle)os.rename(OldPath,newPath)except:raiseInfoSQL.commit()

1.9.0

向所有表添加唯一约束。更好的迭代器状态 保存

sqlite3 /PATH/TO/NEW/TABLE/BCYInfo.db
CREATE TABLE IF NOT EXISTS UserInfo (uid STRING,UserName STRING,UNIQUE(uid) ON CONFLICT IGNORE);
CREATE TABLE IF NOT EXISTS GroupInfo (gid STRING,GroupName STRING,UNIQUE(gid) ON CONFLICT IGNORE);
CREATE TABLE IF NOT EXISTS WorkInfo (uid STRING NOT NULL DEFAULT '',Title STRING NOT NULL DEFAULT '',cp_id STRING NOT NULL DEFAULT '',rp_id STRING NOT NULL DEFAULT '',dp_id STRING NOT NULL DEFAULT '',ud_id STRING NOT NULL DEFAULT '',post_id STRING NOT NULL DEFAULT '',Info STRING NOT NULL DEFAULT '',Tags STRING,UNIQUE(UID,cp_id,rp_id,dp_id,ud_id,post_id) ON CONFLICT REPLACE);

然后应用旧表的转储

sqlite3 /PATH/TO/OLD/TABLE/BCYInfo.db .dump >DUMP.SQL
sqlite3 /PATH/TO/NEW/TABLE/BCYInfo.db < DUMP.SQL

2.4.0

使用integer作为workinfo相关列的数据类型。 python3迁移脚本

importsqlite3importjsonInfoSQL=sqlite3.connect("OLD/DATABASE/")NewSQL=sqlite3.connect("NEW/DATABASE/")InfoSQL.text_factory=strNewSQL.text_factory=strNewSQL.execute("CREATE TABLE IF NOT EXISTS UserInfo (uid STRING,UserName STRING,UNIQUE(uid) ON CONFLICT IGNORE);")NewSQL.execute("CREATE TABLE IF NOT EXISTS GroupInfo (gid STRING,GroupName STRING,UNIQUE(gid) ON CONFLICT IGNORE);")NewSQL.execute("CREATE TABLE IF NOT EXISTS WorkInfo (uid INTEGER DEFAULT 0,Title STRING NOT NULL DEFAULT '',cp_id INTEGER DEFAULT 0,rp_id INTEGER DEFAULT 0,dp_id INTEGER DEFAULT 0,ud_id INTEGER DEFAULT 0,post_id INTEGER DEFAULT 0,Info STRING NOT NULL DEFAULT '',Tags STRING,UNIQUE(uid,cp_id,rp_id,dp_id,ud_id,post_id) ON CONFLICT REPLACE);")Cursor=InfoSQL.execute("SELECT Title,Info FROM WorkInfo").fetchall()index=1foriteminCursor:Title=item[0]Info=json.loads(item[1])tags=list()args=list()args.append(int(Info["uid"]))args.append(Title)args.append(int(Info.get("cp_id",0)))args.append(int(Info.get("rp_id",0)))args.append(int(Info.get("dp_id",0)))args.append(int(Info.get("ud_id",0)))args.append(int(Info.get("post_id",0)))args.append(item[1])forfooinInfo.get("post_tags",list()):tags.append(foo["tag_name"])args.append(json.dumps(tags))NewSQL.execute("INSERT OR REPLACE INTO WorkInfo(uid,Title,cp_id,rp_id,dp_id,ud_id,post_id,Info,Tags) VALUES(?,?,?,?,?,?,?,?,?)",tuple(args))print("WorkInfo Update:%i/%i"%(index,len(Cursor)))index=index+1index=1Cursor=InfoSQL.execute("SELECT gid,GroupName FROM GroupInfo").fetchall()foriteminCursor:NewSQL.execute("INSERT OR REPLACE INTO GroupInfo(gid,GroupName) VALUES(?,?)",(int(item[0]),item[1]))print("GroupInfo Update:%i/%i"%(index,len(Cursor)))index=index+1index=1Cursor=InfoSQL.execute("SELECT uid,UserName FROM UserInfo").fetchall()foriteminCursor:NewSQL.execute("INSERT OR REPLACE INTO UserInfo(uid,UserName) VALUES(?,?)",(int(item[0]),item[1]))print("UserInfo Update:%i/%i"%(index,len(Cursor)))index=index+1NewSQL.commit()NewSQL.close()InfoSQL.close()

然后用新数据库替换旧数据库

2.5.2

修复旧问题会导致保存空标识符。重新运行 2.4.0的迁移脚本

2.7.0

实现数据库版本检查并将uid分发到更小的 子文件夹以减少文件系统负载。
迁移脚本:
importsqlite3,os,shutil,errnoBasePath="PATH/TO/DOWNLOAD/ROOT"SQL=sqlite3.connect(os.path.join(BasePath,"BCYInfo.db"))Cursor=SQL.execute("SELECT UID,UserName FROM UserInfo").fetchall()index=1length=len(Cursor)foriteminCursor:UID=int(item[0])UserName=item[1]L1Path=UID%10L2Path=(int((UID-L1Path)/10))%10OriginalPath=os.path.join(BasePath,str(UserName))SavePath=os.path.join(BasePath,str(L1Path),str(L2Path),str(UID))try:os.makedirs(os.path.join(BasePath,str(L1Path),str(L2Path)))exceptOSErrorase:ife.errno!=errno.EEXIST:raiseeifos.path.isdir(OriginalPath):shutil.move(OriginalPath,SavePath)print("Moved %s to %s"%(OriginalPath,SavePath))print("%i/%i"%(index,length))index=index+1SQL.execute("INSERT OR REPLACE INTO PyBCY(Key,Value) VALUES(\"Version\",\"2.7.0\");")SQL.commit()SQL.close()
请注意,从现在起,uid存储在两级子文件夹中。
示例:具有uid 12345的用户现在存储在saveroot/5/4/12345中

2.7.8

在数据库中存储筛选器以简化调用方使用的初始化过程 sqlite3使用以下命令创建新数据库:

CREATE TABLE IF NOT EXISTS UserInfo (uid INTEGER,UserName STRING,UNIQUE(uid) ON CONFLICT IGNORE);
CREATE TABLE IF NOT EXISTS GroupInfo (gid INTEGER,GroupName STRING,UNIQUE(gid) ON CONFLICT IGNORE);
CREATE TABLE IF NOT EXISTS WorkInfo (uid INTEGER DEFAULT 0,Title STRING NOT NULL DEFAULT '',cp_id INTEGER DEFAULT 0,rp_id INTEGER DEFAULT 0,dp_id INTEGER DEFAULT 0,ud_id INTEGER DEFAULT 0,post_id INTEGER DEFAULT 0,Info STRING NOT NULL DEFAULT '',Tags STRING,UNIQUE(uid,cp_id,rp_id,dp_id,ud_id,post_id) ON CONFLICT REPLACE);
CREATE TABLE IF NOT EXISTS PyBCY (Key STRING DEFAULT '',Value STRING NOT NULL DEFAULT '',UNIQUE(Key) ON CONFLICT IGNORE);
PRAGMA journal_mode=WAL;
INSERT INTO PyBCY(Key,Value) VALUES("Version","2.7.8");

然后应用旧转储文件

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
使用jaxrpc的Java eclipse WebService客户端   java编程方式在对象上写入名称   java Spring批处理:重试后跳过   java Android错误:错误:任务执行失败:应用程序:transformClassesWithDexForDebug'   带有清单文件nullPointerException的java Android元数据   spring Java Quartz调度作业停止运行   JavaMockito:如何在不调用实际方法的情况下,模拟带有参数和无效返回类型的静态方法?   java Tomcat连接池问题无法在关闭的连接上调用方法   java如何交换列表中的项目?   java如何停止线程并通过Toast在线程中正确显示文本?   java为什么连续写入OutputStream时偏移量0不会导致重复字节?   java我无法生成头文件   不兼容的返回类型错误java   修改值后键值对的java Jolt转换规范   java有自动更新Javadoc的工具吗?   java线程如何在ints自身实例类中共享变量   java继承一个非gwt模块   java Hibernate xml配置   使用netty4异步调用的java链接HTTP请求响应