Beispiel #1
0
 def exportSinglePage(self, client, filename, webDir, stylesDir, printFlag):
     """
     Export 'client' to a single web page,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     'printFlag' indicates whether or not this is for print (and whatever else that might mean)
     """
     try:
         imagesDir    = webDir.joinpath('images')
         scriptsDir   = webDir.joinpath('scripts')
         templatesDir = webDir.joinpath('templates')
         filename = Path(filename)
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(_(u'Filename %s is a file, cannot replace it') % 
                          filename)
             log.error("Couldn't export web page: "+
                       "Filename %s is a file, cannot replace it" % filename)
             return
         else:
             client.alert(_(u'Folder name %s already exists. '
                             'Please choose another one or delete existing one then try again.') % filename)           
             return 
         singlePageExport = SinglePageExport(stylesDir, filename, imagesDir, scriptsDir, templatesDir)
         singlePageExport.export(self.package, printFlag)
     except Exception, e:
         client.alert(_('SAVE FAILED!\n%s' % str(e)))
         raise
Beispiel #2
0
 def exportWebSite(self, client, filename, webDir, stylesDir):
     """
     Export 'client' to a web site,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     """
     imagesDir    = webDir.joinpath('images')
     scriptsDir   = webDir.joinpath('scripts')
     templatesDir = webDir.joinpath('templates')
     filename = Path(filename)
     if filename.basename() != self.package.name:
         filename /= self.package.name
     if not filename.exists():
         filename.makedirs()
     elif not filename.isdir():
         client.alert(_(u'Filename %s is a file, cannot replace it') % 
                      filename)
         log.error("Couldn't export web page: "+
                   "Filename %s is a file, cannot replace it" % filename)
         return
     else:
         filename.rmtree()
         filename.mkdir()
     websiteExport = WebsiteExport(stylesDir, filename, 
                                   imagesDir, scriptsDir, templatesDir)
     websiteExport.export(self.package)
     self._startFile(filename)
Beispiel #3
0
    def do_export(self, inputf, outputf):
        if hasattr(self, 'export_' + self.options["export"]):
            LOG.debug("Exporting to type %s, in: %s, out: %s, overwrite: %s" \
            % (self.options["export"], inputf, outputf, str(self.options["overwrite"])))
            if not outputf:
                if self.options["export"] in ('website', 'singlepage'):
                    outputf = inputf.rsplit(".elp")[0]
                else:
                    outputf = inputf + self.extensions[self.options["export"]]
            outputfp = Path(outputf)
            if outputfp.exists() and not self.options["overwrite"]:
                error = _(u'"%s" already exists.\nPlease try again \
with a different filename') % outputf
                raise Exception(error.encode(sys.stdout.encoding))
            else:
                if outputfp.exists() and self.options["overwrite"]:
                    if outputfp.isdir():
                        for filen in outputfp.walkfiles():
                            filen.remove()
                        outputfp.rmdir()
                    else:
                        outputfp.remove()
                pkg = Package.load(inputf)
                LOG.debug("Package %s loaded" % (inputf))
                if not pkg:
                    error = _(u"Invalid input package")
                    raise Exception(error.encode(sys.stdout.encoding))
                self.styles_dir = self.web_dir.joinpath('style', pkg.style)
                LOG.debug("Styles dir: %s" % (self.styles_dir))
                getattr(self, 'export_' + self.options["export"])(pkg, outputf)
                return outputf
        else:
            raise Exception(_(u"Export format not implemented")\
.encode(sys.stdout.encoding))
Beispiel #4
0
 def exportSinglePage(self, client, filename, webDir, stylesDir):
     """
     Export 'client' to a single web page,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     """
     imagesDir    = webDir.joinpath('images')
     scriptsDir   = webDir.joinpath('scripts')
     templatesDir = webDir.joinpath('templates')
     filename = Path(filename)
     if filename.basename() != self.package.name:
         filename /= self.package.name
     if not filename.exists():
         filename.makedirs()
     elif not filename.isdir():
         client.alert(_(u'Filename %s is a file, cannot replace it') % 
                      filename)
         log.error("Couldn't export web page: "+
                   "Filename %s is a file, cannot replace it" % filename)
         return
     else:
         try:
             filename.rmtree()
             filename.mkdir()
         except Exception, e:
             client.alert(_('There was an error in the export:\n%s') % str(e))
             return
Beispiel #5
0
    def do_export(self, inputf, outputf):
        if hasattr(self, 'export_' + self.options["export"]):
            LOG.debug("Exporting to type %s, in: %s, out: %s, overwrite: %s" \
            % (self.options["export"], inputf, outputf, str(self.options["overwrite"])))
            if not outputf:
                if self.options["export"] in ('website', 'singlepage'):
                    outputf = inputf.rsplit(".elp")[0]
                else:
                    outputf = inputf + self.extensions[self.options["export"]]
            outputfp = Path(outputf)
            if outputfp.exists() and not self.options["overwrite"]:
                error = _(u'"%s" already exists.\nPlease try again \
with a different filename') % outputf
                raise Exception(error.encode(sys.stdout.encoding))
            else:
                if outputfp.exists() and self.options["overwrite"]:
                    if outputfp.isdir():
                        for filen in outputfp.walkfiles():
                            filen.remove()
                        outputfp.rmdir()
                    else:
                        outputfp.remove()
                pkg = Package.load(inputf)
                LOG.debug("Package %s loaded" % (inputf))
                if not pkg:
                    error = _(u"Invalid input package")
                    raise Exception(error.encode(sys.stdout.encoding))
                self.styles_dir = self.web_dir.joinpath('style', pkg.style)
                LOG.debug("Styles dir: %s" % (self.styles_dir))
                getattr(self, 'export_' + self.options["export"])(pkg, outputf)
                return outputf
        else:
            raise Exception(_(u"Export format not implemented")\
.encode(sys.stdout.encoding))
Beispiel #6
0
 def exportIpod(self, client, filename):
     """
     Export 'client' to an iPod Notes folder tree
     'webDir' is just read from config.webDir
     """
     try:
         # filename is a directory where we will export the notes to
         # We assume that the user knows what they are doing
         # and don't check if the directory is already full or not
         # and we just overwrite what's already there
         filename = Path(filename)
         # Append the package name to the folder path if necessary
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(_(u'Filename %s is a file, cannot replace it') % 
                          filename)
             log.error("Couldn't export web page: "+
                       "Filename %s is a file, cannot replace it" % filename)
             return
         else:
             client.alert(_(u'Folder name %s already exists. '
                             'Please choose another one or delete existing one then try again.') % filename)           
             return 
         # Now do the export
         ipodExport = IpodExport(self.config, filename)
         ipodExport.export(self.package)
     except Exception, e:
         client.alert(_('EXPORT FAILED!\n%s') % str(e))
         raise
 def exportIpod(self, client, filename):
     """
     Export 'client' to an iPod Notes folder tree
     'webDir' is just read from config.webDir
     """
     try:
         # filename is a directory where we will export the notes to
         # We assume that the user knows what they are doing
         # and don't check if the directory is already full or not
         # and we just overwrite what's already there
         filename = Path(filename)
         # Append the package name to the folder path if necessary
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(
                 _(u'Filename %s is a file, cannot replace it') % filename)
             log.error("Couldn't export web page: " +
                       "Filename %s is a file, cannot replace it" %
                       filename)
             return
         else:
             client.alert(
                 _(u'Folder name %s already exists. '
                   'Please choose another one or delete existing one then try again.'
                   ) % filename)
             return
         # Now do the export
         ipodExport = IpodExport(self.config, filename)
         ipodExport.export(self.package)
     except Exception, e:
         client.alert(_('EXPORT FAILED!\n%s') % str(e))
         raise
Beispiel #8
0
 def exportIpod(self, client, filename):
     """
     Export 'client' to an iPod Notes folder tree
     'webDir' is just read from config.webDir
     """
     try:
         filename = Path(filename)
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(_(u'Filename %s is a file, cannot replace it') % 
                          filename)
             log.error("Couldn't export web page: "+
                       "Filename %s is a file, cannot replace it" % filename)
             return
         else:
             client.alert(_(u'Folder name %s already exists. '
                             'Please choose another one or delete existing one then try again.') % filename)           
             return 
         ipodExport = IpodExport(self.config, filename)
         ipodExport.export(self.package)
     except Exception, e:
         client.alert(_('EXPORT FAILED!\n%s') % str(e))
         raise
Beispiel #9
0
 def exportWebSite(self, client, filename, stylesDir):
     """
     Export 'client' to a web site,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     """
     try:
         filename = Path(filename)
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(_(u'Filename %s is a file, cannot replace it') % 
                          filename)
             log.error("Couldn't export web page: "+
                       "Filename %s is a file, cannot replace it" % filename)
             return
         else:
             client.alert(_(u'Folder name %s already exists. '
                             'Please choose another one or delete existing one then try again.') % filename)           
             return 
         websiteExport = WebsiteExport(self.config, stylesDir, filename)
         websiteExport.export(self.package)
     except Exception, e:
         client.alert(_('EXPORT FAILED!\n%s') % str(e))
         raise
 def exportSinglePage(self, client, filename, webDir, stylesDir, \
                      printFlag):
     """
     Export 'client' to a single web page,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     'printFlag' indicates whether or not this is for print 
                 (and whatever else that might mean)
     """
     try:
         imagesDir = webDir.joinpath('images')
         scriptsDir = webDir.joinpath('scripts')
         templatesDir = webDir.joinpath('templates')
         # filename is a directory where we will export the website to
         # We assume that the user knows what they are doing
         # and don't check if the directory is already full or not
         # and we just overwrite what's already there
         filename = Path(filename)
         # Append the package name to the folder path if necessary
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(
                 _(u'Filename %s is a file, cannot replace it') % filename)
             log.error("Couldn't export web page: " +
                       "Filename %s is a file, cannot replace it" %
                       filename)
             return
         else:
             client.alert(
                 _(u'Folder name %s already exists. '
                   'Please choose another one or delete existing one then try again.'
                   ) % filename)
             return
         # Now do the export
         singlePageExport = SinglePageExport(stylesDir, filename, \
                                      imagesDir, scriptsDir, templatesDir)
         singlePageExport.export(self.package, printFlag)
     except Exception, e:
         client.alert(_('SAVE FAILED!\n%s' % str(e)))
         raise
Beispiel #11
0
 def exportSinglePage(self, client, filename, webDir, stylesDir, \
                      printFlag):
     """
     Export 'client' to a single web page,
     'webDir' is just read from config.webDir
     'stylesDir' is where to copy the style sheet information from
     'printFlag' indicates whether or not this is for print 
                 (and whatever else that might mean)
     """
     try:
         imagesDir    = webDir.joinpath('images')
         scriptsDir   = webDir.joinpath('scripts')
         templatesDir = webDir.joinpath('templates')
         # filename is a directory where we will export the website to
         # We assume that the user knows what they are doing
         # and don't check if the directory is already full or not
         # and we just overwrite what's already there
         filename = Path(filename)
         # Append the package name to the folder path if necessary
         if filename.basename() != self.package.name:
             filename /= self.package.name
         if not filename.exists():
             filename.makedirs()
         elif not filename.isdir():
             client.alert(_(u'Filename %s is a file, cannot replace it') % 
                          filename)
             log.error("Couldn't export web page: "+
                       "Filename %s is a file, cannot replace it" % filename)
             return
         else:
             client.alert(_(u'Folder name %s already exists. '
                             'Please choose another one or delete existing one then try again.') % filename)           
             return 
         # Now do the export
         singlePageExport = SinglePageExport(stylesDir, filename, \
                                      imagesDir, scriptsDir, templatesDir)
         singlePageExport.export(self.package, printFlag)
     except Exception, e:
         client.alert(_('SAVE FAILED!\n%s' % str(e)))
         raise
Beispiel #12
0
class Config:
    """
    The Config class contains the configuration information for eXe.
    """
    optionNames = {
        'system': ('webDir', 'xulDir', 'port', 'dataDir', 
                   'configDir', 'localeDir', 'browserPath'),
        'user': ('locale',),
    }
    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser(self.onWrite)
        self.exePath     = Path(sys.argv[0]).abspath()
        self.webDir      = self.exePath.dirname()
        self.xulDir      = self.exePath.dirname()
        self.localeDir   = self.exePath.dirname()/"locale"
        self.port        = 51235
        self.dataDir     = Path(".")
        self.configDir   = Path(".")
        self.browserPath = Path("firefox")
        self.locale = chooseDefaultLocale(self.localeDir)
        self.styles      = []
        self.recentProjects = []
        self.hiddeniDevices = []
        self.deprecatediDevices = [ "flash with text", "flash movie", "mp3", \
                                    "attachment"]
        self.assumeMediaPlugins = False;
        self._overrideDefaultVals()
        self.webDir = Path(self.webDir)
        if not (self.webDir/'scripts').isdir() \
           and (self.webDir/'webui').isdir():
            self.webDir /= 'webui'
        self.xulDir = Path(self.xulDir)
        if not (self.xulDir/'scripts').isdir() \
           and (self.xulDir/'xului').isdir():
            self.xulDir /= 'xului'
        self.__setConfigPath()
        self._writeDefaultConfigFile()
        self.loadSettings()
        self.setupLogging()
        self.loadStyles()
        self.loadLocales()
    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """
    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ['exe.conf']
    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file 
        (auto write is on so we don't need to write the file at the end)
        """
        for sectionName, optionNames in self.optionNames.items():
            for optionName in optionNames:
                defaultVal = getattr(self, optionName)
                self.configParser.setdefault(sectionName, 
                                             optionName, 
                                             defaultVal)
        self.configParser.setdefault('logging', 'root', 'INFO')
    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True
    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section('system'):
            system = self.configParser.system
            if system.has_option('appDataDir'):
                self.configDir = Path(system.appDataDir)
                system.configDir = self.configDir
                del system.appDataDir
            if system.has_option('greDir'):
                del system.greDir
    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """
        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)
        self.configParser.defaultValue = defVal
        self.upgradeFile()
        if self.configParser.has_section('system'):
            system = self.configParser.system
            self.webDir         = Path(system.webDir)
            self.xulDir         = Path(system.xulDir)
            self.localeDir      = Path(system.localeDir)
            self.port           = int(system.port)
            self.browserPath    = Path(system.browserPath)
            self.dataDir        = Path(system.dataDir)
            self.configDir      = Path(system.configDir)
            self.assumeMediaPlugins = False;
            if self.configParser.has_option('system', \
                    'assumeMediaPlugins'):
               value = system.assumeMediaPlugins.strip().lower()
               if value == "1" or value == "yes" or value == "true" or \
                   value == "on":
                       self.assumeMediaPlugins = True;
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        self.webDir = self.webDir.expand().abspath()
        if not self.configDir.exists():
            self.configDir.mkdir()
        self.recentProjects = []
        if self.configParser.has_section('recent_projects'):
            recentProjectsSection = self.configParser.recent_projects
            for key, path in recentProjectsSection.items():
                self.recentProjects.append(path)
        self.hiddeniDevices = []
        if self.configParser.has_section('idevices'):
            idevicesSection = self.configParser.idevices
            for key,value in idevicesSection.items():
                value = value.strip().lower()
                if value == "0" or value == "no" or value == "false" or \
                        value == "off":
                    self.hiddeniDevices.append(key.lower())
        if self.configParser.has_section('deprecated'):
            deprecatedSection = self.configParser.deprecated
            for key,value in deprecatedSection.items():
                value = value.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                        value == "on":
                    if key.lower() in self.deprecatediDevices:
                        self.deprecatediDevices.remove(key.lower())
        if self.configParser.has_section('user'):
            if self.configParser.user.has_option('locale'):
                self.locale = self.configParser.user.locale
                return
        self.locale = chooseDefaultLocale(self.localeDir)
    def onWrite(self, configParser):
        """
        Called just before the config file is written.
        We use it to fill out any settings that are stored here and 
        not in the config parser itself
        """
        self.configParser.delete('recent_projects')
        recentProjectsSection = self.configParser.addSection('recent_projects')
        for num, path in enumerate(self.recentProjects):
            recentProjectsSection[str(num)] = path
    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir/'exe.log', 'a', 
                                       500000, 10)
            hdlr.doRollover()
        except OSError:
            hdlr = logging.FileHandler(self.configDir/'exe.log')
        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log    = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)
        loggingLevels = {"DEBUG"    : logging.DEBUG,
                         "INFO"     : logging.INFO,
                         "WARNING"  : logging.WARNING,
                         "ERROR"    : logging.ERROR,
                         "CRITICAL" : logging.CRITICAL }
        if self.configParser.has_section('logging'):
            for logger, level in self.configParser._sections["logging"].items():
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])
        log.info("************** eXe logging started **************")
        log.info("configPath  = %s" % self.configPath)
        log.info("exePath     = %s" % self.exePath)
        log.info("browserPath = %s" % self.browserPath)
        log.info("webDir      = %s" % self.webDir)
        log.info("xulDir      = %s" % self.xulDir)
        log.info("localeDir   = %s" % self.localeDir)
        log.info("port        = %d" % self.port)
        log.info("dataDir     = %s" % self.dataDir)
        log.info("configDir   = %s" % self.configDir)
        log.info("locale      = %s" % self.locale)
    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        log = logging.getLogger()
        self.styles = []
        styleDir    = self.webDir/"style"
        log.debug("loadStyles from %s" % styleDir)
        for subDir in styleDir.dirs():
            styleSheet = subDir/'content.css'
            log.debug(" checking %s" % styleSheet)
            if styleSheet.exists():
                style = subDir.basename()
                log.debug(" loading style %s" % style)
                self.styles.append(style)
    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install('exe', self.localeDir, True)
        self.locales = {}
        for subDir in self.localeDir.dirs():
            if (subDir/'LC_MESSAGES'/'exe.mo').exists():
                self.locales[subDir.basename()] = \
                    gettext.translation('exe', 
                                        self.localeDir, 
                                        languages=[str(subDir.basename())])
                if subDir.basename() == self.locale:
                    locale = subDir.basename()
                    log.debug(" loading locale %s" % locale)
                    self.locales[locale].install(unicode=True)
Beispiel #13
0
    def render(self, request):
        if "sendWhat" in request.args:
            if request.args['sendWhat'][0] == 'dirs':
                pathdir = Path(unquote(
                    request.args['node'][0].decode('utf-8')))
                l = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for d in get_drives():
                        try:
                            if is_readable(Path(d)):
                                icon = None
                            else:
                                icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                            l.append({
                                "realtext": d,
                                "text": d,
                                "id": d + '\\',
                                "icon": icon
                            })
                        except:
                            pass
                else:
                    for d in pathdir.dirs():
                        try:
                            if not d.name.startswith(
                                    '.') or sys.platform[:3] == "win":
                                if not iswinlink(d.abspath()):
                                    if is_readable(d):
                                        icon = None
                                    else:
                                        icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                                    l.append({
                                        "realtext": d.name,
                                        "text": getname(d),
                                        "id": d.abspath(),
                                        "icon": icon
                                    })
                        except:
                            pass
            elif request.args['sendWhat'][0] == 'both':
                pathdir = Path(unquote(request.args['dir'][0].decode('utf-8')))
                items = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for drive in get_drives():
                        d = Path(drive + '\\')
                        items.append({
                            "name": drive,
                            "realname": drive + '\\',
                            "size": 0,
                            "type": 'directory',
                            "modified": 0,
                            "is_readable": is_readable(d),
                            "is_writable": is_writable(d)
                        })
                else:
                    parent = pathdir.parent
                    if (parent == pathdir):
                        realname = '/'
                    else:
                        realname = parent.abspath()
                    items.append({
                        "name": '.',
                        "realname": pathdir.abspath(),
                        "size": pathdir.size,
                        "type": "directory",
                        "modified": int(pathdir.mtime),
                        "is_readable": is_readable(pathdir),
                        "is_writable": is_writable(pathdir)
                    })
                    items.append({
                        "name": '..',
                        "realname": realname,
                        "size": parent.size,
                        "type": "directory",
                        "modified": int(parent.mtime),
                        "is_readable": is_readable(parent),
                        "is_writable": is_writable(parent)
                    })
                    try:
                        for d in pathdir.listdir():
                            try:
                                if not d.name.startswith(
                                        '.') or sys.platform[:3] == "win":
                                    if not iswinlink(d.abspath()):
                                        if d.isdir():
                                            pathtype = "directory"
                                        elif d.isfile():
                                            if is_readable(d):
                                                pathtype = repr(
                                                    mimetypes.guess_type(
                                                        d.name, False)[0])
                                            else:
                                                pathtype = "file"
                                        elif d.islink():
                                            pathtype = "link"
                                        else:
                                            pathtype = "None"
                                        items.append({
                                            "name":
                                            getname(d),
                                            "realname":
                                            d.abspath(),
                                            "size":
                                            d.size,
                                            "type":
                                            pathtype,
                                            "modified":
                                            int(d.mtime),
                                            "is_readable":
                                            is_readable(d),
                                            "is_writable":
                                            is_writable(d)
                                        })
                            except:
                                pass
                        G.application.config.lastDir = pathdir
                    except:
                        pass
                l = {
                    "totalCount": len(items),
                    'results': len(items),
                    'items': items
                }
            return json.dumps(l).encode('utf-8')
        elif "query" in request.args:
            query = request.args['query'][0]
            pathdir = Path(unquote(request.args['dir'][0].decode('utf-8')))
            items = []
            if pathdir == '/' and sys.platform[:3] == "win":
                for d in get_drives():
                    items.append({
                        "name": d,
                        "realname": d + '\\',
                        "size": 0,
                        "type": 'directory',
                        "modified": 0
                    })
            else:
                parent = pathdir.parent
                if (parent == pathdir):
                    realname = '/'
                else:
                    realname = parent.abspath()
                for d in pathdir.listdir():
                    try:
                        if d.isdir():
                            pathtype = "directory"
                        elif d.isfile():
                            if is_readable(d):
                                pathtype = repr(
                                    mimetypes.guess_type(d.name, False)[0])
                            else:
                                pathtype = "file"
                        elif d.islink():
                            pathtype = "link"
                        else:
                            pathtype = "None"
                        if d.name.startswith(query):
                            items.append({
                                "name": getname(d),
                                "realname": d.abspath(),
                                "size": d.size,
                                "type": pathtype,
                                "modified": int(d.mtime),
                                "is_readable": is_readable(d),
                                "is_writable": is_writable(d)
                            })
                    except:
                        pass

            l = {
                "totalCount": len(items),
                'results': len(items),
                'items': items
            }
            return json.dumps(l).encode('utf-8')
        return ""
Beispiel #14
0
class Config:
    """
    The Config class contains the configuration information for eXe.
    """

    # Class attributes
    optionNames = {
        'idevices': ('someone', ),
        'system': ('webDir', 'xulDir', 'port', 'dataDir', 'configDir',
                   'localeDir', 'browserPath'),
        'user': ('locale', ),
    }

    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser(self.onWrite)
        # Set default values
        # idevices is the list of hidden idevices selected by the user
        self.someone = 0
        # exePath is the whole path and filename of the exe executable
        self.exePath = Path(sys.argv[0]).abspath()
        # webDir is the parent directory for styles,scripts and templates
        self.webDir = self.exePath.dirname()
        # xulDir is the parent directory for styles,scripts and templates
        self.xulDir = self.exePath.dirname()
        # localeDir is the base directory where all the locales are stored
        self.localeDir = self.exePath.dirname() / "locale"
        # port is the port the exe webserver will listen on
        # (previous default, which earlier users might still use, was 8081)
        self.port = 51235
        # dataDir is the default directory that is shown to the user
        # to save packages and exports in
        self.dataDir = Path(".")
        # configDir is the dir for storing user profiles
        # and user made idevices and the config file
        self.configDir = Path(".")
        # browserPath is the entire pathname to firefox
        self.browserPath = Path("firefox")
        # locale is the language of the user
        self.locale = chooseDefaultLocale(self.localeDir)
        # internalAnchors indicate which exe_tmp_anchor tags to generate for each tinyMCE field
        # available values = "enable_all", "disable_autotop", or "disable_all"
        self.internalAnchors = "enable_all"
        # styles is the list of style names available for loading
        self.styles = []
        # The documents that we've recently looked at
        self.recentProjects = []
        # canonical (English) names of iDevices not to show in the iDevice pane
        self.hiddeniDevices = []
        # likewise, a canonical (English) names of iDevices not to show in the
        # iDevice pane but, contrary to the hiddens, these are ones that the
        # configuration can specify to turn ON:
        self.deprecatediDevices = [ "flash with text", "flash movie", "mp3", \
                                    "attachment"]
        # by default, only allow embedding of media types for which a
        # browser plugin is found:
        self.assumeMediaPlugins = False
        # Let our children override our defaults depending
        # on the OS that we're running on
        self._overrideDefaultVals()
        # Try to make the defaults a little intelligent
        # Under devel trees, webui is the default webdir
        self.webDir = Path(self.webDir)
        if not (self.webDir/'scripts').isdir() \
           and (self.webDir/'webui').isdir():
            self.webDir /= 'webui'
        # Under devel trees, xului is the default xuldir
        self.xulDir = Path(self.xulDir)
        if not (self.xulDir/'scripts').isdir() \
           and (self.xulDir/'xului').isdir():
            self.xulDir /= 'xului'
        # Find where the config file will be saved
        self.__setConfigPath()
        # Fill in any undefined config options with our defaults
        self._writeDefaultConfigFile()
        # Now we are ready to serve the application
        self.loadSettings()
        self.setupLogging()
        self.loadStyles()
        self.loadLocales()

    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """

    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ['exe.conf']

    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file 
        (auto write is on so we don't need to write the file at the end)
        """
        for sectionName, optionNames in self.optionNames.items():
            for optionName in optionNames:
                defaultVal = getattr(self, optionName)
                self.configParser.setdefault(sectionName, optionName,
                                             defaultVal)
        # Logging can't really be changed from inside the program at the moment...
        self.configParser.setdefault('logging', 'root', 'INFO')

    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        # If there's an EXECONF environment variable, use it
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        # Otherwise find the most appropriate existing file
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                # If no config files exist, create and use the
                # first one on the list
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        # Now make our configParser
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True

    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section('system'):
            system = self.configParser.system
            if system.has_option('appDataDir'):
                # Older config files had configDir stored as appDataDir
                self.configDir = Path(system.appDataDir)
                # We'll just upgrade their config file for them for now...
                system.configDir = self.configDir
                del system.appDataDir
            if system.has_option('greDir'):
                # No longer used, system should automatically support
                del system.greDir

    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """

        # Set up the parser so that if a certain value is not in the config
        # file, it will use the value from our default values
        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)

        self.configParser.defaultValue = defVal
        self.upgradeFile()
        # System Section
        if self.configParser.has_section('system'):
            system = self.configParser.system
            self.webDir = Path(system.webDir)
            self.xulDir = Path(system.xulDir)
            self.localeDir = Path(system.localeDir)
            self.port = int(system.port)
            self.browserPath = Path(system.browserPath)
            self.dataDir = Path(system.dataDir)
            self.configDir = Path(system.configDir)

            self.assumeMediaPlugins = False
            if self.configParser.has_option('system', \
                    'assumeMediaPlugins'):
                value = system.assumeMediaPlugins.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                    value == "on":
                    self.assumeMediaPlugins = True

        # If the dataDir points to some other dir, fix it
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        # make the webDir absolute, to hide path joins of relative paths
        self.webDir = self.webDir.expand().abspath()
        # If the configDir doesn't exist (as it may be a default setting with a
        # new installation) create it
        if not self.configDir.exists():
            self.configDir.mkdir()

        # Get the list of recently opened projects
        self.recentProjects = []
        if self.configParser.has_section('recent_projects'):
            recentProjectsSection = self.configParser.recent_projects
            for key, path in recentProjectsSection.items():
                self.recentProjects.append(path)

        # Load the list of "hidden" iDevices
        self.hiddeniDevices = []
        if self.configParser.has_section('idevices'):
            idevicesSection = self.configParser.idevices
            for key, value in idevicesSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "0" or value == "no" or value == "false" or \
                        value == "off":
                    self.hiddeniDevices.append(key.lower())

        #self.deprecatediDevices = [ "flash with text", "flash movie", ...]
        # and UN-Load from the list of "deprecated" iDevices
        if self.configParser.has_section('deprecated'):
            deprecatedSection = self.configParser.deprecated
            for key, value in deprecatedSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                        value == "on":
                    if key.lower() in self.deprecatediDevices:
                        self.deprecatediDevices.remove(key.lower())

        # Load the "user" section
        if self.configParser.has_section('user'):
            if self.configParser.user.has_option('internalAnchors'):
                self.internalAnchors = self.configParser.user.internalAnchors
            if self.configParser.user.has_option('locale'):
                self.locale = self.configParser.user.locale
                return
        self.locale = chooseDefaultLocale(self.localeDir)

    def onWrite(self, configParser):
        """
        Called just before the config file is written.
        We use it to fill out any settings that are stored here and 
        not in the config parser itself
        """
        # Recent projects
        self.configParser.delete('recent_projects')
        recentProjectsSection = self.configParser.addSection('recent_projects')
        for num, path in enumerate(self.recentProjects):
            recentProjectsSection[str(num)] = path

    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir / 'exe.log', 'a', 500000,
                                       10)
            hdlr.doRollover()
        except OSError:
            # ignore the error we get if the log file is logged
            hdlr = logging.FileHandler(self.configDir / 'exe.log')

        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)

        loggingLevels = {
            "DEBUG": logging.DEBUG,
            "INFO": logging.INFO,
            "WARNING": logging.WARNING,
            "ERROR": logging.ERROR,
            "CRITICAL": logging.CRITICAL
        }

        if self.configParser.has_section('logging'):
            for logger, level in self.configParser._sections["logging"].items(
            ):
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])

        log.info("************** eXe logging started **************")
        log.info("configPath  = %s" % self.configPath)
        log.info("exePath     = %s" % self.exePath)
        log.info("browserPath = %s" % self.browserPath)
        log.info("webDir      = %s" % self.webDir)
        log.info("xulDir      = %s" % self.xulDir)
        log.info("localeDir   = %s" % self.localeDir)
        log.info("port        = %d" % self.port)
        log.info("dataDir     = %s" % self.dataDir)
        log.info("configDir   = %s" % self.configDir)
        log.info("locale      = %s" % self.locale)
        log.info("internalAnchors = %s" % self.internalAnchors)

    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        log = logging.getLogger()
        self.styles = []
        styleDir = self.webDir / "style"

        log.debug("loadStyles from %s" % styleDir)

        for subDir in styleDir.dirs():
            styleSheet = subDir / 'content.css'
            log.debug(" checking %s" % styleSheet)
            if styleSheet.exists():
                style = subDir.basename()
                log.debug(" loading style %s" % style)
                self.styles.append(style)

    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install('exe', self.localeDir, True)
        self.locales = {}
        for subDir in self.localeDir.dirs():
            if (subDir / 'LC_MESSAGES' / 'exe.mo').exists():
                self.locales[subDir.basename()] = \
                    gettext.translation('exe',
                                        self.localeDir,
                                        languages=[str(subDir.basename())])
                if subDir.basename() == self.locale:
                    locale = subDir.basename()
                    log.debug(" loading locale %s" % locale)
                    self.locales[locale].install(unicode=True)


# ===========================================================================
Beispiel #15
0
class Config(object):
    """
    The Config class contains the configuration information for eXe.
    """

    # To build link to git revision
    baseGitWebURL = 'https://forja.cenatic.es/plugins/scmgit/cgi-bin/gitweb.cgi?p=iteexe/iteexe.git'

    # Class attributes
    optionNames = {
        'system': ('webDir', 'jsDir', 'port', 'dataDir',
                   'configDir', 'localeDir', 'browser', 'mediaProfilePath',
                   'videoMediaConverter_ogv', 'videoMediaConverter_3gp',
                   'videoMediaConverter_mpg',
                   'videoMediaConverter_avi', 'audioMediaConverter_ogg',
                   'audioMediaConverter_au', 'audioMediaConverter_mp3',
                   'audioMediaConverter_wav', 'ffmpegPath'),
        'user': ('locale', 'lastDir', 'showPreferencesOnStart','defaultStyle', 'showIdevicesGrouped','docType','editorMode'),
    }

    idevicesCategories = {
        'activity': [x_('Non-Interactive Activities')],
        'reading activity': [x_('Non-Interactive Activities')],
        'dropdown activity': [x_('Interactive Activities')],
        'java applet': [x_('Non-Textual Information')],
        'wiki article': [x_('Non-Textual Information')],
        'case study': [x_('Non-Interactive Activities')],
        'preknowledge': [x_('Textual Information')],
        'scorm quiz': [x_('Interactive Activities')],
        'fpd - multi choice activity': [x_('FPD')],
        'fpd - cloze activity': [x_('FPD')],
        'fpd - cloze activity (modified)': [x_('FPD')],
        'fpd - multi select activity': [x_('FPD')],
        'fpd - true/false activity': [x_('FPD')],
        'fpd - situation': [x_('FPD')],
        'fpd - quotation': [x_('FPD')],
        'fpd - you should know': [x_('FPD')],
        'fpd - highlighted': [x_('FPD')],
        'fpd - translation': [x_('FPD')],
        'fpd - guidelines students': [x_('FPD')],
        'fpd - guidelines teacher': [x_('FPD')],
        'fpd - a step ahead': [x_('FPD')],
        'fpd - a piece of advice': [x_('FPD')],
        'fpd - think about it (with feedback)': [x_('FPD')],
        'fpd - think about it (without feedback)': [x_('FPD')],
        'fpd - free text': [x_('FPD')],
        'image gallery': [x_('Non-Textual Information')],
        'image magnifier': [x_('Non-Textual Information')],
        'note': [x_('Textual Information')],
        'objectives': [x_('Textual Information')],
        'multi-choice': [x_('Interactive Activities')],
        'multi-select': [x_('Interactive Activities')],
        'true-false question': [x_('Interactive Activities')],
        'reflection': [x_('Non-Interactive Activities')],
        'cloze activity': [x_('Interactive Activities')],
        'rss': [x_('Non-Textual Information')],
        'external web site': [x_('Non-Textual Information')],
        'free text': [x_('Textual Information')],
        'click in order game': [x_('Experimental')],
        'hangman game': [x_('Experimental')],
        'place the objects': [x_('Interactive Activities')],
        'memory match game': [x_('Experimental')],
        'file attachments': [x_('Non-Textual Information')],
        'sort items': [x_('Experimental')],
        'sort items': [x_('Interactive Activities')],
        'scorm test cloze': [x_('Interactive Activities')],
        'scorm test cloze (multiple options)': [x_('Interactive Activities')],
        'scorm test dropdown': [x_('Interactive Activities')],
        'scorm test multiple choice': [x_('Interactive Activities')]
    }
    
    @classmethod
    def getConfigPath(cls):
        obj = cls.__new__(cls)
        obj.configParser = ConfigParser()
        obj._overrideDefaultVals()
        obj.__setConfigPath()
        return obj.configPath

    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser(self.onWrite)
        # Set default values
        # exePath is the whole path and filename of the exe executable
        self.exePath     = Path(sys.argv[0]).abspath()
        # webDir is the parent directory for styles,scripts and templates
        self.webDir      = self.exePath.dirname()
        self.jsDir       = self.exePath.dirname()
        # localeDir is the base directory where all the locales are stored
        self.localeDir   = self.exePath.dirname()/"locale"
        # port is the port the exe webserver will listen on 
        # (previous default, which earlier users might still use, was 8081)
        self.port        = 51235
        # dataDir is the default directory that is shown to the user
        # to save packages and exports in
        self.dataDir     = Path(".")
        # configDir is the dir for storing user profiles
        # and user made idevices and the config file
        self.configDir   = Path(".")
		#FM: New Styles Directory path
        self.stylesDir =Path(self.configDir/'style').abspath()
        #FM: Default Style name
        self.defaultStyle= u"standardwhite"
        # browser is the name of a predefined browser specified at http://docs.python.org/library/webbrowser.html.
        # None for system default
        self.browser = None
        # docType  is the HTML export format
        self.docType = 'XHTML' 
        # locale is the language of the user
        self.locale = chooseDefaultLocale(self.localeDir)
        # internalAnchors indicate which exe_tmp_anchor tags to generate for each tinyMCE field
        # available values = "enable_all", "disable_autotop", or "disable_all"
        self.internalAnchors = "enable_all"
        self.lastDir = None
        self.showPreferencesOnStart = "1"
        self.showIdevicesGrouped = "1"
        # tinymce option
        self.editorMode = 'permissive' 
        # styleSecureMode : if this [user] key is = 0  , exelearning can run python files in styles
        # as websitepage.py , ... ( deactivate secure mode )
        self.styleSecureMode="1"
        # styles is the list of style names available for loading
        self.styles      = []
        # The documents that we've recently looked at
        self.recentProjects = []
        # canonical (English) names of iDevices not to show in the iDevice pane
        self.hiddeniDevices = []
        #Media conversion programs used for XML export system
        self.videoMediaConverter_ogv = ""
        self.videoMediaConverter_3gp = ""
        self.videoMediaConverter_avi = ""
        self.videoMediaConverter_mpg = ""
        self.audioMediaConverter_ogg = ""
        self.audioMediaConverter_au = ""
        self.audioMediaConverter_mp3 = ""
        self.audioMediaConverter_wav = ""
        self.ffmpegPath = ""
        self.mediaProfilePath = self.exePath.dirname()/'mediaprofiles'
        
        # likewise, a canonical (English) names of iDevices not to show in the
        # iDevice pane but, contrary to the hiddens, these are ones that the 
        # configuration can specify to turn ON:
        self.deprecatediDevices = [ "flash with text", "flash movie", "mp3", \
                                    "attachment"]
        # by default, only allow embedding of media types for which a 
        # browser plugin is found:
        self.assumeMediaPlugins = False;
        # Let our children override our defaults depending
        # on the OS that we're running on
        self._overrideDefaultVals()
        # Try to make the defaults a little intelligent
        # Under devel trees, webui is the default webdir
        self.webDir = Path(self.webDir)
        if not (self.webDir/'scripts').isdir() \
           and (self.webDir/'webui').isdir():
            self.webDir /= 'webui'
        self.jsDir = Path(self.jsDir)
        if not (self.jsDir/'scripts').isdir() \
           and (self.jsDir/'jsui').isdir():
            self.jsDir /= 'jsui'
        # Find where the config file will be saved
        self.__setConfigPath()
        # Fill in any undefined config options with our defaults
        self._writeDefaultConfigFile()
        # Now we are ready to serve the application
        self.loadSettings()
        self.setupLogging()
        self.loadLocales()
        self.loadStyles()



    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """

    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ['exe.conf']


    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file 
        (auto write is on so we don't need to write the file at the end)
        """
        if not G.application.portable:
            for sectionName, optionNames in self.optionNames.items():
                for optionName in optionNames:
                    defaultVal = getattr(self, optionName)
                    self.configParser.setdefault(sectionName, 
                                             optionName, 
                                             defaultVal)
                    # Logging can't really be changed from inside the program at the moment...
            self.configParser.setdefault('logging', 'root', 'INFO')


    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        # If there's an EXECONF environment variable, use it
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        # Otherwise find the most appropriate existing file
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                # If no config files exist, create and use the
                # first one on the list
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        # Now make our configParser
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True


    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section('system'):
            system = self.configParser.system
            if system.has_option('appDataDir'):
                # Older config files had configDir stored as appDataDir
                self.configDir = Path(system.appDataDir)
                self.stylesDir =Path(self.configDir)/'style'
                # We'll just upgrade their config file for them for now...
                system.configDir = self.configDir
                system.stylesDir =Path(self.configDir)/'style'
                del system.appDataDir
                
                self.audioMediaConverter_au = system.audioMediaConverter_au
                self.audioMediaConverter_wav = system.audioMediaConverter_wav
                self.videoMediaConverter_ogv = system.videoMediaConverter_ogv
                self.videoMediaConverter_3gp = system.videoMediaConverter_3gp
                self.videoMediaConverter_avi = system.videoMediaConverter_avi
                self.videoMediaConverter_mpg = system.videoMediaConverter_mpg
                self.audioMediaConverter_ogg = system.audioMediaConverter_ogg
                self.audioMediaConverter_mp3 = system.audioMediaConverter_mp3
                self.ffmpegPath = system.ffmpegPath
            
            self.mediaProfilePath = system.mediaProfilePath
                
            if system.has_option('greDir'):
                # No longer used, system should automatically support
                del system.greDir


    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """
        # Set up the parser so that if a certain value is not in the config
        # file, it will use the value from our default values
        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)
        self.configParser.defaultValue = defVal
        self.upgradeFile()
        # System Section
        if self.configParser.has_section('system'):
            system = self.configParser.system

            
            self.port           = int(system.port)
            self.browser        = None if system.browser == u"None" else system.browser
            
            
            if not G.application.portable:
                self.dataDir        = Path(system.dataDir)
                self.configDir      = Path(system.configDir)
                self.webDir         = Path(system.webDir)
                self.stylesDir      = Path(self.configDir)/'style'
                self.jsDir          = Path(system.jsDir)
            else:
                self.stylesDir      = Path(self.webDir/'style').abspath()
            
            self.assumeMediaPlugins = False;
            if self.configParser.has_option('system', \
                    'assumeMediaPlugins'):
               value = system.assumeMediaPlugins.strip().lower()
               if value == "1" or value == "yes" or value == "true" or \
                   value == "on":
                       self.assumeMediaPlugins = True;

        # If the dataDir points to some other dir, fix it
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        # make the webDir absolute, to hide path joins of relative paths
        self.webDir = self.webDir.expand().abspath()
        # If the configDir doesn't exist (as it may be a default setting with a
        # new installation) create it
        if not self.configDir.exists():
            self.configDir.mkdir()
		
        if not G.application.standalone: 
             #FM: Copy styles         
            if not os.path.exists(self.stylesDir) or not os.listdir(self.stylesDir):
                self.copyStyles() 
            else:
                self.updateStyles()                      
        else:
            if G.application.portable:
                if os.name == 'posix': 
                    self.stylesDir      = Path(self.webDir/'..'/'..'/'..'/'style')
                else: 
                    self.stylesDir      = Path(self.webDir/'..'/'style')
                if not os.path.exists(self.stylesDir) or not os.listdir(self.stylesDir): 
                    self.copyStyles()
            else:
                self.stylesDir     = Path(self.webDir/'style').abspath()
            
               
        # Get the list of recently opened projects
        self.recentProjects = []
        if self.configParser.has_section('recent_projects'):
            recentProjectsSection = self.configParser.recent_projects
            # recentProjectsSection.items() is in the wrong order, keys are alright.
            # Sorting list by key before adding to self.recentProjects, to avoid wrong ordering
            # in Recent Projects menu list
            recentProjectsItems = recentProjectsSection.items();
            recentProjectsItems.sort()
            for key, path in recentProjectsItems:
                self.recentProjects.append(path)
                
        # Load the list of "hidden" iDevices
        self.hiddeniDevices = []
        if self.configParser.has_section('idevices'):
            idevicesSection = self.configParser.idevices
            for key,value in idevicesSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "0" or value == "no" or value == "false" or \
                        value == "off":
                    self.hiddeniDevices.append(key.lower())

        #self.deprecatediDevices = [ "flash with text", "flash movie", ...]
        # and UN-Load from the list of "deprecated" iDevices
        if self.configParser.has_section('deprecated'):
            deprecatedSection = self.configParser.deprecated
            for key,value in deprecatedSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                        value == "on":
                    if key.lower() in self.deprecatediDevices:
                        self.deprecatediDevices.remove(key.lower())

        # Load the "user" section
        if self.configParser.has_section('user'):
            if self.configParser.user.has_option('editorMode'):
                self.editorMode = self.configParser.user.editorMode
            if self.configParser.user.has_option('docType'):
                self.docType = self.configParser.user.docType
                common.setExportDocType(self.configParser.user.docType)
            if self.configParser.user.has_option('defaultStyle'):
                self.defaultStyle= self.configParser.user.defaultStyle
            if self.configParser.user.has_option('styleSecureMode'):
                self.styleSecureMode= self.configParser.user.styleSecureMode
            if self.configParser.user.has_option('internalAnchors'):
                self.internalAnchors = self.configParser.user.internalAnchors
            if self.configParser.user.has_option('lastDir'):
                self.lastDir = self.configParser.user.lastDir
            if self.configParser.user.has_option('showPreferencesOnStart'):
                self.showPreferencesOnStart = self.configParser.user.showPreferencesOnStart
            if self.configParser.user.has_option('showIdevicesGrouped'):
                self.showIdevicesGrouped = self.configParser.user.showIdevicesGrouped
            if self.configParser.user.has_option('locale'):
                self.locale = self.configParser.user.locale
                return
        self.locale = chooseDefaultLocale(self.localeDir)

    def onWrite(self, configParser):
        """
        Called just before the config file is written.
        We use it to fill out any settings that are stored here and 
        not in the config parser itself
        """
        # Recent projects
        self.configParser.delete('recent_projects')
        recentProjectsSection = self.configParser.addSection('recent_projects')
        for num, path in enumerate(self.recentProjects):
            recentProjectsSection[str(num)] = path

    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir/'exe.log', 'a', 
                                       500000, 10)
            hdlr.doRollover()
        except OSError:
            # ignore the error we get if the log file is logged
            hdlr = logging.FileHandler(self.configDir/'exe.log')

        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log    = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)

        loggingLevels = {"DEBUG"    : logging.DEBUG,
                         "INFO"     : logging.INFO,
                         "WARNING"  : logging.WARNING,
                         "ERROR"    : logging.ERROR,
                         "CRITICAL" : logging.CRITICAL }

    
        if self.configParser.has_section('logging'):
            for logger, level in self.configParser._sections["logging"].items():
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])
        if not G.application.portable:
            log.info("************** eXe logging started **************")
            log.info("version     = %s" % version.version)
            log.info("configPath  = %s" % self.configPath)
            log.info("exePath     = %s" % self.exePath)
            log.info("libPath     = %s" % Path(twisted.__path__[0]).splitpath()[0])
            log.info("browser     = %s" % self.browser)
            log.info("webDir      = %s" % self.webDir)
            log.info("jsDir       = %s" % self.jsDir)
            log.info("localeDir   = %s" % self.localeDir)
            log.info("port        = %d" % self.port)
            log.info("dataDir     = %s" % self.dataDir)
            log.info("configDir   = %s" % self.configDir)
            log.info("locale      = %s" % self.locale)
            log.info("internalAnchors = %s" % self.internalAnchors)
                    

    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        self.styleStore = StyleStore(self)
        listStyles = self.styleStore.getStyles()
        for style in listStyles:
            self.styles.append(style)
            #print style
            
    def copyStyles(self):
        bkstyle=self.webDir/'style'
        dststyle=self.stylesDir
        if os.path.exists(bkstyle):            
            if os.path.exists(dststyle) and not os.listdir(self.stylesDir): shutil.rmtree(dststyle)                 
            shutil.copytree(bkstyle,dststyle )
            
    def updateStyles(self):
        bkstyle=self.webDir/'style'
        dststyle=self.stylesDir
        if os.stat(bkstyle).st_mtime - os.stat(dststyle).st_mtime > 1:
            for name in os.listdir(bkstyle):
                bksdirstyle=os.path.join(bkstyle, name)
                dstdirstyle=os.path.join(dststyle, name)
                if os.path.isdir(bksdirstyle):
                    if os.path.exists(dstdirstyle):shutil.rmtree(dstdirstyle)
                    shutil.copytree(bksdirstyle, dstdirstyle)
                else:
                    shutil.copy(bksdirstyle, dstdirstyle)                    
                    

    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install('exe', self.localeDir, True)
        self.locales = {}
        for subDir in self.localeDir.dirs():
            if (subDir/'LC_MESSAGES'/'exe.mo').exists():
                self.locales[subDir.basename()] = \
                    gettext.translation('exe', 
                                        self.localeDir, 
                                        languages=[str(subDir.basename())])
                if subDir.basename() == self.locale:
                    locale = subDir.basename()
                    log.debug(" loading locale %s" % locale)
                    self.locales[locale].install(unicode=True)
                    __builtins__['c_'] = lambda s: self.locales[locale].ugettext(s) if s else s
Beispiel #16
0
    def render(self, request):
        if "sendWhat" in request.args:
            if request.args['sendWhat'][0] == 'dirs':
                pathdir = Path(unquote(request.args['node'][0].decode('utf-8')))
                l = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for d in get_drives():
                        try:
                            if is_readable(Path(d)):
                                icon = None
                            else:
                                icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                            l.append({"realtext": d, "text": d, "id": d + '\\', "icon": icon})
                        except:
                            pass
                else:
                    for d in pathdir.dirs():
                        try:
                            if not d.name.startswith('.') or sys.platform[:3] == "win":
                                if not iswinlink(d.abspath()):
                                    if is_readable(d):
                                        icon = None
                                    else:
                                        icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                                    l.append({"realtext": d.name, "text": getname(d), "id": d.abspath(), "icon": icon})
                        except:
                            pass
            elif request.args['sendWhat'][0] == 'both':
                pathdir = Path(unquote(request.args['dir'][0].decode('utf-8')))
                items = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for drive in get_drives():
                        d = Path(drive + '\\')
                        items.append({"name": drive, "realname": drive + '\\', "size": 0, "type": 'directory', "modified": 0,
                                      "is_readable": is_readable(d),
                                      "is_writable": is_writable(d)})
                else:
                    parent = pathdir.parent
                    if (parent == pathdir):
                        realname = '/'
                    else:
                        realname = parent.abspath()
                    items.append({"name": '.', "realname": pathdir.abspath(), "size": pathdir.size, "type": "directory", "modified": int(pathdir.mtime),
                                  "is_readable": is_readable(pathdir),
                                  "is_writable": is_writable(pathdir)})
                    items.append({"name": '..', "realname": realname, "size": parent.size, "type": "directory", "modified": int(parent.mtime),
                                  "is_readable": is_readable(parent),
                                  "is_writable": is_writable(parent)})
                    try:
                        for d in pathdir.listdir():
                            try:
                                if not d.name.startswith('.') or sys.platform[:3] == "win":
                                    if not iswinlink(d.abspath()):
                                        if d.isdir():
                                            pathtype = "directory"
                                        elif d.isfile():
                                            if is_readable(d):
                                                pathtype = repr(mimetypes.guess_type(d.name, False)[0])
                                            else:
                                                pathtype = "file"
                                        elif d.islink():
                                            pathtype = "link"
                                        else:
                                            pathtype = "None"
                                        items.append({"name": getname(d), "realname": d.abspath(), "size": d.size, "type": pathtype, "modified": int(d.mtime),
                                          "is_readable": is_readable(d),
                                          "is_writable": is_writable(d)})
                            except:
                                pass
                        G.application.config.lastDir = pathdir
                    except:
                        pass
                l = {"totalCount": len(items), 'results': len(items), 'items': items}
            return json.dumps(l).encode('utf-8')
        elif "query" in request.args:
            query = request.args['query'][0]
            pathdir = Path(unquote(request.args['dir'][0].decode('utf-8')))
            items = []
            if pathdir == '/' and sys.platform[:3] == "win":
                for d in get_drives():
                    items.append({"name": d, "realname": d + '\\', "size": 0, "type": 'directory', "modified": 0})
            else:
                parent = pathdir.parent
                if (parent == pathdir):
                    realname = '/'
                else:
                    realname = parent.abspath()
                for d in pathdir.listdir():
                    try:
                        if d.isdir():
                            pathtype = "directory"
                        elif d.isfile():
                            if is_readable(d):
                                pathtype = repr(mimetypes.guess_type(d.name, False)[0])
                            else:
                                pathtype = "file"
                        elif d.islink():
                            pathtype = "link"
                        else:
                            pathtype = "None"
                        if d.name.startswith(query):
                            items.append({"name": getname(d), "realname": d.abspath(), "size": d.size, "type": pathtype, "modified": int(d.mtime),
                                          "is_readable": is_readable(d),
                                          "is_writable": is_writable(d)})
                    except:
                        pass

            l = {"totalCount": len(items), 'results': len(items), 'items': items}
            return json.dumps(l).encode('utf-8')
        return ""
Beispiel #17
0
 def __init__(self, filename = None, name = None):
     '''
     Constructor
     '''
     self.filename = filename
     if name is not None:
         self.name = name
     else:
         self.name = os.path.basename(filename)
     
     self.resourceDir = TempDirPath()
     
     #TODO: inspect filenames for untrusted entries e.g. .. and /
     zippedFile = zipfile.ZipFile(filename, "r")
     for fn in zippedFile.namelist():
         #check to make sure that we have the required directories
         Dir = None
         if fn[-1:] == '/':
             Dir = Path(self.resourceDir/fn)
         else:
             Dir = Path(self.resourceDir/os.path.dirname(fn))
         
         if not Dir.exists():
             Dir.makedirs()
             
             
         Fn = Path(self.resourceDir/fn)
         
         if not Fn.isdir():
             outFile = open(self.resourceDir/fn, "wb")
             outFile.write(zippedFile.read(fn))
             outFile.flush()
             outFile.close()
             file_info = zippedFile.getinfo(fn)
             mod_time =time.mktime(file_info.date_time+(0,0,-1))
             os.utime(self.resourceDir/fn, (time.time(), mod_time))
     
     #update files here...
     
     ocf_str = open(self.resourceDir/"META-INF/container.xml", 'r').read()
     self.ocf = EPUBOCF(ocf_doc = ocf_str)
     self.opfs = []
     for container in self.ocf.root_containers:
         if container.media_type == "application/oebps-package+xml":
             opf_path = os.path.join(self.resourceDir, container.full_path)
             opf_str = open(opf_path, 'r').read()
             self.opfs.append(EPUBOPF(opf_path, opf_str = opf_str, 
                                      container_path = container.full_path, package = self)) 
     
     
     # for now we handle one OPF in a package
     self.main_opf = self.opfs[0]
     self.main_manifest = self.main_opf.manifest
     self.root = self.main_opf.get_navigation()
     
     if EPUBPackage.UPDATE_ALL_ON_OPEN:
         self.main_opf.resource_manager.update_all_pages()
     
     self.currentNode = self.root
     self.tincan_manager = TinCanXMLManager(self)
     self.isChanged = False
Beispiel #18
0
class Config:
    """
    The Config class contains the configuration information for eXe.
    """

    optionNames = {
        "system": ("webDir", "xulDir", "port", "dataDir", "configDir", "localeDir", "browserPath"),
        "user": ("locale",),
    }

    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser()
        self.exePath = Path(sys.argv[0]).abspath()
        self.webDir = self.exePath.dirname()
        self.xulDir = self.exePath.dirname()
        self.localeDir = self.exePath.dirname() / "locale"
        self.port = 51235
        self.dataDir = Path(".")
        self.configDir = Path(".")
        self.browserPath = Path("firefox")
        self.locale = chooseDefaultLocale(self.localeDir)
        self.styles = []
        self._overrideDefaultVals()
        self.webDir = Path(self.webDir)
        if not (self.webDir / "scripts").isdir() and (self.webDir / "webui").isdir():
            self.webDir /= "webui"
        self.xulDir = Path(self.xulDir)
        if not (self.xulDir / "scripts").isdir() and (self.xulDir / "xului").isdir():
            self.xulDir /= "xului"
        self.__setConfigPath()
        self._writeDefaultConfigFile()
        self.loadSettings()
        self.setupLogging()
        self.loadStyles()
        self.loadLocales()

    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """

    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ["exe.conf"]

    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file 
        (auto write is on so we don't need to write the file at the end)
        """
        for sectionName, optionNames in self.optionNames.items():
            for optionName in optionNames:
                defaultVal = getattr(self, optionName)
                self.configParser.setdefault(sectionName, optionName, defaultVal)
        self.configParser.setdefault("logging", "root", "INFO")

    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True

    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section("system"):
            system = self.configParser.system
            if system.has_option("appDataDir"):
                self.configDir = Path(system.appDataDir)
                system.configDir = self.configDir
                del system.appDataDir
            if system.has_option("greDir"):
                del system.greDir

    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """

        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)

        self.configParser.defaultValue = defVal
        self.upgradeFile()
        if self.configParser.has_section("system"):
            system = self.configParser.system
            self.webDir = Path(system.webDir)
            self.xulDir = Path(system.xulDir)
            self.localeDir = Path(system.localeDir)
            self.port = int(system.port)
            self.browserPath = Path(system.browserPath)
            self.dataDir = Path(system.dataDir)
            self.configDir = Path(system.configDir)
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        self.webDir = self.webDir.expand().abspath()
        if not self.configDir.exists():
            self.configDir.mkdir()
        if self.configParser.has_section("user"):
            if self.configParser.user.has_option("locale"):
                self.locale = self.configParser.user.locale
                return
        self.locale = chooseDefaultLocale(self.localeDir)

    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir / "exe.log", "a", 500000, 10)
            hdlr.doRollover()
        except OSError:
            hdlr = logging.FileHandler(self.configDir / "exe.log")
        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)
        loggingLevels = {
            "DEBUG": logging.DEBUG,
            "INFO": logging.INFO,
            "WARNING": logging.WARNING,
            "ERROR": logging.ERROR,
            "CRITICAL": logging.CRITICAL,
        }
        if self.configParser.has_section("logging"):
            for logger, level in self.configParser._sections["logging"].items():
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])
        log.info("************** eXe logging started **************")
        log.info("configPath  = %s" % self.configPath)
        log.info("exePath     = %s" % self.exePath)
        log.info("browserPath = %s" % self.browserPath)
        log.info("webDir      = %s" % self.webDir)
        log.info("xulDir      = %s" % self.xulDir)
        log.info("localeDir   = %s" % self.localeDir)
        log.info("port        = %d" % self.port)
        log.info("dataDir     = %s" % self.dataDir)
        log.info("configDir   = %s" % self.configDir)
        log.info("locale      = %s" % self.locale)

    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        log = logging.getLogger()
        self.styles = []
        styleDir = self.webDir / "style"
        log.debug("loadStyles from %s" % styleDir)
        for subDir in styleDir.dirs():
            styleSheet = subDir / "content.css"
            log.debug(" checking %s" % styleSheet)
            if styleSheet.exists():
                style = subDir.basename()
                log.debug(" loading style %s" % style)
                self.styles.append(style)

    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install("exe", self.localeDir, True)
        self.locales = {}
        for subDir in self.localeDir.dirs():
            if (subDir / "LC_MESSAGES" / "exe.mo").exists():
                self.locales[subDir.basename()] = gettext.translation(
                    "exe", self.localeDir, languages=[str(subDir.basename())]
                )
                if subDir.basename() == self.locale:
                    locale = subDir.basename()
                    log.debug(" loading locale %s" % locale)
                    self.locales[locale].install(unicode=True)
Beispiel #19
0
class Config(object):
    """
    The Config class contains the configuration information for eXe.
    """

    # To build link to git revision
    baseGitWebURL = 'https://github.com/exelearning/iteexe'

    # Class attributes
    optionNames = {
        'system': ('webDir', 'jsDir', 'port', 'dataDir',
                   'configDir', 'localeDir', 'stylesRepository',
                   'browser', 'mediaProfilePath',
                   'videoMediaConverter_ogv', 'videoMediaConverter_3gp',
                   'videoMediaConverter_mpg',
                   'videoMediaConverter_avi', 'audioMediaConverter_ogg',
                   'audioMediaConverter_au', 'audioMediaConverter_mp3',
                   'audioMediaConverter_wav', 'ffmpegPath'),
        'user': ('locale', 'lastDir', 'showPreferencesOnStart',
                 'defaultStyle', 'showIdevicesGrouped', 'docType', 'editorMode', 'editorVersion', 'defaultLicense'),
    }

    idevicesCategories = {
        'activity': [x_('Non-Interactive Activities')],
        'reading activity': [x_('Non-Interactive Activities')],
        'dropdown activity': [x_('Interactive Activities')],
        'java applet': [x_('Non-Textual Information')],
        'wiki article': [x_('Non-Textual Information')],
        'case study': [x_('Non-Interactive Activities')],
        'preknowledge': [x_('Textual Information')],
        'scorm quiz': [x_('Interactive Activities')],
        'fpd - multi choice activity': [x_('FPD')],
        'fpd - cloze activity': [x_('FPD')],
        'fpd - cloze activity (modified)': [x_('FPD')],
        'fpd - multi select activity': [x_('FPD')],
        'fpd - true/false activity': [x_('FPD')],
        'fpd - situation': [x_('FPD')],
        'fpd - quotation': [x_('FPD')],
        'fpd - you should know': [x_('FPD')],
        'fpd - highlighted': [x_('FPD')],
        'fpd - translation': [x_('FPD')],
        'fpd - guidelines students': [x_('FPD')],
        'fpd - guidelines teacher': [x_('FPD')],
        'fpd - a step ahead': [x_('FPD')],
        'fpd - a piece of advice': [x_('FPD')],
        'fpd - think about it (with feedback)': [x_('FPD')],
        'fpd - think about it (without feedback)': [x_('FPD')],
        'fpd - free text': [x_('FPD')],
        'image gallery': [x_('Non-Textual Information')],
        'image magnifier': [x_('Non-Textual Information')],
        'note': [x_('Textual Information')],
        'objectives': [x_('Textual Information')],
        'multi-choice': [x_('Interactive Activities')],
        'multi-select': [x_('Interactive Activities')],
        'true-false question': [x_('Interactive Activities')],
        'reflection': [x_('Non-Interactive Activities')],
        'cloze activity': [x_('Interactive Activities')],
        'rss': [x_('Non-Textual Information')],
        'external web site': [x_('Non-Textual Information')],
        'free text': [x_('Textual Information')],
        'click in order game': [x_('Experimental')],
        'hangman game': [x_('Experimental')],
        'place the objects': [x_('Interactive Activities')],
        'memory match game': [x_('Experimental')],
        'file attachments': [x_('Non-Textual Information')],
        'sort items': [x_('Experimental')]
    }

    @classmethod
    def getConfigPath(cls):
        obj = cls.__new__(cls)
        obj.configParser = ConfigParser()
        obj._overrideDefaultVals()
        obj.__setConfigPath()
        return obj.configPath

    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser(self.onWrite)
        # Set default values
        # exePath is the whole path and filename of the exe executable
        self.exePath     = Path(sys.argv[0]).abspath()
        # webDir is the parent directory for styles,scripts and templates
        self.webDir      = self.exePath.dirname()
        self.jsDir       = self.exePath.dirname()
        self.locales     = {}
        # localeDir is the base directory where all the locales are stored
        self.localeDir   = self.exePath.dirname()/"locale"
        # port is the port the exe webserver will listen on
        # (previous default, which earlier users might still use, was 8081)
        self.port        = 51235
        # dataDir is the default directory that is shown to the user
        # to save packages and exports in
        self.dataDir     = Path(".")
        # configDir is the dir for storing user profiles
        # and user made idevices and the config file
        self.configDir   = Path(".")
        # FM: New Styles Directory path
        self.stylesDir   = Path(self.configDir/'style').abspath()
        # FM: Default Style name
        self.defaultStyle = u"INTEF"
        # Styles repository XML-RPC endpoint
        # self.stylesRepository = 'http://www.exelearning.es/xmlrpc.php'
        self.stylesRepository = 'http://www.exelearning.net/xmlrpc.php'
        # browser is the name of a predefined browser specified
        # at http://docs.python.org/library/webbrowser.html.
        # None for system default
        self.browser = None
        # docType  is the HTML export format
        self.docType = 'HTML5'
        # internalAnchors indicate which exe_tmp_anchor tags to generate for each tinyMCE field
        # available values = "enable_all", "disable_autotop", or "disable_all"
        self.internalAnchors = "enable_all"
        self.lastDir = None
        self.showPreferencesOnStart = "1"
        self.showIdevicesGrouped = "1"
        # tinymce option
        self.editorMode = 'permissive'
        self.editorVersion = '4'
        # styleSecureMode : if this [user] key is = 0  , exelearning can run python files in styles
        # as websitepage.py , ... ( deactivate secure mode )
        self.styleSecureMode = "1"
        # styles is the list of style names available for loading
        self.styles = []
        # The documents that we've recently looked at
        self.recentProjects = []
        # canonical (English) names of iDevices not to show in the iDevice pane
        self.hiddeniDevices = []
        # Media conversion programs used for XML export system
        self.videoMediaConverter_ogv = ""
        self.videoMediaConverter_3gp = ""
        self.videoMediaConverter_avi = ""
        self.videoMediaConverter_mpg = ""
        self.audioMediaConverter_ogg = ""
        self.audioMediaConverter_au = ""
        self.audioMediaConverter_mp3 = ""
        self.audioMediaConverter_wav = ""
        self.ffmpegPath = ""
        self.mediaProfilePath = self.exePath.dirname()/'mediaprofiles'

        # likewise, a canonical (English) names of iDevices not to show in the
        # iDevice pane but, contrary to the hiddens, these are ones that the
        # configuration can specify to turn ON:
        self.deprecatediDevices = ["flash with text", "flash movie", "mp3",
                                   "attachment"]
        # by default, only allow embedding of media types for which a
        # browser plugin is found:

        self.defaultLicense='creative commons: attribution - share alike 4.0'

        self.assumeMediaPlugins = False
        # Let our children override our defaults depending
        # on the OS that we're running on
        self._overrideDefaultVals()
        # locale is the language of the user. localeDir can be overridden
        # that's why we must set it _after_ the call to _overrideDefaultVals()
        self.locale = chooseDefaultLocale(self.localeDir)
        # Try to make the defaults a little intelligent
        # Under devel trees, webui is the default webdir
        self.webDir = Path(self.webDir)
        if not (self.webDir/'scripts').isdir() \
           and (self.webDir/'webui').isdir():
            self.webDir /= 'webui'
        self.jsDir = Path(self.jsDir)
        if not (self.jsDir/'scripts').isdir() \
           and (self.jsDir/'jsui').isdir():
            self.jsDir /= 'jsui'
        # Find where the config file will be saved
        self.__setConfigPath()
        # Fill in any undefined config options with our defaults
        self._writeDefaultConfigFile()
        # Now we are ready to serve the application
        self.loadSettings()
        self.setupLogging()
        self.loadLocales()
        self.loadStyles()

    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """

    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ['exe.conf']

    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file
        (auto write is on so we don't need to write the file at the end)
        """
        if not G.application.portable:
            for sectionName, optionNames in self.optionNames.items():
                for optionName in optionNames:
                    defaultVal = getattr(self, optionName)
                    self.configParser.setdefault(sectionName,
                                                 optionName,
                                                 defaultVal)
            # Logging can't really be changed from inside the program at the moment...
            self.configParser.setdefault('logging', 'root', 'INFO')

    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        # If there's an EXECONF environment variable, use it
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        # Otherwise find the most appropriate existing file
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                # If no config files exist, create and use the
                # first one on the list
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        # Now make our configParser
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True

    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section('system'):
            system = self.configParser.system
            if system.has_option('appDataDir'):
                # Older config files had configDir stored as appDataDir
                self.configDir = Path(system.appDataDir)
                self.stylesDir = Path(self.configDir)/'style'
                # We'll just upgrade their config file for them for now...
                system.configDir = self.configDir
                system.stylesDir = Path(self.configDir)/'style'
                del system.appDataDir

                self.audioMediaConverter_au = system.audioMediaConverter_au
                self.audioMediaConverter_wav = system.audioMediaConverter_wav
                self.videoMediaConverter_ogv = system.videoMediaConverter_ogv
                self.videoMediaConverter_3gp = system.videoMediaConverter_3gp
                self.videoMediaConverter_avi = system.videoMediaConverter_avi
                self.videoMediaConverter_mpg = system.videoMediaConverter_mpg
                self.audioMediaConverter_ogg = system.audioMediaConverter_ogg
                self.audioMediaConverter_mp3 = system.audioMediaConverter_mp3
                self.ffmpegPath = system.ffmpegPath

            self.mediaProfilePath = system.mediaProfilePath

            if system.has_option('greDir'):
                # No longer used, system should automatically support
                del system.greDir
            if system.has_option('xulDir'):
                del system.xulDir
            # if system.has_option('browser'):
            #    del system.browser

    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """
        # Set up the parser so that if a certain value is not in the config
        # file, it will use the value from our default values
        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)
        self.configParser.defaultValue = defVal
        self.upgradeFile()
        # System Section
        if self.configParser.has_section('system'):
            system = self.configParser.system

            self.port           = int(system.port)
            self.browser        = None if system.browser == u"None" else system.browser
            self.stylesRepository = system.stylesRepository

            if not G.application.portable:
                self.dataDir        = Path(system.dataDir)
                self.configDir      = Path(system.configDir)
                self.webDir         = Path(system.webDir)
                self.stylesDir      = Path(self.configDir)/'style'
                self.jsDir          = Path(system.jsDir)
            else:
                self.stylesDir      = Path(self.webDir/'style').abspath()

            self.assumeMediaPlugins = False
            if self.configParser.has_option('system', 'assumeMediaPlugins'):
                value = system.assumeMediaPlugins.strip().lower()
                if value == "1" or value == "yes" or value == "true" or value == "on":
                    self.assumeMediaPlugins = True

        # If the dataDir points to some other dir, fix it
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        # make the webDir absolute, to hide path joins of relative paths
        self.webDir = self.webDir.expand().abspath()
        # If the configDir doesn't exist (as it may be a default setting with a
        # new installation) create it
        if not self.configDir.exists():
            self.configDir.mkdir()

        if not G.application.standalone:
            # FM: Copy styles
            if not os.path.exists(self.stylesDir) or not os.listdir(self.stylesDir):
                self.copyStyles()
            else:
                self.updateStyles()
        else:
            if G.application.portable:
                if os.name == 'posix':
                    self.stylesDir = Path(self.webDir/'..'/'..'/'..'/'style')
                else:
                    self.stylesDir = Path(self.webDir/'..'/'style')
                if not os.path.exists(self.stylesDir) or not os.listdir(self.stylesDir):
                    self.copyStyles()
            else:
                self.stylesDir = Path(self.webDir/'style').abspath()

        # Get the list of recently opened projects
        self.recentProjects = []
        if self.configParser.has_section('recent_projects'):
            recentProjectsSection = self.configParser.recent_projects
            # recentProjectsSection.items() is in the wrong order, keys are alright.
            # Sorting list by key before adding to self.recentProjects, to avoid wrong ordering
            # in Recent Projects menu list
            recentProjectsItems = recentProjectsSection.items()
            recentProjectsItems.sort()
            for key, path in recentProjectsItems:
                self.recentProjects.append(path)

        # Load the list of "hidden" iDevices
        self.hiddeniDevices = []
        if self.configParser.has_section('idevices'):
            idevicesSection = self.configParser.idevices
            for key, value in idevicesSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "0" or value == "no" or value == "false" or \
                        value == "off":
                    self.hiddeniDevices.append(key.lower())

        # self.deprecatediDevices = [ "flash with text", "flash movie", ...]
        # and UN-Load from the list of "deprecated" iDevices
        if self.configParser.has_section('deprecated'):
            deprecatedSection = self.configParser.deprecated
            for key, value in deprecatedSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                        value == "on":
                    if key.lower() in self.deprecatediDevices:
                        self.deprecatediDevices.remove(key.lower())

        # Load the "user" section
        if self.configParser.has_section('user'):
            if self.configParser.user.has_option('editorMode'):
                self.editorMode = self.configParser.user.editorMode
            if self.configParser.user.has_option('editorVersion'):
                self.editorVersion = self.configParser.user.editorVersion
            if self.configParser.user.has_option('docType'):
                self.docType = self.configParser.user.docType
                common.setExportDocType(self.configParser.user.docType)
            if self.configParser.user.has_option('defaultStyle'):
                self.defaultStyle = self.configParser.user.defaultStyle
            if self.configParser.user.has_option('styleSecureMode'):
                self.styleSecureMode = self.configParser.user.styleSecureMode
            if self.configParser.user.has_option('internalAnchors'):
                self.internalAnchors = self.configParser.user.internalAnchors
            if self.configParser.user.has_option('lastDir'):
                self.lastDir = self.configParser.user.lastDir
            if self.configParser.user.has_option('showPreferencesOnStart'):
                self.showPreferencesOnStart = self.configParser.user.showPreferencesOnStart
            if self.configParser.user.has_option('showIdevicesGrouped'):
                self.showIdevicesGrouped = self.configParser.user.showIdevicesGrouped
            if self.configParser.user.has_option('locale'):
                self.locale = self.configParser.user.locale
            if self.configParser.user.has_option('defaultLicense'):
                self.defaultLicense = self.configParser.user.defaultLicense

    def onWrite(self, configParser):
        """
        Called just before the config file is written.
        We use it to fill out any settings that are stored here and
        not in the config parser itself
        """
        # Recent projects
        self.configParser.delete('recent_projects')
        recentProjectsSection = self.configParser.addSection('recent_projects')
        for num, path in enumerate(self.recentProjects):
            recentProjectsSection[str(num)] = path

    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir/'exe.log', 'a',
                                       500000, 10)
            hdlr.doRollover()
        except OSError:
            # ignore the error we get if the log file is logged
            hdlr = logging.FileHandler(self.configDir/'exe.log')

        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log    = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)

        loggingLevels = {"DEBUG"    : logging.DEBUG,
                         "INFO"     : logging.INFO,
                         "WARNING"  : logging.WARNING,
                         "ERROR"    : logging.ERROR,
                         "CRITICAL" : logging.CRITICAL}

        if self.configParser.has_section('logging'):
            for logger, level in self.configParser._sections["logging"].items():
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])
        if not G.application.portable:
            log.info("************** eXe logging started **************")
            log.info("version     = %s" % version.version)
            log.info("configPath  = %s" % self.configPath)
            log.info("exePath     = %s" % self.exePath)
            log.info("libPath     = %s" % Path(twisted.__path__[0]).splitpath()[0])
            log.info("browser     = %s" % self.browser)
            log.info("webDir      = %s" % self.webDir)
            log.info("jsDir       = %s" % self.jsDir)
            log.info("localeDir   = %s" % self.localeDir)
            log.info("port        = %d" % self.port)
            log.info("dataDir     = %s" % self.dataDir)
            log.info("configDir   = %s" % self.configDir)
            log.info("locale      = %s" % self.locale)
            log.info("internalAnchors = %s" % self.internalAnchors)
            log.info("License = %s" % self.defaultLicense)

    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        self.styleStore = StyleStore(self)
        listStyles = self.styleStore.getStyles()
        for style in listStyles:
            self.styles.append(style)
            # print style

    def copyStyles(self):
        bkstyle = self.webDir/'style'
        dststyle = self.stylesDir
        if os.path.exists(bkstyle):
            if os.path.exists(dststyle) and not os.listdir(self.stylesDir):
                shutil.rmtree(dststyle)
            shutil.copytree(bkstyle, dststyle)

    def updateStyles(self):
        bkstyle = self.webDir/'style'
        dststyle = self.stylesDir
        if os.stat(bkstyle).st_mtime - os.stat(dststyle).st_mtime > 1:
            for name in os.listdir(bkstyle):
                bksdirstyle = os.path.join(bkstyle, name)
                dstdirstyle = os.path.join(dststyle, name)
                if os.path.isdir(bksdirstyle):
                    if os.path.exists(dstdirstyle):
                        shutil.rmtree(dstdirstyle)
                    shutil.copytree(bksdirstyle, dstdirstyle)
                else:
                    shutil.copy(bksdirstyle, dstdirstyle)

    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install('exe', self.localeDir, True)
        for subDir in self.localeDir.dirs():
            if (subDir/'LC_MESSAGES'/'exe.mo').exists():
                self.locales[subDir.basename()] = \
                    gettext.translation('exe',
                                        self.localeDir,
                                        languages=[str(subDir.basename())])
        if self.locale not in self.locales:
            self.locale = 'en'
        log.debug("loading locale %s" % self.locale)
        self.locales[self.locale].install(unicode=True)
        __builtins__['c_'] = lambda s: self.locales[self.locale].ugettext(s) if s else s
    def render(self, request):
        if "sendWhat" in request.args:
            if request.args['sendWhat'][0] == 'dirs':
                #Because this might be absolute and mess up...
                
                
                path_dir_str = unquote(request.args['node'][0].decode('utf-8'))
                path_dir_str = self.get_dirpath_for_request(
                                                request, path_dir_str)
                pathdir = Path(path_dir_str)
                
                
                l = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for d in get_drives():
                        try:
                            if is_readable(Path(d)):
                                icon = None
                            else:
                                icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                            l.append({"realtext": d, "text": d, "id": d + '\\', "icon": icon})
                        except:
                            pass
                else:
                    for d in pathdir.dirs():
                        try:
                            if not d.name.startswith('.') or sys.platform[:3] == "win":
                                if not iswinlink(d.abspath()):
                                    if is_readable(d):
                                        icon = None
                                    else:
                                        icon = '../jsui/extjs/resources/themes/images/gray/grid/hmenu-lock.gif'
                                    l.append({"realtext": d.name, "text": getname(d), "id": self.abs_to_user_path(d.abspath(), request), "icon": icon})
                        except:
                            pass
            elif request.args['sendWhat'][0] == 'both':
                req_pathdir_str = unquote(request.args['dir'][0].decode('utf-8'))
                pathdir_str = self.get_dirpath_for_request(
                                               request, req_pathdir_str)
                pathdir = Path(pathdir_str)
                items = []
                if pathdir == '/' and sys.platform[:3] == "win":
                    for drive in get_drives():
                        d = Path(drive + '\\')
                        items.append({"name": drive, "realname": drive + '\\', "size": 0, "type": 'directory', "modified": 0,
                                      "is_readable": is_readable(d),
                                      "is_writable": is_writable(d)})
                else:
                    parent = pathdir.parent
                    if (parent == pathdir):
                        realname = '/'
                    else:
                        realname = self.abs_to_user_path(parent.abspath(), request)
                    items.append({"name": '.', "realname": self.abs_to_user_path(pathdir.abspath(), request), "size": pathdir.size, "type": "directory", "modified": int(pathdir.mtime),
                                  "is_readable": is_readable(pathdir),
                                  "is_writable": is_writable(pathdir)})
                    items.append({"name": '..', "realname": realname, "size": parent.size, "type": "directory", "modified": int(parent.mtime),
                                  "is_readable": is_readable(parent),
                                  "is_writable": is_writable(parent)})
                    try:
                        for d in pathdir.listdir():
                            try:
                                if not d.name.startswith('.') or sys.platform[:3] == "win":
                                    if not iswinlink(d.abspath()):
                                        if d.isdir():
                                            pathtype = "directory"
                                        elif d.isfile():
                                            if is_readable(d):
                                                pathtype = repr(mimetypes.guess_type(d.name, False)[0])
                                            else:
                                                pathtype = "file"
                                        elif d.islink():
                                            pathtype = "link"
                                        else:
                                            pathtype = "None"
                                        items.append({"name": getname(d), "realname": self.abs_to_user_path(d.abspath(), request), "size": d.size, "type": pathtype, "modified": int(d.mtime),
                                          "is_readable": is_readable(d),
                                          "is_writable": is_writable(d)})
                            except:
                                pass
                        #this was before just pathdir - check this
                        if G.application.config.appMode != Config.MODE_WEBAPP:
                            G.application.config.lastDir = pathdir
                        else:
                            self.session.webservice_config.lastDir = req_pathdir_str
                    except:
                        pass
                l = {"totalCount": len(items), 'results': len(items), 'items': items}
            return json.dumps(l).encode('utf-8')
        elif "query" in request.args:
            query = request.args['query'][0]
            path_dir_str = unquote(request.args['dir'][0].decode('utf-8'))
            path_dir_str = self.get_dirpath_for_request(request,path_dir_str)
            pathdir = Path(path_dir_str)
            items = []
            if pathdir == '/' and sys.platform[:3] == "win":
                for d in get_drives():
                    items.append({"name": d, "realname": d + '\\', "size": 0, "type": 'directory', "modified": 0})
            else:
                parent = pathdir.parent
                if (parent == pathdir):
                    realname = '/'
                else:
                    realname = self.abs_to_user_path(parent.abspath(), request)
                for d in pathdir.listdir():
                    try:
                        if d.isdir():
                            pathtype = "directory"
                        elif d.isfile():
                            if is_readable(d):
                                pathtype = repr(mimetypes.guess_type(d.name, False)[0])
                            else:
                                pathtype = "file"
                        elif d.islink():
                            pathtype = "link"
                        else:
                            pathtype = "None"
                        if d.name.startswith(query):
                            items.append({"name": getname(d), "realname": self.abs_to_user_path(d.abspath(), request), "size": d.size, "type": pathtype, "modified": int(d.mtime),
                                          "is_readable": is_readable(d),
                                          "is_writable": is_writable(d)})
                    except:
                        pass

            l = {"totalCount": len(items), 'results': len(items), 'items': items}
            return json.dumps(l).encode('utf-8')
        elif "uploadfileaction" in request.args:
            filename = request.args["upload_file_name"][0]
            current_dir = request.args["upload_current_dir"][0]
            save_path = os.path.join(current_dir, filename)
            file_path =  self.get_dirpath_for_request(
                                                request, save_path)
            file = open(file_path, "wb")
            file.write(request.args['upload_file'][0])
            file.close()
            
            result = {"success" : True}
            return json.dumps(result).encode('utf-8')
        return ""
Beispiel #21
0
class Config:
    """
    The Config class contains the configuration information for eXe.
    """

    # Class attributes
    optionNames = {
        'system': ('webDir', 'xulDir', 'port', 'dataDir', 
                   'configDir', 'localeDir', 'browserPath', ),
        'user': ('locale', 'latexpath'),
    }

    def __init__(self):
        """
        Initialise
        """
        self.configPath = None
        self.configParser = ConfigParser(self.onWrite)
        # Set default values
        # exePath is the whole path and filename of the exe executable
        self.exePath     = Path(sys.argv[0]).abspath()
        # webDir is the parent directory for styles,scripts and templates
        self.webDir      = self.exePath.dirname()
        # xulDir is the parent directory for styles,scripts and templates
        self.xulDir      = self.exePath.dirname()
        # localeDir is the base directory where all the locales are stored
        self.localeDir   = self.exePath.dirname()/"locale"
        # port is the port the exe webserver will listen on 
        # (previous default, which earlier users might still use, was 8081)
        self.port        = 51235
        # dataDir is the default directory that is shown to the user
        # to save packages and exports in
        self.dataDir     = Path(".")
        # configDir is the dir for storing user profiles
        # and user made idevices and the config file
        self.configDir   = Path(".")
        # browserPath is the entire pathname to firefox
        self.browserPath = Path("firefox")
        # locale is the language of the user
        self.locale = chooseDefaultLocale(self.localeDir)
        # internalAnchors indicate which exe_tmp_anchor tags to generate for each tinyMCE field
        # available values = "enable_all", "disable_autotop", or "disable_all"
        self.internalAnchors = "enable_all"
        # styles is the list of style names available for loading
        self.styles      = []
        # The documents that we've recently looked at
        self.recentProjects = []
        # canonical (English) names of iDevices not to show in the iDevice pane
        self.hiddeniDevices = []
        # likewise, a canonical (English) names of iDevices not to show in the
        # iDevice pane but, contrary to the hiddens, these are ones that the 
        # configuration can specify to turn ON:
        self.deprecatediDevices = [ "flash with text", "flash movie", "mp3", \
                                    "attachment"]
        # by default, only allow embedding of media types for which a 
        # browser plugin is found:
        self.assumeMediaPlugins = False;
        # Let our children override our defaults depending
        # on the OS that we're running on
        self._overrideDefaultVals()
        # Try to make the defaults a little intelligent
        # Under devel trees, webui is the default webdir
        self.webDir = Path(self.webDir)
        if not (self.webDir/'scripts').isdir() \
           and (self.webDir/'webui').isdir():
            self.webDir /= 'webui'
        # Under devel trees, xului is the default xuldir
        self.xulDir = Path(self.xulDir)
        if not (self.xulDir/'scripts').isdir() \
           and (self.xulDir/'xului').isdir():
            self.xulDir /= 'xului'
        # Latex distribution path if environment wasn't set properly
        self.latexpath = ""
        # Find where the config file will be saved
        self.__setConfigPath()
        # Fill in any undefined config options with our defaults
        self._writeDefaultConfigFile()
        # Now we are ready to serve the application
        self.loadSettings()
        self.setupLogging()
        self.loadStyles()
        self.loadLocales()


    def _overrideDefaultVals(self):
        """
        Override this to override the
        default config values
        """

    def _getConfigPathOptions(self):
        """
        Override this to give a list of
        possible config filenames
        in order of preference
        """
        return ['exe.conf']


    def _writeDefaultConfigFile(self):
        """
        [Over]writes 'self.configPath' with a default config file 
        (auto write is on so we don't need to write the file at the end)
        """
        for sectionName, optionNames in self.optionNames.items():
            for optionName in optionNames:
                defaultVal = getattr(self, optionName)
                self.configParser.setdefault(sectionName, 
                                             optionName, 
                                             defaultVal)
        # Logging can't really be changed from inside the program at the moment...
        self.configParser.setdefault('logging', 'root', 'INFO')


    def _getWinFolder(self, code):
        """
        Gets one of the windows famous directorys
        depending on 'code'
        Possible values can be found at:
        http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp#CSIDL_WINDOWS
        """
        from ctypes import WinDLL, create_unicode_buffer
        dll = WinDLL('shell32')
        # The '5' and the '0' from the below call come from
        # google: "ShellSpecialConstants site:msdn.microsoft.com"
        result = create_unicode_buffer(260)
        resource = dll.SHGetFolderPathW(None, code, None, 0, result)
        if resource != 0: 
            return Path('')
        else: 
            return Path(result.value)

        
    def __setConfigPath(self):
        """
        sets self.configPath to the filename of the config file that we'll
        use.
        In descendant classes set self.configFileOptions to a list
        of directories where the configDir should be in order of preference.
        If no config files can be found in these dirs, it will
        force creation of the config file in the top dir
        """
        # If there's an EXECONF environment variable, use it
        self.configPath = None
        configFileOptions = map(Path, self._getConfigPathOptions())
        if "EXECONF" in os.environ:
            envconf = Path(os.environ["EXECONF"])
            if envconf.isfile():
                self.configPath = os.environ["EXECONF"]
        # Otherwise find the most appropriate existing file
        if self.configPath is None:
            for confPath in configFileOptions:
                if confPath.isfile():
                    self.configPath = confPath
                    break
            else:
                # If no config files exist, create and use the
                # first one on the list
                self.configPath = configFileOptions[0]
                folder = self.configPath.abspath().dirname()
                if not folder.exists():
                    folder.makedirs()
                self.configPath.touch()
        # Now make our configParser
        self.configParser.read(self.configPath)
        self.configParser.autoWrite = True


    def upgradeFile(self):
        """
        Called before loading the config file,
        removes or upgrades any old settings.
        """
        if self.configParser.has_section('system'):
            system = self.configParser.system
            if system.has_option('appDataDir'):
                # Older config files had configDir stored as appDataDir
                self.configDir = Path(system.appDataDir)
                # We'll just upgrade their config file for them for now...
                system.configDir = self.configDir
                del system.appDataDir
            if system.has_option('greDir'):
                # No longer used, system should automatically support
                del system.greDir


    def loadSettings(self):
        """
        Loads the settings from the exe.conf file.
        Overrides the defaults set in __init__
        """
        # Set up the parser so that if a certain value is not in the config
        # file, it will use the value from our default values
        def defVal(dummy, option):
            """If something is not in the config file, just use the default in
            'self'"""
            return getattr(self, option)
        self.configParser.defaultValue = defVal
        self.upgradeFile()
        # System Section
        if self.configParser.has_section('system'):
            system = self.configParser.system
            self.webDir         = Path(system.webDir)
            self.xulDir         = Path(system.xulDir)
            self.localeDir      = Path(system.localeDir)
            self.port           = int(system.port)
            self.browserPath    = Path(system.browserPath)
            self.dataDir        = Path(system.dataDir)
            self.configDir      = Path(system.configDir)
            
            self.assumeMediaPlugins = False;
            if self.configParser.has_option('system', \
                    'assumeMediaPlugins'):
               value = system.assumeMediaPlugins.strip().lower()
               if value == "1" or value == "yes" or value == "true" or \
                   value == "on":
                       self.assumeMediaPlugins = True;

        # If the dataDir points to some other dir, fix it
        if not self.dataDir.isdir():
            self.dataDir = tempfile.gettempdir()
        # make the webDir absolute, to hide path joins of relative paths
        self.webDir = self.webDir.expand().abspath()
        # If the configDir doesn't exist (as it may be a default setting with a
        # new installation) create it
        if not self.configDir.exists():
            self.configDir.mkdir()
                
        # Get the list of recently opened projects
        self.recentProjects = []
        if self.configParser.has_section('recent_projects'):
            recentProjectsSection = self.configParser.recent_projects
            for key, path in recentProjectsSection.items():
                self.recentProjects.append(path)
                
        # Load the list of "hidden" iDevices
        self.hiddeniDevices = []
        if self.configParser.has_section('idevices'):
            idevicesSection = self.configParser.idevices
            for key,value in idevicesSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "0" or value == "no" or value == "false" or \
                        value == "off":
                    self.hiddeniDevices.append(key.lower())

        #self.deprecatediDevices = [ "flash with text", "flash movie", ...]
        # and UN-Load from the list of "deprecated" iDevices
        if self.configParser.has_section('deprecated'):
            deprecatedSection = self.configParser.deprecated
            for key,value in deprecatedSection.items():
                # emulate standard library's getboolean()
                value = value.strip().lower()
                if value == "1" or value == "yes" or value == "true" or \
                        value == "on":
                    if key.lower() in self.deprecatediDevices:
                        self.deprecatediDevices.remove(key.lower())

        # Load the "user" section
        if self.configParser.has_section('user'):
            if self.configParser.user.has_option('internalAnchors'):
                self.internalAnchors = self.configParser.user.internalAnchors
            if self.configParser.user.has_option('locale'):
                self.locale = self.configParser.user.locale
                return
        self.locale = chooseDefaultLocale(self.localeDir)

    def onWrite(self, configParser):
        """
        Called just before the config file is written.
        We use it to fill out any settings that are stored here and 
        not in the config parser itself
        """
        # Recent projects
        self.configParser.delete('recent_projects')
        recentProjectsSection = self.configParser.addSection('recent_projects')
        for num, path in enumerate(self.recentProjects):
            recentProjectsSection[str(num)] = path

    def setupLogging(self):
        """
        setup logging file
        """
        try:
            hdlr = RotatingFileHandler(self.configDir/'exe.log', 'a', 
                                       500000, 10)
            hdlr.doRollover()
        except OSError:
            # ignore the error we get if the log file is logged
            hdlr = logging.FileHandler(self.configDir/'exe.log')

        format = "%(asctime)s %(name)s %(levelname)s %(message)s"
        log    = logging.getLogger()
        hdlr.setFormatter(logging.Formatter(format))
        log.addHandler(hdlr)

        loggingLevels = {"DEBUG"    : logging.DEBUG,
                         "INFO"     : logging.INFO,
                         "WARNING"  : logging.WARNING,
                         "ERROR"    : logging.ERROR,
                         "CRITICAL" : logging.CRITICAL }

    
        if self.configParser.has_section('logging'):
            for logger, level in self.configParser._sections["logging"].items():
                if logger == "root":
                    logging.getLogger().setLevel(loggingLevels[level])
                else:
                    logging.getLogger(logger).setLevel(loggingLevels[level])

        log.info("************** eXe logging started **************")
        log.info("configPath  = %s" % self.configPath)
        log.info("exePath     = %s" % self.exePath)
        log.info("browserPath = %s" % self.browserPath)
        log.info("webDir      = %s" % self.webDir)
        log.info("xulDir      = %s" % self.xulDir)
        log.info("localeDir   = %s" % self.localeDir)
        log.info("port        = %d" % self.port)
        log.info("dataDir     = %s" % self.dataDir)
        log.info("configDir   = %s" % self.configDir)
        log.info("locale      = %s" % self.locale)
        log.info("internalAnchors = %s" % self.internalAnchors)
                    

    def loadStyles(self):
        """
        Scans the eXe style directory and builds a list of styles
        """
        log = logging.getLogger()
        self.styles = [] 
        styleDir    = self.webDir/"style"
        localeStyleDir = self.configDir / "style"
        if not os.path.exists(localeStyleDir):
            os.makedirs(localeStyleDir)

        log.debug("loadStyles from %s" % styleDir)

        for subDir in styleDir.dirs():
            if self.__checkStyle(subDir):
                styleName = subDir.basename()
                log.debug(" adding style to style/%s" % styleName)
                self.styles.append(styleName)
        # adding style from config to style/locale
        for subDir in localeStyleDir.dirs():
            if self.__checkStyle(subDir):
                styleName = "locale/" + subDir.basename()
                log.debug(" adding locale style to style/%s" % styleName)
                self.styles.append(styleName)

    def __checkStyle(self, style):
        '''Checks if it's valid style'''
        styleSheet = style / 'content.css'
        return styleSheet.exists()


    def loadLocales(self):
        """
        Scans the eXe locale directory and builds a list of locales
        """
        log = logging.getLogger()
        log.debug("loadLocales")
        gettext.install('exe', self.localeDir, True)
        self.locales = {}
        for subDir in self.localeDir.dirs():
            if (subDir/'LC_MESSAGES'/'exe.mo').exists():
                self.locales[subDir.basename()] = \
                    gettext.translation('exe', 
                                        self.localeDir, 
                                        languages=[str(subDir.basename())])
                if subDir.basename() == self.locale:
                    locale = subDir.basename()
                    log.debug(" loading locale %s" % locale)
                    self.locales[locale].install(unicode=True)
Beispiel #22
0
    def load(filename, newLoad=True, destinationPackage=None, fromxml=None):
        """
        Load package from disk, returns a package.
        """
        if not zipfile.is_zipfile(filename):
            return None

        zippedFile = zipfile.ZipFile(filename, "r")

        xml = None
        
        try:
            xml = zippedFile.read(u"contentv2.xml")
        except:
            pass
        
        if not xml:
            try:
                # Get the jellied package data
                toDecode   = zippedFile.read(u"content.data")
            except KeyError:
                log.info("no content.data, trying Common Cartridge/Content Package")
                newPackage = loadCC(zippedFile, filename)
                newPackage.tempFile = False
                newPackage.isChanged = False
                newPackage.filename = Path(filename)
    
                return newPackage
            
        # Need to add a TempDirPath because it is a nonpersistant member
        resourceDir = TempDirPath()

        # Extract resource files from package to temporary directory
        for fn in zippedFile.namelist():
            if unicode(fn, 'utf8') not in [u"content.data", u"content.xml", u"contentv2.xml", u"content.xsd" ]:
                #JR: Hacemos las comprobaciones necesarias por si hay directorios
                if ("/" in fn):
                    dir = fn[:fn.index("/")]
                    Dir = Path(resourceDir/dir)
                    if not Dir.exists():
                        Dir.mkdir()
                Fn = Path(resourceDir/fn)
                if not Fn.isdir():
                    outFile = open(resourceDir/fn, "wb")
                    outFile.write(zippedFile.read(fn))
                    outFile.flush()
                    outFile.close()

        try:
            validxml = False
            if fromxml:
                newPackage, validxml = decodeObjectFromXML(fromxml)
            elif xml:
                xmlinfo = zippedFile.getinfo(u"contentv2.xml")
                datainfo = zippedFile.getinfo(u"content.data")
                if xmlinfo.date_time >= datainfo.date_time:
                    newPackage, validxml = decodeObjectFromXML(xml)
            if not validxml:
                toDecode   = zippedFile.read(u"content.data")
                newPackage = decodeObjectRaw(toDecode)
            G.application.afterUpgradeHandlers = []
            newPackage.resourceDir = resourceDir
            G.application.afterUpgradeZombies2Delete = []
            if not validxml and (xml or fromxml or "content.xml" in zippedFile.namelist()):
                for key, res in newPackage.resources.items():
                    if len(res) < 1:
                        newPackage.resources.pop(key)
                    else:
                        res[0].testForAndDeleteZombieResources()

            if newLoad: 
                # provide newPackage to doUpgrade's versionUpgrade() to
                # correct old corrupt extracted packages by setting the
                # any corrupt package references to the new package:

                log.debug("load() about to doUpgrade newPackage \"" 
                        + newPackage._name + "\" " + repr(newPackage) )
                if hasattr(newPackage, 'resourceDir'):
                    log.debug("newPackage resourceDir = "
                            + newPackage.resourceDir)
                else:
                    # even though it was just set above? should not get here:
                    log.error("newPackage resourceDir has NO resourceDir!")

                doUpgrade(newPackage)

                # after doUpgrade, compare the largest found field ID:
                if G.application.maxFieldId >= Field.nextId:
                    Field.nextId = G.application.maxFieldId + 1

            else: 
                # and when merging, automatically set package references to
                # the destinationPackage, into which this is being merged:

                log.debug("load() about to merge doUpgrade newPackage \"" 
                        + newPackage._name + "\" " + repr(newPackage)
                        + " INTO destinationPackage \"" 
                        + destinationPackage._name + "\" " 
                        + repr(destinationPackage))
                
                log.debug("using their resourceDirs:")
                if hasattr(newPackage, 'resourceDir'):
                    log.debug("   newPackage resourceDir = " 
                            + newPackage.resourceDir)
                else:
                    log.error("newPackage has NO resourceDir!")
                if hasattr(destinationPackage, 'resourceDir'):
                    log.debug("   destinationPackage resourceDir = " 
                            + destinationPackage.resourceDir)
                else:
                    log.error("destinationPackage has NO resourceDir!")

                doUpgrade(destinationPackage, 
                        isMerge=True, preMergePackage=newPackage)

                # after doUpgrade, compare the largest found field ID:
                if G.application.maxFieldId >= Field.nextId:
                    Field.nextId = G.application.maxFieldId + 1

        except:
            import traceback
            traceback.print_exc()
            raise

        if newPackage.tempFile:
            # newPackage.filename was stored as it's original filename
            newPackage.tempFile = False
        else:
            # newPackage.filename is the name that the package was last loaded from
            # or saved to
            newPackage.filename = Path(filename)

        # Let idevices and nodes handle any resource upgrading they may need to
        # Note: Package afterUpgradeHandlers *must* be done after Resources'
        # and the package should be updated before everything else,
        # so, prioritize with a 3-pass, 3-level calling setup
        # in order of: 1) resources, 2) package, 3) anything other objects
        for handler_priority in range(3):
          for handler in G.application.afterUpgradeHandlers:

            if handler_priority == 0 and \
            repr(handler.im_class)=="<class 'exe.engine.resource.Resource'>":
                # level-0 handlers: Resource
                handler()

            elif handler_priority == 1 and \
            repr(handler.im_class)=="<class 'exe.engine.package.Package'>":
                # level-1 handlers: Package (requires resources first)
                if handler.im_self == newPackage: 
                    handler()
                else:
                    log.warn("Extra package object found, " \
                       + "ignoring its afterUpgradeHandler: " \
                       + repr(handler))

            elif handler_priority == 2 and \
            repr(handler.im_class)!="<class 'exe.engine.resource.Resource'>" \
            and \
            repr(handler.im_class)!="<class 'exe.engine.package.Package'>":
                # level-2 handlers: all others
                handler()

        G.application.afterUpgradeHandlers = []

        num_zombies = len(G.application.afterUpgradeZombies2Delete)
        for i in range(num_zombies-1, -1, -1):
            zombie = G.application.afterUpgradeZombies2Delete[i]
            # now, the zombie list can contain nodes OR resources to delete.
            # if zombie is a node, then also pass in a pruning parameter..
            zombie_is_node = False
            if isinstance(zombie, Node):
                zombie_is_node = True

            if zombie_is_node: 
                zombie.delete(pruningZombies=True) 
            else:
                zombie.delete() 
            del zombie
        G.application.afterUpgradeZombies2Delete = []

        newPackage.updateRecentDocuments(newPackage.filename)
        newPackage.isChanged = False
        return newPackage