zotero-plugin 1.0.64 → 1.0.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,3 +27,32 @@ to the current branch (or maybe your branch isn't named `gh-<number>`,
27
27
  add `#<number>` to the commit message.
28
28
 
29
29
  Release new versions by issuing `npm version <major|minor|patch>`.
30
+
31
+ # Starting Zotero with your plugin loaded
32
+
33
+ Note is is *much* adviced to create a separate Zotero profile for testing!
34
+
35
+ You will need to have python3 installed to use this.
36
+
37
+ Create a file called `zotero-plugin.ini` with the following contents:
38
+
39
+ ```
40
+ [profile]
41
+ name = <your test profile name>
42
+ path = <your test profile absolute path>
43
+
44
+ [zotero]
45
+ log = <file name to write log output to> # optional
46
+ db = <path to zotero.sqlite you want to populate the profile with> # optional
47
+
48
+ [preferences]
49
+ extensions.zotero.<your extension>.<some setting> = true
50
+ ```
51
+
52
+ and add this script to your package.json:
53
+
54
+ ```
55
+ "start": "zotero-start"
56
+ ```
57
+
58
+ then when you execute `npm start`, zotero will start up with the latest build of your plugin installed.
package/bin/start.py ADDED
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import os, sys
4
+ import shutil
5
+ import json
6
+ import configparser
7
+ import argparse
8
+ import shlex
9
+ import xml.etree.ElementTree as ET
10
+ import subprocess
11
+ import collections
12
+ import types
13
+ import platform
14
+
15
+ class Config:
16
+ def __init__(self):
17
+ config_file = 'zotero-plugin.ini'
18
+ assert os.path.isfile(config_file), f'cannot find {config_file}'
19
+
20
+ config = configparser.ConfigParser(strict = False)
21
+ config.read(config_file)
22
+
23
+ self.profile = types.SimpleNamespace(
24
+ path=os.path.expanduser(config.get('profile', 'path')),
25
+ name=config.get('profile', 'name', fallback=None)
26
+ )
27
+
28
+ self.zotero = types.SimpleNamespace(
29
+ path=config.get('zotero', 'path', fallback=None),
30
+ log=config.get('zotero', 'log', fallback=None),
31
+ db=config.get('profile', 'db', fallback=None)
32
+ )
33
+
34
+ if self.zotero.path:
35
+ self.zotero.path = os.path.expanduser(self.zotero.path)
36
+ elif platform.system() == 'Darwin':
37
+ self.zotero.path = '/Applications/Zotero.app/Contents/MacOS/zotero'
38
+ elif platform.system() == 'Linux':
39
+ self.zotero.path = '/usr/lib/zotero/zotero'
40
+ else:
41
+ assert False, f'{platform.system()} not supported'
42
+
43
+ if self.zotero.log:
44
+ self.zotero.log = os.path.expanduser(self.zotero.log)
45
+
46
+ if 'preferences' in config:
47
+ self.preference = { k: self.pref_value(v) for k, v in dict(config['preferences']).items() }
48
+ else:
49
+ self.preference = {}
50
+
51
+ # always set these
52
+ self.preference['extensions.autoDisableScopes']= 0
53
+ self.preference['extensions.enableScopes'] = 15
54
+ self.preference['extensions.startupScanScopes'] = 15
55
+ self.preference['extensions.zotero.debug.log'] = True
56
+ # null deletes if present
57
+ self.preference['extensions.lastAppBuildId'] = None
58
+ self.preference['extensions.lastAppVersion'] = None
59
+
60
+ def pref_value(self, v):
61
+ if v in ['true', 'false']: return v == 'true'
62
+ if v == 'null': return None
63
+ try:
64
+ return int(v)
65
+ except ValueError:
66
+ pass
67
+ try:
68
+ return float(v)
69
+ except ValueError:
70
+ pass
71
+ try:
72
+ return json.loads(v)
73
+ except json.decoder.JSONDecodeError:
74
+ pass
75
+ return v
76
+ config = Config()
77
+
78
+ def patch_prefs(prefs, add_config):
79
+ def name(line):
80
+ if not line.startswith('user_pref('): return None
81
+ if not line.startswith('user_pref("'): raise ValueError('unexpected user pref: ' + line)
82
+ open_quote = None
83
+ for i, c in enumerate(line):
84
+ if c == '"':
85
+ if open_quote is None:
86
+ open_quote = i
87
+ else:
88
+ try:
89
+ return json.loads(line[open_quote : i + 1])
90
+ except json.decoder.JSONDecodeError:
91
+ pass
92
+ raise ValueError('unexpected user pref: ' + line)
93
+
94
+ prefs = os.path.join(config.profile.path, f'{prefs}.js')
95
+ if not os.path.exists(prefs): return
96
+
97
+ user_prefs = []
98
+ with open(prefs) as f:
99
+ for line in f.readlines():
100
+ if name(line) not in config.preference:
101
+ user_prefs.append(line)
102
+ if add_config:
103
+ for key, value in config.preference.items():
104
+ if value is not None:
105
+ user_prefs.append(f'user_pref({json.dumps(key)}, {json.dumps(value)});\n')
106
+
107
+ with open(prefs, 'w') as f:
108
+ f.write(''.join(user_prefs))
109
+
110
+ patch_prefs('prefs', False)
111
+ patch_prefs('user', True)
112
+
113
+ def system(cmd):
114
+ print('$', cmd)
115
+ subprocess.run(cmd, shell=True, check=True)
116
+
117
+ system('npm run build')
118
+
119
+ if config.zotero.db:
120
+ shutil.copyfile(config.zotero.db, os.path.join(config.profile.path, 'zotero', 'zotero.sqlite'))
121
+
122
+ for plugin_id in ET.parse(os.path.join('build', 'install.rdf')).getroot().findall('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description/{http://www.mozilla.org/2004/em-rdf#}id'):
123
+ plugin_path = os.path.join(config.profile.path, 'extensions', plugin_id.text)
124
+ with open(plugin_path, 'w') as f:
125
+ sources = os.path.join(os.getcwd(), 'build')
126
+ if sources[-1] != '/': sources += '/'
127
+ print(sources, file=f)
128
+
129
+ cmd = config.zotero.path + ' -purgecaches -P'
130
+ if config.profile.name: cmd += ' ' + shlex.quote(config.profile.name)
131
+ cmd += ' -jsconsole -ZoteroDebugText -datadir profile'
132
+ if config.zotero.log: cmd += ' > ' + shlex.quote(config.zotero.log)
133
+ cmd += ' &'
134
+
135
+ system(cmd)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zotero-plugin",
3
- "version": "1.0.64",
3
+ "version": "1.0.65",
4
4
  "description": "Zotero plugin builder",
5
5
  "homepage": "https://github.com/retorquere/zotero-plugin/wiki",
6
6
  "bin": {
@@ -8,7 +8,7 @@
8
8
  "zotero-plugin-zipup": "bin/zipup.js",
9
9
  "zotero-plugin-link": "bin/link.js",
10
10
  "issue-branches": "bin/branches.js",
11
- "zotero-start": "bin/start.js"
11
+ "zotero-start": "bin/start.py"
12
12
  },
13
13
  "author": {
14
14
  "name": "Emiliano Heyns",
@@ -67,8 +67,6 @@
67
67
  },
68
68
  "license": "ISC",
69
69
  "files": [
70
- "bin/start.d.ts",
71
- "bin/start.js",
72
70
  "bin/branches.d.ts",
73
71
  "bin/branches.js",
74
72
  "bin/link.d.ts",
@@ -77,6 +75,7 @@
77
75
  "bin/release.js",
78
76
  "bin/zipup.d.ts",
79
77
  "bin/zipup.js",
78
+ "bin/start.py",
80
79
  "continuous-integration.d.ts",
81
80
  "continuous-integration.js",
82
81
  "copy-assets.d.ts",
package/bin/start.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/bin/start.js DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /* eslint-disable no-console, prefer-template, @typescript-eslint/no-unsafe-argument, @typescript-eslint/restrict-plus-operands */
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const tslib_1 = require("tslib");
6
- const fs = (0, tslib_1.__importStar)(require("fs"));
7
- const path = (0, tslib_1.__importStar)(require("path"));
8
- const child_process_1 = require("child_process");
9
- const shell_quote_1 = require("shell-quote");
10
- const clp_1 = (0, tslib_1.__importDefault)(require("clp"));
11
- function quote(args) {
12
- return (0, shell_quote_1.quote)(args); // eslint-disable-line @typescript-eslint/no-unsafe-call
13
- }
14
- const argv = clp_1.default();
15
- const root_1 = (0, tslib_1.__importDefault)(require("../root"));
16
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
17
- const profile = require(path.join(root_1.default, 'profile.json'));
18
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
- const pkg = require(path.join(root_1.default, 'package.json'));
20
- function exec(cmd) {
21
- console.log(cmd);
22
- if (!argv.dryRun)
23
- (0, child_process_1.execSync)(cmd, { stdio: 'inherit' });
24
- }
25
- if (argv.reset) {
26
- const settings = {
27
- replace: {
28
- 'extensions.autoDisableScopes': 0,
29
- 'extensions.enableScopes': 15,
30
- 'extensions.startupScanScopes': 15,
31
- },
32
- remove: [
33
- 'extensions.lastAppBuildId',
34
- 'extensions.lastAppVersion',
35
- ],
36
- };
37
- const remove = new RegExp(settings.remove.concat(Object.keys(settings)).map(setting => setting.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'));
38
- for (const prefs of ['user', 'prefs']) {
39
- const user_prefs = [];
40
- for (const user_pref of fs.readFileSync(path.join(profile.dir, `${prefs}.js`), 'utf-8').split('\n')) {
41
- if (!user_pref.match(remove))
42
- user_prefs.push(user_pref);
43
- }
44
- for (const [user_pref, value] of Object.entries(settings.replace)) {
45
- user_prefs.push(`user_pref("${user_pref}", ${value});`);
46
- }
47
- fs.writeFileSync(path.join(profile.dir, `${prefs}.js`), user_prefs.join('\n'));
48
- }
49
- }
50
- exec('npm run build');
51
- exec(quote(['rm', '-rf', path.join(profile.dir, 'extensions.json')]));
52
- exec(quote(['rm', '-rf', path.join(profile.dir, 'extensions')]) + path.sep + pkg.name + '*.xpi');
53
- let code = path.resolve(path.join(root_1.default, 'build'));
54
- if (!code.endsWith(path.sep))
55
- code += path.sep;
56
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
57
- fs.writeFileSync(path.join(profile.dir, 'extensions', pkg.name.replace('zotero-', '') + pkg.author.email.replace(/.*@/, '@')), code);
58
- let zotero = null;
59
- switch (process.platform) {
60
- case 'darwin':
61
- zotero = '/Applications/Zotero.app/Contents/MacOS/zotero';
62
- break;
63
- case 'win32':
64
- console.log('not implemented on windows');
65
- process.exit(1);
66
- default:
67
- zotero = '/usr/local/bin/zotero/zotero';
68
- break;
69
- }
70
- exec(quote([zotero, '-purgecaches', '-P', profile.name, '-jsconsole', '-ZoteroDebugText']) + ' > ' + quote([profile.log]));