This file is indexed.

/usr/share/pyshared/keepnote/extension.py is in keepnote 0.7.8-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
"""
    KeepNote
    Extension system
"""

#
#  KeepNote
#  Copyright (c) 2008-2009 Matt Rasmussen
#  Author: Matt Rasmussen <rasmus@alum.mit.edu>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#


import os
import imp
import sys
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.elementtree.ElementTree as ET


import keepnote
from keepnote.listening import Listeners
from keepnote import orderdict, plist



# globals
EXTENSION_EXT = u".kne"  # filename extension for KeepNote Extensions
INFO_FILE = u"info.xml"


class DependencyError (StandardError):
    """Exception for dependency error"""

    def __init__(self, ext, dep):
        self.ext = ext
        self.dep = dep


    def __str__(self):
        return "Extension '%s' has failed dependency %s" % \
            (self.ext.key, self.dep)


#=============================================================================
# extension functions


def init_user_extensions(pref_dir=None, home=None):
    """Ensure users extensions are initialized
       Install defaults if needed"""

    if pref_dir is None:
        pref_dir = keepnote.get_user_pref_dir(home)

    extensions_dir = keepnote.get_user_extensions_dir(pref_dir)
    if not os.path.exists(extensions_dir):
        # make user extensions directory
        os.makedirs(extensions_dir, 0700)

    extensions_data_dir = keepnote.get_user_extensions_data_dir(pref_dir)
    if not os.path.exists(extensions_data_dir):
        # make user extensions data directory
        os.makedirs(extensions_data_dir, 0700)



def scan_extensions_dir(extensions_dir):
    """Iterate through the extensions in directory"""

    for filename in os.listdir(extensions_dir):
        path = os.path.join(extensions_dir, filename)
        if os.path.isdir(path):
            yield path



def import_extension(app, name, filename):
    """Import an Extension"""

    filename2 = os.path.join(filename, u"__init__.py")
    
    try:
        infile = open(filename2)
    except Exception, e:
        raise keepnote.KeepNotePreferenceError("cannot load extension '%s'" %
                                               filename, e)

    try:
        mod = imp.load_module(name, infile, filename2,
                              (".py", "rb", imp.PY_SOURCE))
        ext = mod.Extension(app)
        ext.key = name
        ext.read_info()
        infile.close()
        return ext
                
    except Exception, e:
        infile.close()
        raise keepnote.KeepNotePreferenceError("cannot load extension '%s'" %
                                               filename, e)


def get_extension_info_file(filename):
    """Returns an info for an extension file path"""
    return os.path.join(filename, INFO_FILE)


def read_extension_info(filename):
    """Reads an extensions info"""
    
    tree = ET.ElementTree(file=get_extension_info_file(filename))
            
    # parse xml
    # check tree structure matches current version
    root = tree.getroot()
    if root.tag != "extension":
        raise keepnote.KeepNotePreferenceError("bad extension info format")
    
    p = root.find("dict")
    if p is None:
        raise keepnote.KeepNotePreferenceError("bad extension info format")

    return plist.load_etree(p)    



def dependency_satisfied(ext, dep):
    """
    Checks whether an extension satisfies a dependency

    if ext is None, only the 'no' rel is checked
    """

    name, rel, version = dep

    if ext is None:
        return (rel == "no")

    if rel == ">":
        if not (ext.version > version): return False
    elif rel == ">=":
        if not (ext.version >= version): return False
    elif rel == "==":
        if not (ext.version == version): return False
    elif rel == "<=":
        if not (ext.version <= version): return False
    elif rel == "<":
        if not (ext.version < version): return False
    elif rel == "!=":
        if not (ext.version != version): return False

    return True


def parse_extension_version(version_str):
    return tuple(map(int, version_str.split(".")))


def format_extension_version(version):
    return ".".join(map(version, str))


def is_extension_install_file(filename):
    """
    Returns True if file is an extension install file
    """
    return filename.endswith(EXTENSION_EXT)


class Extension (object):
    """KeepNote Extension"""

    version = (1, 0)
    key = ""
    name = "untitled"
    author = "no author"
    website = "http://keepnote.org"
    description = "base extension"
    visible = True


    def __init__(self, app):
        
        self._app = app
        self._info = {}
        self._enabled = False
        self.type = "system"
        self.enabled = Listeners()


    def read_info(self):
        """Populate extension info"""

        path = self.get_base_dir(False)
        self._info = read_extension_info(path)

        # populate info
        self.version = parse_extension_version(self._info["version"])
        self.name = self._info["name"]
        self.author = self._info["author"]
        self.website = self._info["website"]
        self.description = self._info["description"]

        
    def get_info(self, key):
        return self._info.get(key, None)
        

    def enable(self, enable):
        """Enable/disable extension"""

        # check dependencies
        self.check_depends()
        
        # mark extension as enabled
        self._enabled = enable
        
        # notify listeners
        self.enabled.notify(enable)
        
        # return whether the extension is enabled
        return self._enabled


    def is_enabled(self):
        """Returns True if extension is enabled"""
        return self._enabled


    def check_depends(self):
        """Checks whether dependencies are met.  Throws exception on failure"""
        for dep in self.get_depends():
            if not self._app.dependency_satisfied(dep):
                raise DependencyError(self, dep)


    def get_depends(self):
        """
        Returns dependencies of extension

        Dependencies returned as a list of tuples (NAME, REL, EXTRA)

        NAME is a string identify an extension (or 'keepnote' itself).
        EXTRA is an object whose type depends on REL

        REL is a string representing a relation.  Options are:

          Version relations.  For each of these values for REL, the EXTRA
          field is interpreted as VERSION (see below):
            '>='   the version must be greater than or equal to
            '>'    the version must be greater than
            '=='   the version must be exactly equal to
            '<='   the version must less than or equal to
            '<'    the version must be less than
            '!='   the version must not be equal to

          Other relations.  
            'no'   the extension must not exist.  EXTRA is None.


        Possible values for EXTRA:

          VERSION   This is a tuple representing a version number.
            ex: the tuple (0, 6, 1) represents version 0.6.1


        All dependencies must be met to enable an extension.  A extension
        name can appear more than once if several relations are required
        (such as specifying a range of valid version numbers).

        """

        return [("keepnote", ">=", (0, 6, 1))]

    #===============================
    # filesystem paths

    def get_base_dir(self, exist=True):
        """
        Returns the directory containing the extension's code

        If 'exists' is True, create directory if it does not exists.
        """
        path = self._app.get_extension_base_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path


    def get_data_dir(self, exist=True):
        """
        Returns the directory for storing data specific to this extension

        If 'exists' is True, create directory if it does not exists.
        """
        path = self._app.get_extension_data_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path

    def get_data_file(self, filename, exist=True):
        """
        Returns a full path to a file within the extension's data directory

        If 'exists' is True, create directory if it does not exists.
        """
        return os.path.join(self.get_data_dir(exist), filename)