Zim

Merge lp:~fenryxo/zim/patches into lp:~jaap.karssenberg/zim/pyzim

Proposed by Jiří Janoušek
Status: Merged
Merged at revision: 306
Proposed branch: lp:~fenryxo/zim/patches
Merge into: lp:~jaap.karssenberg/zim/pyzim
Diff against target: 116 lines (+62/-14)
3 files modified
tests/plugins.py (+2/-2)
zim/exporter.py (+2/-1)
zim/plugins/__init__.py (+58/-11)
To merge this branch: bzr merge lp:~fenryxo/zim/patches
Reviewer Review Type Date Requested Status
Jaap Karssenberg Approve
Review via email: mp+35102@code.launchpad.net

Description of the change

1. Loading plugins in per-user site-packages directory.
2. During HTML export spaces in page links have not been converted to underscores causing broken links. Fixed.

To post a comment you must log in.
lp:~fenryxo/zim/patches updated
301. By Jaap Karssenberg

* Fixed bug with unicode handling for file objects
* Added names for pageindex and pageview widgets for use in gtkrc
* Added special case for mid: and cid: uris when parsing links
* Fixed printtobrowser plugin to use proper preference for web browser
* Added checkbox to quicknote dialog to open the new page or not
* Added character count to "Count words" dialog

302. By Jaap Karssenberg

* Reworked setdefault a bit so tasklist plugin can have empty string for labels
* Fixed unicode conversion in Path so e.g. tasklist dialog opens non-ascii page names correctly

303. By Jaap Karssenberg

Possible fix for unicode in quicknote dialog

304. By Jaap Karssenberg

Fix for issues with empty lines automatically inserted after indented
sections. Added a new parsetree element 'div' with a property 'indent'
to handle indenting within paragraphs. Also 'ul' can now have the 'indent'
property. Should fix bug lp:297932.

305. By Jaap Karssenberg

Updated file write logic for Windows

Revision history for this message
Jaap Karssenberg (jaap.karssenberg) wrote :

Will merge this patch with two changes:
1) will use "zim.plugins.path" instead of "zim.plugins.__path__" -- please note that all double underscore names are in principle reserved for future use by python
2) will make fix for spaces in exported paths more robust by using "encode_filename()" instead of "replace(' ', '_')" -- this way we ensure other encoding stuff is done as well

review: Approve
lp:~fenryxo/zim/patches updated
306. By Jaap Karssenberg

Merging path by Jiří Janoušek
* Backport per-user site-packages dir for python 2.5
* Fix bug with spaces in links in exported HTML

Revision history for this message
Jiří Janoušek (fenryxo) wrote :

1) I know double underscored names are reserved, but __path__ has to be used, because the function __import__ (in zim.plugins.get_plugin_module) uses __path__ to find a plugin module for import. Rev306 doesn't work for me. I have plugin "jjcms" (directory jjcms with __init__.py and other *.py files) in "~/.local/lib/python2.6/site-packages/zim/plugins/" and Zim rev306 tells me "Failed to load plugin jjcms". (BTW "return mypath" is missing in _check_path()).

$ zim -D --no-daemon
...
ERROR: Could not load plugin jjcms
Traceback (most recent call last):
  File "/home/jirkaxx/dev/prj/zim/trunk/zim/gui/preferencesdialog.py", line 303, in __init__
    klass = zim.plugins.get_plugin(name)
  File "/home/jirkaxx/dev/prj/zim/trunk/zim/plugins/__init__.py", line 75, in get_plugin
    mod = get_plugin_module(pluginname)
  File "/home/jirkaxx/dev/prj/zim/trunk/zim/plugins/__init__.py", line 67, in get_plugin_module
    mod = __import__('zim.plugins.'+pluginname)
ImportError: No module named jjcms
...

The idea of extending __path__ originally comes from plugin system of Sonata <http://sonata.berlios.de/>.

2) Yes, it's the proper solution :-)

Revision history for this message
Jaap Karssenberg (jaap.karssenberg) wrote :

2010/9/20 Jiří Janoušek <email address hidden>:
> 1) I know double underscored names are reserved, but __path__ has to be used, because the function __import__ (in  zim.plugins.get_plugin_module) uses __path__ to find a plugin module for import. Rev306 doesn't work for me. I have plugin "jjcms" (directory jjcms with __init__.py and other *.py files) in "~/.local/lib/python2.6/site-packages/zim/plugins/" and Zim rev306 tells me "Failed to load plugin jjcms". (BTW "return mypath" is missing in _check_path()).

OK, that is a consequence I did not foresee. I would have thought
sys.path to be leading for import. Will check python docs and fix it
accordingly.

-- Jaap

Revision history for this message
Jaap Karssenberg (jaap.karssenberg) wrote :

Rev 307 should fix usage of __path__ again.

Revision history for this message
Jiří Janoušek (fenryxo) wrote :

Everything is OK, thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/plugins.py'
2--- tests/plugins.py 2010-07-21 16:25:40 +0000
3+++ tests/plugins.py 2010-09-10 13:27:40 +0000
4@@ -11,8 +11,8 @@
5
6 def runTest(self):
7 '''Test loading plugins and meta data'''
8-
9- plugins = zim.plugins.list_plugins(_path=['.'])
10+ plugin_path = [i.path for i in zim.plugins.plugin_dirs(_path=['.'])]
11+ plugins = zim.plugins.list_plugins(_path=plugin_path)
12 self.assertTrue(len(plugins) > 0)
13 self.assertTrue('spell' in plugins)
14 self.assertTrue('linkmap' in plugins)
15
16=== modified file 'zim/exporter.py'
17--- zim/exporter.py 2010-07-12 21:51:32 +0000
18+++ zim/exporter.py 2010-09-10 13:27:40 +0000
19@@ -223,7 +223,8 @@
20 path = '../' * uppath.count(':') or './'
21 path += encode_filename(downpath) + self._extension
22 #~ print '>>>', path
23- return url_encode(path)
24+ # convert spaces back to underscores
25+ return url_encode(path.replace(' ', '_'))
26
27 def file(self, link):
28 if self.document_root_url and link.startswith('/'):
29
30=== modified file 'zim/plugins/__init__.py'
31--- zim/plugins/__init__.py 2010-07-21 16:25:40 +0000
32+++ zim/plugins/__init__.py 2010-09-10 13:27:40 +0000
33@@ -15,6 +15,57 @@
34
35 logger = logging.getLogger('zim.plugins')
36
37+def user_site_packages():
38+ '''
39+ In Python 2.6 has been introduced feature "Per-user site-packages Directory"
40+ <http://docs.python.org/whatsnew/2.6.html#pep-370-per-user-site-packages-directory>
41+ This function backports this feature to Python 2.5.
42+ '''
43+
44+ if sys.version_info[0:2] == (2, 5):
45+ if os.name == 'nt':
46+ if 'APPDATA' in os.environ:
47+ dir = Dir([os.environ['APPDATA'],
48+ 'Python/Python25/site-packages']).path
49+ else:
50+ dir = None
51+ else:
52+ dir = Dir('~/.local/lib/python2.5/site-packages').path;
53+
54+ if dir and not dir in sys.path: sys.path.append(dir)
55+
56+
57+user_site_packages()
58+
59+def plugin_dirs(_path=None):
60+ '''
61+ Generator of possible plugin directories.
62+ The _path argument is reserved for testing, it allows to override the
63+ search path.
64+ '''
65+ path = _path or sys.path
66+ for dir in path:
67+ try:
68+ dir = dir.decode(zim.fs.ENCODING)
69+ except UnicodeDecodeError:
70+ logger.exception('Could not decode path "%s"', dir)
71+ continue
72+
73+ if os.path.basename(dir) == 'zim.exe':
74+ # path is an executable, not a folder -- examine containing folder
75+ dir = os.path.dirname(dir)
76+
77+ dir = Dir((dir, 'zim', 'plugins'))
78+ if dir.exists(): yield dir
79+
80+# extend path for importing and searching plugins
81+try:
82+ for plugin_dir in plugin_dirs():
83+ if plugin_dir.path not in __path__:
84+ __path__.append(plugin_dir.path)
85+except NameError, e:
86+ # During test is not __path__ defined?
87+ __path__ = [i.path for i in plugin_dirs()]
88
89 def get_plugin_module(pluginname):
90 '''Returns the plugin module object for a given name'''
91@@ -46,18 +97,14 @@
92 # FIXME how should this work for e.g. for python eggs ??
93 # for windows exe we now package plugins separately
94 plugins = set()
95- path = _path or sys.path
96+
97+ # We now use __path__ instead of searching "zim/plugin" directories
98+ # in sys.path directories. This ensure that found plugins can be
99+ # imported.
100+ path = _path or __path__
101+
102 for dir in path:
103- try:
104- dir = dir.decode(zim.fs.ENCODING)
105- except UnicodeDecodeError:
106- logger.exception('Could not decode path "%s"', dir)
107- continue
108-
109- if os.path.basename(dir) == 'zim.exe':
110- # path is an executable, not a folder -- examine containing folder
111- dir = os.path.dirname(dir)
112- dir = Dir((dir, 'zim', 'plugins'))
113+ dir = Dir(dir)
114 for candidate in dir.list():
115 if candidate.startswith('_'):
116 continue