用于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
since和to关键字已添加到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");
然后应用旧转储文件
推荐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请求响应