更新:使用 @滏阳河边捉蚯蚓 https://zhuanlan.zhihu.com/p/41297136上获取系统PDF文件和zotero.sqlite文件的代码,在此感谢!
在zotero的library中删除参考文献条目后,有时PDF不会同步删除,尤甚是安装了zotfile插件后,添加参考文献条目后,对应的PDF附件会移动后zotfile指定的目录中,删除条目后PDF也不会同步删除,因此写了个脚本。运行后,如果目录中某个PDF没有对应的参考文献条目,这个PDF就会被转移到备份的文件夹中。
其原理是读取PDF目录中PDF文件的文件名,如a.pdf,b.pdf....,再读取zoter.sqlite文件中的附件目录,如果后者不包括a.pdf,则移动PDF目录中的a.pdf到备份的目录中。
将代码复制为.py文件,如zot.py,在命令提示符下运行:
python zot.py
运行时需要关闭zotero,自己指定选择备份的目录。
如果有多余的PDF,则提示已备份***.pdf到备份目录中。
如果移动错了,将备份文件目录中的文件自己复制回去即可。如果确认无误,再自行删除备份的文件。
# -*- coding: utf-8 -*-
"""
Spyder Editor"""
from __future__ import print_function
from os import walk, remove
import os
import re
import tkinter as tk
from tkinter import filedialog
import shutil #移动或复制文件
import sqlite3
import pandas as pd
import configparser
import shutil
import sysroot = tk.Tk()
root.withdraw()#选择PDF备份的目录
back_dir = filedialog.askdirectory(title = '请选择PDF备份的目录:')try:from pathlib import Path
except ImportError:from pathlib2 import Pathif sys.version_info.major == 2:reload(sys)sys.setdefaultencoding('UTF8')def get_zotfile_dest_and_zotero_data_dirs():'''Get the Zotero data dir and the Zotfile destination dir in PosixPath type'''profile_dirs = {'darwin': Path.home() / 'Library/Application Support/Zotero','linux': Path.home() / '.zotero/zotero','linux2': Path.home() / '.zotero/zotero','win32': Path.home() / 'AppData/Roaming/Zotero/Zotero'}profile_dir = profile_dirs[sys.platform]config = configparser.ConfigParser()config.read('{}'.format(profile_dir / 'profiles.ini'))configs_loc = profile_dir / config['Profile0']['Path'] / 'prefs.js'configs = configs_loc.read_text()zotero_data_pat = re.compile(r'user_pref("extensions.zotero.dataDir", "(?P<zotero_data>.+)");')zotero_data_dir = Path(zotero_data_pat.search(configs).group('zotero_data'))zotfile_dest_pat = re.compile(r'user_pref("extensions.zotfile.dest_dir", "(?P<zotfile_dest>.+)");')zotfile_dest_dir = Path(zotfile_dest_pat.search(configs).group('zotfile_dest'))return zotero_data_dir, zotfile_dest_dirif __name__ == '__main__':#得到zotero数据目录和文件目录zotero_data_dir, zotfile_dest_dir = get_zotfile_dest_and_zotero_data_dirs()list_of_files = [] #文件包含目录files = [] #仅文件名for (dirpath, dirnames, filenames) in walk(zotfile_dest_dir):for file in filenames:if file.endswith('.pdf') == True:list_of_files.append(os.path.join(dirpath, file))files.append(file)#连接数据库zot_sqlite = os.path.join(zotero_data_dir, 'zotero.sqlite')with sqlite3.connect(zot_sqlite) as con:item_att=pd.read_sql_query("SELECT * FROM itemAttachments", con=con)item_path = item_att['path']#生成备份文件目录#当文件不存在时,才创建该文件夹。if not os.path.exists(back_dir):os.mkdir(back_dir)for i in range(len(files)):#如zotero.sqlite的path中不包括文件if not (item_path.str.contains(re.escape(files[i])).any()): #os.remove(list_of_files[i]) #也可以删除文件shutil.move(list_of_files[i], os.path.join(back_dir, files[i]))#移动文件到备份目录print('已备份',files[i],'到',back_dir)
win 10,Deepin 15.11测试通过。