Beispiel #1
1
def main():
    if len(sys.argv) < 2:
        print 'Usage: %s [version] [--install] [--local|username password]' % sys.argv[0]
        print 'Where [version] is the branch you want to checkout'
        print 'and username and password are for your eduforge account'
        print 'Eg. %s 0.7 --local' % sys.argv[0]
    else:
        version = sys.argv[1]
        branch = 'http://exe.cfdl.auckland.ac.nz/svn/exe/branches/%s' % version
        origDir = Path(sys.argv[0]).abspath().dirname()
        tmp = TempDirPath()
        os.chdir(tmp)
        os.system('svn export %s exe' % branch)
        (origDir/'../../exe/webui/firefox').copytree(tmp/'exe/exe/webui/firefox')
        os.chdir(tmp/'exe')
        tarball = Path('../exe-%s-source.tgz' % version).abspath()
        os.system('tar czf %s *' % tarball)
        os.chdir(tmp)
        if '--local' not in sys.argv:
            try:
                from paramiko import Transport
            except ImportError:
                print 'To upload you need to install paramiko python library from:'
                print 'http://www.lag.net/paramiko'
                sys.exit(2)
            from socket import socket, gethostbyname
            s = socket()
            s.connect((gethostbyname('shell.eduforge.org'), 22))
            t = Transport(s)
            t.connect()
            t.auth_password(sys.argv[-2], sys.argv[-1])
            f = t.open_sftp_client()
            f.chdir('/home/pub/exe')
            f.put(tarball.encode('utf8'), tarball.basename().encode('utf8'))
        if os.getuid() == 0:
            tarball.copyfile('/usr/portage/distfiles/' + tarball.basename())
        os.chdir(tmp/'exe/installs/gentoo')
        newEbuildFilename = Path('exe-%s.ebuild' % version).abspath()
        if not newEbuildFilename.exists():
            Path('exe-0.7.ebuild').copy(newEbuildFilename)
        if os.getuid() == 0:
            ebuildDir = Path('/usr/local/portage/dev-python/exe')
            if ebuildDir.exists():
                ebuildDir.rmtree()
            ebuildDir.makedirs()
            os.chdir(ebuildDir)
            newEbuildFilename.copy(ebuildDir)
            filesDir = ebuildDir/'files'
            filesDir.makedirs()
            Path(tmp/'exe/installs/gentoo/all-config.patch').copy(filesDir)
            if '--local' not in sys.argv:
                oldTarball = Path('/usr/portage/distfiles/')/tarball.basename()
                if oldTarball.exists():
                    oldTarball.remove()
                os.environ['GENTOO_MIRRORS']=''
                os.system('ebuild %s fetch' % newEbuildFilename.basename())
            os.system('ebuild %s manifest' % newEbuildFilename.basename())
            os.system('ebuild %s digest' % newEbuildFilename.basename())
            if '--install' in sys.argv:
                os.system('ebuild %s install' % newEbuildFilename.basename())
Beispiel #2
0
    def renderEdit(self, style):
        """
        Returns an XHTML string with the form element for editing this block
        """
        html = u'<div><div class="block">'
        html += common.textInput("title" + self.id, self.idevice.title)
        html += common.hiddenField("iconiDevice" + self.id, self.idevice.icon)
        html += u'<a class="js-show-icon-panel-button" href="javascript:showMessageBox(\'iconpanel\');">%s</a>' % _(
            'Select an icon')

        # Get icon source (if it exists)
        icon = self.idevice.icon
        icon_exists = False
        if icon != '':
            idevice_icon = Path(G.application.config.stylesDir / style /
                                'icon_' + self.idevice.icon + '.gif')
            if idevice_icon.exists():
                icon_exists = True
            else:
                idevice_icon = Path(G.application.config.stylesDir / style /
                                    "icon_" + self.idevice.icon + ".png")
                if idevice_icon.exists():
                    icon_exists = True

        # Icon HTML element
        html += u'<img class="js-idevide-icon-preview" name="iconiDevice%s" id="iconiDevice"' % (
            self.id)
        if icon_exists:
            html += u' src="/style/%s/icon_%s%s"' % (style, icon,
                                                     idevice_icon.ext)
        else:
            html += u' src="/images/empty.gif"'
        html += u'/>'

        # Delete button
        html += u'<a href="javascript:deleteIcon(%s);" id="deleteIcon%s" class="deleteIcon" title="%s"' % (
            self.id, self.id, _('Delete'))
        # If the icon doesn't exists
        if not icon_exists:
            html += u' style="display: none;"'
        html += u'>'
        html += u'<img class="js-delete-icon" alt="%s" src="%s"/>' % (
            _('Delete'), '/images/stock-delete.png')
        html += u'</a>'

        html += u'<div class="js-icon-panel-container">'
        html += u'<div id="iconpaneltitle">%s</div>' % _("Icons")
        html += u'<div id="iconpanelcontent">'
        html += self.__renderIcons(style)
        html += u'</div>'
        html += u'</div>'
        html += u"</div>"

        for element in self.elements:
            html += element.renderEdit() + u'<br />'

        html += self.renderEditButtons()
        html += u"</div>"

        return html
Beispiel #3
0
    def getResourcesList(self, editMode=False, ordered=True, appendPath=True):
        """ Get a list of the iDevice resources """
        resources = list()

        # Check export resources
        export_resources_path = Path(self.get_jsidevice_dir()) / 'export'
        if export_resources_path.exists():
            for res in os.listdir(export_resources_path):
                if appendPath:
                    resources.append(
                        str(
                            Path(self.get_jsidevice_dir()).basename() +
                            '/export/' + res))
                else:
                    resources.append(str(res))

        # Check edition resources
        edition_resources_path = Path(self.get_jsidevice_dir()) / 'edition'
        if (editMode) and edition_resources_path.exists():
            for res in os.listdir(edition_resources_path):
                if appendPath:
                    resources.append(
                        str(
                            Path(self.get_jsidevice_dir()).basename() +
                            '/edition/' + res))
                else:
                    resources.append(str(res))

        # Order the list
        if (ordered):
            resources.sort(key=lambda x: x.split('/')[-1])

        return resources
Beispiel #4
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 #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 _checkValid(self):
     config = Path(self._iDeviceDir) / 'config.xml'
     edition = Path(self._iDeviceDir) / 'edition'
     export = Path(self._iDeviceDir) / 'export'
     if config.exists() and edition.exists() and export.exists():
         self._valid = True
     else:
         self._valid = False
Beispiel #7
0
    def _checkValid(self):
        config = Path(self.get_jsidevice_dir()) / 'config.xml'
        edition = Path(self.get_jsidevice_dir()) / 'edition'

        if config.exists() and edition.exists():
            self._valid = True
        else:
            self._valid = False
Beispiel #8
0
    def renderEdit(self, style):
        """
        Returns an XHTML string with the form element for editing this block
        """
        html = u'<div>'
        html += '<span class="js-idevice-title-label">'
        html += '<label for="title'+self.id+'">'+_('Title')+':</label> '
        html += common.elementInstruc(_('The title and the icon are not required. If you leave them empty the iDevice will have no emphasis.'))
        html += '</span>'
        html += common.hiddenField("iconiDevice" + self.id, self.idevice.icon)
        html += u'<a class="js-show-icon-panel-button" href="javascript:showMessageBox(\'iconpanel\');" title="%s"><img src="/images/stock-insert-image.png" alt="%s" width="16" height="16" /></a>' % (_('Select an icon'),_('Choose an Image'))        
        
        # Get icon source (if it exists)
        icon = self.idevice.icon
        icon_exists = False
        if icon != '':
            idevice_icon = Path(G.application.config.stylesDir / style / 'icon_' + self.idevice.icon + '.gif')
            if idevice_icon.exists():
                icon_exists = True
            else:
                idevice_icon = Path(G.application.config.stylesDir/style/"icon_" + self.idevice.icon + ".png")
                if idevice_icon.exists():
                    icon_exists = True

        # Icon HTML element
        html += u'<img class="js-idevide-icon-preview" name="iconiDevice%s" id="iconiDevice"' % (self.id)
        if icon_exists:
            html += u' src="/style/%s/icon_%s%s"' % (style, icon, idevice_icon.ext)
        else:
            html += u' src="/images/empty.gif"'
        html += u'/>'

        # Delete button
        html += u'<a href="javascript:deleteIcon(%s);" id="deleteIcon%s" class="deleteIcon" title="%s"' % (self.id, self.id, _('Delete'))
        # If the icon doesn't exists
        if not icon_exists:
            html += u' style="display: none;"'
        html += u'>'
        html += u'<img class="js-delete-icon" alt="%s" src="%s"/>' % (_('Delete'), '/images/stock-delete.png')
        html += u'</a>'
        
        html += common.textInput("title" + self.id, self.idevice.title)

        html += u'<div class="js-icon-panel-container">'
        html += u'<div id="iconpaneltitle">%s</div>' % _("Icons")
        html += u'<div id="iconpanelcontent">'
        html += self.__renderIcons(style)
        html += u'</div>'
        
        html += u"</div>"

        for element in self.elements:
            html += element.renderEdit()

        html += self.renderEditButtons()
        html += u"</div>"

        return html
Beispiel #9
0
    def __renderIcons(self, style):
        """
        Return xhtml string for dispay all icons
        """
        iconpath = Path(G.application.config.stylesDir / style)
        iconfiles = iconpath.files("icon_*")
        html = '<div id="styleIcons"><div style="height:300px;overflow:auto">'

        for iconfile in iconfiles:
            iconname = iconfile.namebase
            icon = iconname.split("_", 1)[1]

            iconExists = False
            iconExtension = "gif"
            myIcon = Path(G.application.config.stylesDir / style / iconname +
                          ".gif")
            if myIcon.exists():
                iconExists = True
                iconValue = icon + '.' + iconExtension
                iconSrc = '/style/%s/icon_%s' % (style, iconValue)
            else:
                myIcon = Path(G.application.config.stylesDir / style /
                              iconname + ".png")
                if myIcon.exists():
                    iconExists = True
                    iconExtension = "png"
                    iconValue = icon + '.' + iconExtension
                    iconSrc = '/style/%s/icon_%s' % (style, iconValue)
                else:
                    myIcon = Path(G.application.config.stylesDir / style /
                                  iconname + ".svg")
                    if myIcon.exists():
                        iconExists = True
                        iconExtension = "svg"
                        iconValue = icon + '.' + iconExtension
                        iconSrc = '/style/%s/icon_%s' % (style, iconValue)

            if iconExists:
                filename = "/style/%s/%s.%s" % (style, iconname, iconExtension)
                html += u'<div style="float:left; text-align:center; width:105px;\n'
                html += u'margin-right:10px; margin-bottom:15px" > '
                html += u'<img src="%s" \n' % filename
                html += u"style=\"border:1px solid #E8E8E8;padding:5px;cursor:pointer;max-width:60px;height:auto\" onclick=\"window[0].selectStyleIcon('%s',this, '%s', '%s')\" title=\"%s.%s\">\n" % (
                    icon, iconSrc, self.id, icon, iconExtension)
                html += u'<br /><span style="display:inline-block;width:100px;overflow:hidden;text-overflow:ellipsis">%s.%s</span></div>\n' % (
                    icon, iconExtension)

        html += '</div></div>'

        return html
Beispiel #10
0
    def __renderIcons(self):
        """
        Return xhtml string for dispay all icons
        """
        iconpath = self.style.get_style_dir()
        iconfiles = iconpath.files("icon_*")
        html = '<div id="styleIcons"><div style="height:300px;overflow:auto">'

        for iconfile in iconfiles:
            iconname = iconfile.namebase
            icon = iconname.split("_", 1)[1]

            iconExists = False
            iconExtension = "gif"
            myIcon = Path(G.application.config.stylesDir /
                          self.style.get_dirname() / iconname + ".gif")
            if myIcon.exists():
                iconExists = True
            else:
                myIcon = Path(G.application.config.stylesDir /
                              self.style.get_dirname() / iconname + ".png")
                if myIcon.exists():
                    iconExists = True
                    iconExtension = "png"
                else:
                    myIcon = Path(G.application.config.stylesDir /
                                  self.style.get_dirname() / iconname + ".svg")
                    if myIcon.exists():
                        iconExists = True
                        iconExtension = "svg"

            if iconExists:
                filename = "/style/%s/%s.%s" % (self.style.get_dirname(),
                                                iconname, iconExtension)
                html += u'<div style="float:left; text-align:center; width:105px;\n'
                html += u'margin-right:10px; margin-bottom:15px" > '
                html += u'<img src="%s" \n' % filename
                # html += u' alt="%s" ' % _("Submit")
                # window[1] because we use Ext.MessageBox instead of libot_drag.js
                html += u"style=\"border:1px solid #E8E8E8;padding:5px;cursor:pointer;max-width:60px;max-height:60px;height:auto\" onclick=\"window[1].selectStyleIcon('%s',this)\" title=\"%s.%s\">\n" % (
                    icon, icon, iconExtension)
                # html += u"style=\"cursor:pointer\" onclick=\"window[1].submitLink('selectIcon','%s',1)\">\n" % icon
                html += u'<br /><span style="display:inline-block;width:100px;overflow:hidden;text-overflow:ellipsis">%s.%s</span></div>\n' % (
                    icon, iconExtension)

        html += '</div></div>'

        return html
Beispiel #11
0
def main():
    if len(sys.argv) < 2:
        print 'Usage: %s [version]' % sys.argv[0]
        print 'Where [version] is the branch you want to checkout'
        print 'Eg. %s 0.7' % sys.argv[0]
    else:
        version = sys.argv[1]
        branch = 'http://exe.cfdl.auckland.ac.nz/svn/exe/branches/%s' % version
        origDir = Path(sys.argv[0]).abspath().dirname()
        tmp = TempDirPath()
        os.chdir(tmp)
        os.system('svn export %s exe' % branch)
        (origDir/'../../exe/webui/firefox').copytree(tmp/'exe/exe/webui/firefox')
        os.chdir(tmp/'exe')
        tarball = Path('../exe-%s-source.tgz' % version).abspath()
        os.system('tar czf %s *' % tarball)
        os.chdir(tmp)
        if '--local' not in sys.argv:
            open('sftpbatch.tmp', 'w').write(
                'cd /home/pub/exe\n'
                'put %s\n' % tarball)
            os.system('sftp -b sftpbatch.tmp [email protected]')
        if os.getuid() == 0:
            tarball.copyfile('/usr/portage/distfiles/' + tarball.basename())
        os.chdir(tmp/'exe/installs/gentoo')
        newEbuildFilename = Path('exe-%s.ebuild' % version).abspath()
        if not newEbuildFilename.exists():
            Path('exe-0.7.ebuild').copy(newEbuildFilename)
        if os.getuid() == 0:
            ebuildDir = Path('/usr/local/portage/dev-python/exe')
            if ebuildDir.exists():
                ebuildDir.rmtree()
            ebuildDir.makedirs()
            os.chdir(ebuildDir)
            newEbuildFilename.copy(ebuildDir)
            filesDir = ebuildDir/'files'
            filesDir.makedirs()
            Path(tmp/'exe/installs/gentoo/all-config.patch').copy(filesDir)
            if '--local' not in sys.argv:
                oldTarball = Path('/usr/portage/distfiles/')/tarball.basename()
                if oldTarball.exists():
                    oldTarball.remove()
                os.environ['GENTOO_MIRRORS']=''
                os.system('ebuild %s fetch' % newEbuildFilename.basename())
            os.system('ebuild %s manifest' % newEbuildFilename.basename())
            os.system('ebuild %s digest' % newEbuildFilename.basename())
            if '--install' in sys.argv:
                os.system('ebuild %s install' % newEbuildFilename.basename())
    def doTest(self, ExporterClass):
        """Exports a package with meta data"""
        # Load our test package
        package = Package.load('testPackage.elp')
        # Do the export
        outFilename = Path('scormtest.zip')
        exporter = ExporterClass(self.app.config,
                                 '../exe/webui/style/default', 
                                 outFilename)
        exporter.export(package)
        # Check that it made a nice zip file
        assert outFilename.exists()
        # See if the manifest file was created
        zipped = ZipFile(outFilename)
        filenames = zipped.namelist()
        assert 'imsmanifest.xml' in filenames, filenames
        self._testManifest(zipped.read('imsmanifest.xml'))

        # Test that all the node's html files have been generated
        pagenodes  = Set([p.node for p in exporter.pages])
        othernodes = Set(self._getNodes([], package.root))
        assert pagenodes == othernodes

        for page in exporter.pages:
            self._testPage(page, zipped)

        # Clean up
        zipped.close()
Beispiel #13
0
def makePO(applicationDirectoryPath,  applicationDomain=None, verbose=1) :
    """Build the Portable Object Template file for the application.

    makePO builds the .pot file for the application stored inside 
    a specified directory by running xgettext for all application source 
    files.  It finds the name of all files by looking for a file called 'app.fil'. 
    If this file does not exists, makePo raises an IOError exception.
    By default the application domain (the application
    name) is the same as the directory name but it can be overridden by the 
    'applicationDomain' argument.

    makePO always creates a new file called messages.pot.  If it finds files 
    of the form app_xx.po where 'app' is the application name and 'xx' is one 
    of the ISO 639 two-letter language codes, makePO resynchronizes those 
    files with the latest extracted strings (now contained in messages.pot). 
    This process updates all line location number in the language-specific
    .po files and may also create new entries for translation (or comment out 
    some).  The .po file is not changed, instead a new file is created with 
    the .new extension appended to the name of the .po file.

    By default the function does not display what it is doing.  Set the 
    verbose argument to 1 to force it to print its commands.
    """
    if applicationDomain is None:
        applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
    else:
        applicationName = applicationDomain
    currentDir = os.getcwd()
    messages_pot = Path('exe/locale/messages.pot')
    # Use xgettext to make the base messages.pot (with header, etc.)
    if messages_pot.exists():
        messages_pot.remove()
    messages_pot.touch()
    cmd = 'xgettext -kx_ -s -j --no-wrap --output=exe/locale/messages.pot --from-code=utf8 exe/engine/package.py'
    if verbose: print cmd
    os.system(cmd)                                                
    if not os.path.exists('app.fil'):
        raise IOError(2,'No module file: app.fil')

    # Steps:                                  
    #  Use xgettext to parse all application modules
    #  The following switches are used:
    #  
    #   -s                          : sort output by string content (easier to use when we need to merge several .po files)
    #   --files-from=app.fil        : The list of files is taken from the file: app.fil
    #   --output=                   : specifies the name of the output file (using a .pot extension)
    cmd = 'xgettext -kx_ -s -j --no-wrap --output=exe/locale/messages.pot --from-code=utf8 %s'
    if verbose: print cmd
    for fn in open('app.fil'):
        print 'Extracting from', fn,
        os.system(cmd % fn[:-1])

    makeXulPO(applicationDirectoryPath, applicationDomain, verbose)

    # Merge new pot with .po files
    localeDirs = Path('exe/locale')
    for filename in localeDirs.walkfiles('*_*.po'):
        cmd = "msgmerge -U --no-wrap %s exe/locale/messages.pot" % filename
        if verbose: print cmd
        os.system(cmd)
 def handleExternalResources(self, html):
     html_content_lower = html.lower()
     start_index = 0
     start_index = self._findNextTagStart(html_content_lower, start_index, ['img'])
     while start_index != -1:
         res_src = self._getSrcForTag(html, start_index)
         if res_src is not None and res_src.startswith("http://"):
             new_file_basename = self.url2ascii(res_src)
             new_file_name = str(self.workingDir/new_file_basename)
             new_file_path = Path(self.workingDir/new_file_basename)
             if new_file_path.exists() is False: 
                 urllib.urlretrieve(res_src, new_file_name)
             
             old_length = len(html)
             html = html.replace(res_src, new_file_name)
             html_content_lower = html.lower()
             new_length = len(html)
             length_difference = old_length - new_length
             start_index += length_difference
             
             
         end_tag_index = html_content_lower.find(">", start_index);
         start_index = self._findNextTagStart(html_content_lower,end_tag_index , ['img'])
     
     return html
Beispiel #15
0
 def testUpgradeAppDir(self):
     """
     Tests that config files with
     'appDataDir' are upgraded to 'configDir'
     """
     # Write the old style config file
     configPath = Path(u'test.exe.conf')
     if configPath.exists():
         configPath.remove()
     oldParser = ConfigParser()
     system = oldParser.addSection('system')
     system.appDataDir = 'my old app data dir'
     oldParser.write(configPath)
     del system
     del oldParser
     # Make the config instance load it
     Config._getConfigPathOptions = lambda self: ['test.exe.conf']
     myconfig = Config()
     myconfig.loadSettings()
     # Check if it reads the old value into the new variable
     assert not hasattr(myconfig, 'appDataDir')
     self.assertEquals(myconfig.configPath, 'test.exe.conf')
     self.assertEquals(myconfig.configDir, 'my old app data dir')
     # Check if it has upgraded the file and added in some nice default values
     newParser = ConfigParser()
     newParser.read(configPath)
     self.assertEquals(newParser.system.configDir, 'my old app data dir')
 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 #17
0
def makeXulPO(applicationDirectoryPath, applicationDomain=None, verbose=0):
    """Searches through xul files and appends to messages.pot"""
    if verbose:
        print "Importing xul templates..."
    path = Path(applicationDirectoryPath)
    messages = pot2dict('exe/locale/messages.pot')
    messageCommentTemplate = '\n#: %s:%s\nmsgid "'
    seq = len(messages)
    skipPaths = (applicationDirectoryPath / 'exe/webui/firefox', )
    for fn in path.walkfiles():
        if fn.ext.lower() == '.xul':
            for skipPath in skipPaths:
                if fn.startswith(skipPath):
                    print 'IGNORING', fn
                    break
            else:
                if verbose:
                    print "template: ", fn
                reader = Sax2.Reader()
                doc = reader.fromStream(file(fn, 'rb'))
                xul2dict(doc, messages, seq, fn.relpath())
    pot = Path('exe/locale/messages.pot')
    if pot.exists():
        pot.remove()
    pot.touch()
    dict2pot(messages, 'exe/locale/messages.pot')
    def doTest(self, ExporterClass):
        """Exports a package with meta data"""
        # Load our test package
        package = Package.load('testPackage.elp')
        # Do the export
        outFilename = Path('scormtest.zip')
        exporter = ExporterClass(self.app.config,
                                 '../exe/webui/style/default', 
                                 outFilename)
        exporter.export(package)
        # Check that it made a nice zip file
        assert outFilename.exists()
        # See if the manifest file was created
        zipped = ZipFile(outFilename)
        filenames = zipped.namelist()
        assert 'imsmanifest.xml' in filenames, filenames
        self._testManifest(zipped.read('imsmanifest.xml'))

        # Test that all the node's html files have been generated
        pagenodes  = Set([p.node for p in exporter.pages])
        othernodes = Set(self._getNodes([], package.root))
        assert pagenodes == othernodes

        for page in exporter.pages:
            self._testPage(page, zipped)

        # Clean up
        zipped.close()
 def _setupConfigFile(self, configParser):
     """
     Override this to setup any customised config
     settings
     """
     # Set up the system section
     system = configParser.addSection('system')
     system.exePath = 'exe/exe'
     system.exeDir = 'exe'
     system.webDir = 'exe/webui'
     system.localeDir = 'exe/locale'
     system.configDir = 'tmp'
     system.port = 8081
     # Make a temporary dir where we can save packages and exports etc
     tmpDir = Path('tmp')
     if not tmpDir.exists():
         tmpDir.mkdir()
     dataDir = tmpDir / 'data'
     if not dataDir.exists():
         dataDir.mkdir()
     system.dataDir = dataDir
     system.browserPath = 'not really used in tests so far'
     # Setup the logging section
     logging = configParser.addSection('logging')
     logging.root = 'DEBUG'
Beispiel #20
0
 def _setupConfigFile(self, configParser):
     """
     Override this to setup any customised config
     settings
     """
     # Set up the system section
     system = configParser.addSection('system')
     system.exePath = 'exe/exe'
     system.exeDir = 'exe'
     system.webDir = 'exe/webui'
     system.localeDir = 'exe/locale'
     system.configDir = 'tmp'
     system.port = 8081
     # Make a temporary dir where we can save packages and exports etc
     tmpDir = Path('tmp')
     if not tmpDir.exists():
         tmpDir.mkdir()
     dataDir = tmpDir / 'data'
     if not dataDir.exists():
         dataDir.mkdir()
     system.dataDir = dataDir
     system.browserPath = 'not really used in tests so far'
     # Setup the logging section
     logging = configParser.addSection('logging')
     logging.root = 'DEBUG'
Beispiel #21
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 #22
0
def launchBrowser(config, packageName):
    """
    Launch the configured webbrowser for this platform
    """
    url = u'%s/%s' % (G.application.exeAppUri, quote(packageName))
    log.info(u"url " + url)
    dfbrw=mywebbrowser.get()
    withdefaultbrowser=True
    if config.browser!=None:
        try:
            config.browser = mywebbrowser.get(config.browser)
            if not config.browser.open(url):
                log.error("Unable to open defined browser: " + config.browser.name)
                withdefaultbrowser = True
            else:
                withdefaultbrowser = False
        except:
            browser_path = Path(config.browser)
            if browser_path.exists():
                log.info(u"path browser " + browser_path.abspath())
                mywebbrowser.register("custom-browser" , None, mywebbrowser.BackgroundBrowser(browser_path.abspath()), -1)
                config.browser = mywebbrowser.get("custom-browser")
                if not config.browser.open(url):
                    log.error("Unable to open custom defined browser: " + browser_path.abspath())
                    withdefaultbrowser=True
                else:
                    withdefaultbrowser=False   
    if withdefaultbrowser:
        config.browser = dfbrw
        config.browser.open(url, new=0, autoraise=True)
    if hasattr(config.browser, "name"):
        log.info(u"Defined Browser: " + config.browser.name)
Beispiel #23
0
def makePO(applicationDirectoryPath, applicationDomain=None, verbose=1):
    """Build the Portable Object Template file for the application.

    makePO builds the .pot file for the application stored inside 
    a specified directory by running xgettext for all application source 
    files.  It finds the name of all files by looking for a file called 'app.fil'. 
    If this file does not exists, makePo raises an IOError exception.
    By default the application domain (the application
    name) is the same as the directory name but it can be overridden by the 
    'applicationDomain' argument.

    makePO always creates a new file called messages.pot.  If it finds files 
    of the form app_xx.po where 'app' is the application name and 'xx' is one 
    of the ISO 639 two-letter language codes, makePO resynchronizes those 
    files with the latest extracted strings (now contained in messages.pot). 
    This process updates all line location number in the language-specific
    .po files and may also create new entries for translation (or comment out 
    some).  The .po file is not changed, instead a new file is created with 
    the .new extension appended to the name of the .po file.

    By default the function does not display what it is doing.  Set the 
    verbose argument to 1 to force it to print its commands.
    """
    if applicationDomain is None:
        applicationName = fileBaseOf(applicationDirectoryPath, withPath=0)
    else:
        applicationName = applicationDomain
    currentDir = os.getcwd()
    messages_pot = Path('exe/locale/messages.pot')
    # Use xgettext to make the base messages.pot (with header, etc.)
    if messages_pot.exists():
        messages_pot.remove()
    messages_pot.touch()
    cmd = 'xgettext -kx_ -s -j --no-wrap --output=exe/locale/messages.pot --from-code=utf8 exe/engine/package.py'
    if verbose: print cmd
    os.system(cmd)
    if not os.path.exists('app.fil'):
        raise IOError(2, 'No module file: app.fil')

    # Steps:
    #  Use xgettext to parse all application modules
    #  The following switches are used:
    #
    #   -s                          : sort output by string content (easier to use when we need to merge several .po files)
    #   --files-from=app.fil        : The list of files is taken from the file: app.fil
    #   --output=                   : specifies the name of the output file (using a .pot extension)
    cmd = 'xgettext -kx_ -L Python -s -j --no-wrap --output=exe/locale/messages.pot --from-code=utf8 %s'
    if verbose: print cmd
    for fn in open('app.fil'):
        print 'Extracting from', fn,
        os.system(cmd % fn[:-1])

    makeXulPO(applicationDirectoryPath, applicationDomain, verbose)

    # Merge new pot with .po files
    localeDirs = Path('exe/locale')
    for filename in localeDirs.walkfiles('*_*.po'):
        cmd = "msgmerge -U --no-wrap -N %s exe/locale/messages.pot" % filename
        if verbose: print cmd
        os.system(cmd)
Beispiel #24
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
Beispiel #25
0
def makeXulPO(applicationDirectoryPath,  applicationDomain=None, verbose=0):
    """Searches through xul files and appends to messages.pot"""
    if verbose:
        print "Importing xul templates..."
    path = Path(applicationDirectoryPath)
    messages = pot2dict('exe/locale/messages.pot')
    messageCommentTemplate = '\n#: %s:%s\nmsgid "'
    seq = len(messages)
    skipPaths = (
          applicationDirectoryPath/'exe/webui/firefox',
        )
    for fn in path.walkfiles():
        if fn.ext.lower() == '.xul':
            for skipPath in skipPaths:
                if fn.startswith(skipPath):
                    print 'IGNORING', fn
                    break
            else:
                if verbose:
                    print "template: ", fn
                reader = Sax2.Reader()
                doc = reader.fromStream(file(fn, 'rb'))
                xul2dict(doc, messages, seq, fn.relpath())
    pot = Path('exe/locale/messages.pot') 
    if pot.exists(): 
        pot.remove() 
    pot.touch() 
    dict2pot(messages, 'exe/locale/messages.pot')
Beispiel #26
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 #27
0
 def handleExport(self, client, exportType, filename):
     """
     Called by js. 
     Exports the current package to one of the above formats
     'exportType' can be one of 'singlePage' 'webSite' 'zipFile'
                  'textFile' or 'scorm'
     'filename' is a file for scorm pages, and a directory for websites
     """ 
     webDir     = Path(self.config.webDir)
     stylesDir  = webDir.joinpath('style', self.package.style)
     exportDir  = Path(filename).dirname()
     if exportDir and not exportDir.exists():
         client.alert(_(u'Cannot access directory named ') +
                      unicode(exportDir) +
                      _(u'. Please use ASCII names.'))
         return
     if exportType == 'singlePage':
         self.exportSinglePage(client, filename, webDir, stylesDir)
     elif exportType == 'webSite':
         self.exportWebSite(client, filename, stylesDir)
     elif exportType == 'zipFile':
         self.exportWebZip(client, filename, stylesDir)
     elif exportType == 'textFile':
         self.exportText(client, filename)
     elif exportType == "scorm":
         self.exportScorm(client, filename, stylesDir, "scorm1.2")
     elif exportType == "scorm2004":
         self.exportScorm(client, filename, stylesDir, "scorm2004")
     else:
         self.exportIMS(client, filename, stylesDir)
Beispiel #28
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 #29
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
Beispiel #30
0
 def testUpgradeAppDir(self):
     """
     Tests that config files with
     'appDataDir' are upgraded to 'configDir'
     """
     # Write the old style config file
     configPath = Path(u'test.exe.conf')
     if configPath.exists():
         configPath.remove()
     oldParser = ConfigParser()
     system = oldParser.addSection('system')
     system.appDataDir = 'my old app data dir'
     oldParser.write(configPath)
     del system
     del oldParser
     # Make the config instance load it
     Config._getConfigPathOptions = lambda self: ['test.exe.conf']
     myconfig = Config()
     myconfig.loadSettings()
     # Check if it reads the old value into the new variable
     assert not hasattr(myconfig, 'appDataDir')
     self.assertEquals(myconfig.configPath, 'test.exe.conf')
     self.assertEquals(myconfig.configDir, 'my old app data dir')
     # Check if it has upgraded the file and added in some nice default values
     newParser = ConfigParser()
     newParser.read(configPath)
     self.assertEquals(newParser.system.configDir, 'my old app data dir')
 def render_POST(self, request):
     """
     function replaced by nevow_clientToServerEvent to avoid POST message
     """
     log.debug("render_POST " + repr(request.args))
     data = {}
     try:
         locale = request.args['locale'][0]
         self.config.locale = locale
         self.config.locales[locale].install(unicode=True)
         self.config.configParser.set('user', 'locale', locale)
         internalAnchors = request.args['internalAnchors'][0]
         self.config.internalAnchors = internalAnchors
         self.config.configParser.set('user', 'internalAnchors', internalAnchors)
         browser = request.args['browser'][0]
         if browser == "None":
             browser = None
         try:
             self.config.browser = mywebbrowser.get(browser)
         except Exception as e:
             browser_path = Path(browser)
             if browser_path.exists():
                 mywebbrowser.register('custom-browser' , None, mywebbrowser.BackgroundBrowser(browser_path.abspath()), -1)
                 self.config.browser = mywebbrowser.get('custom-browser')
             else:
                 raise e
         self.config.configParser.set('system', 'browser', browser)
         showWizardOnStart = request.args['showWizardOnStart'][0]
         self.config.showWizardOnStart = showWizardOnStart
         self.config.configParser.set('user', 'showWizardOnStart', showWizardOnStart)
     except Exception as e:
         log.exception(e)
         return json.dumps({'success': False, 'errorMessage': _("Failed to save preferences wizard")})
     return json.dumps({'success': True, 'data': data})
Beispiel #32
0
def makeMO(applicationDirectoryPath, targetDir=None, applicationDomain=None, verbose=0, forceEnglish=0):
    """Compile the Portable Object files into the Machine Object stored in the right location.
    makeMO converts all translated language-specific PO files located inside 
    the  application directory into the binary .MO files stored inside the 
    LC_MESSAGES sub-directory for the found locale files.
    makeMO searches for all files that have a name of the form 'app_xx.po' 
    inside the application directory specified by the first argument.  The 
    'app' is the application domain name (that can be specified by the 
    applicationDomain argument or is taken from the directory name). The 'xx' 
    corresponds to one of the ISO 639 two-letter language codes.
    makeMo stores the resulting files inside a sub-directory of `targetDir` 
    called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language 
    code.
    """
    if targetDir is None:
        targetDir = "exe/locale"
    if verbose:
        print "Target directory for .mo files is: %s" % targetDir
    targetDir = Path(targetDir)
    if applicationDomain is None:
        applicationName = fileBaseOf(applicationDirectoryPath, withPath=0)
    else:
        applicationName = applicationDomain
    currentDir = os.getcwd()
    os.chdir(applicationDirectoryPath)
    for filename in targetDir.glob("*_*.po"):
        langCode = filename.split("_", 1)[1].split(".", 1)[0]
        mo_targetDir = Path("%s/%s/LC_MESSAGES" % (targetDir, langCode))
        if not mo_targetDir.exists():
            mo_targetDir.makedirs()
        cmd = "msgfmt --output-file=%s.mo %s" % (mo_targetDir / applicationName, filename)
        if verbose:
            print cmd
        os.system(cmd)
    os.chdir(currentDir)
Beispiel #33
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 #34
0
    def render_POST(self, request):
        """
        function replaced by nevow_clientToServerEvent to avoid POST message
        """
        log.debug("render_POST " + repr(request.args))
        data = {}
        try:
            locale = request.args["locale"][0]
            self.config.locale = locale
            self.config.locales[locale].install(unicode=True)
            self.config.configParser.set("user", "locale", locale)

            internalAnchors = request.args["internalAnchors"][0]
            self.config.internalAnchors = internalAnchors
            self.config.configParser.set("user", "internalAnchors", internalAnchors)

            editormodesel = request.args["editorMode"][0]
            self.config.editorMode = editormodesel
            self.config.configParser.set("user", "editorMode", editormodesel)
            theme = request.args["theme"][0]
            self.config.theme = theme
            self.config.configParser.set("user", "theme", theme)

            doctypesel = request.args["docType"][0]
            self.config.docType = doctypesel
            self.config.configParser.set("user", "docType", doctypesel)

            googleApiClientID = request.args["googleApiClientID"][0]
            self.config.googleApiClientID = googleApiClientID
            self.config.configParser.set("user", "googleApiClientID", googleApiClientID)

            defaultLicense = request.args["defaultLicense"][0]
            self.config.defaultLicense = defaultLicense
            self.config.configParser.set("user", "defaultLicense", defaultLicense)

            browser = request.args["browser"][0]
            if browser == "None":
                browser = None
            try:
                self.config.browser = mywebbrowser.get(browser)
            except Exception as e:
                browser_path = Path(browser)
                if browser_path.exists():
                    mywebbrowser.register(
                        "custom-browser", None, mywebbrowser.BackgroundBrowser(browser_path.abspath()), -1
                    )
                    self.config.browser = mywebbrowser.get("custom-browser")
                else:
                    raise e
            self.config.configParser.set("system", "browser", browser)

            showPreferencesOnStart = request.args["showPreferencesOnStart"][0]
            self.config.showPreferencesOnStart = showPreferencesOnStart
            self.config.configParser.set("user", "showPreferencesOnStart", showPreferencesOnStart)
        except Exception as e:
            log.exception(e)
            return json.dumps({"success": False, "errorMessage": _("Failed to save preferences")})
        return json.dumps({"success": True, "data": data})
Beispiel #35
0
    def render_POST(self, request):
        """
        function replaced by nevow_clientToServerEvent to avoid POST message
        """
        log.debug("render_POST " + repr(request.args))
        data = {}
        try:
            locale = request.args['locale'][0]
            self.config.locale = locale
            self.config.locales[locale].install(unicode=True)
            self.config.configParser.set('user', 'locale', locale)

            internalAnchors = request.args['internalAnchors'][0]
            self.config.internalAnchors = internalAnchors
            self.config.configParser.set('user', 'internalAnchors',
                                         internalAnchors)

            editormodesel = request.args['editorMode'][0]
            self.config.editorMode = editormodesel
            self.config.configParser.set('user', 'editorMode', editormodesel)

            doctypesel = request.args['docType'][0]
            self.config.docType = doctypesel
            self.config.configParser.set('user', 'docType', doctypesel)

            defaultLicense = request.args['defaultLicense'][0]
            self.config.defaultLicense = defaultLicense
            self.config.configParser.set('user', 'defaultLicense',
                                         defaultLicense)

            browser = request.args['browser'][0]
            if browser == "None":
                browser = None
            try:
                self.config.browser = mywebbrowser.get(browser)
            except Exception as e:
                browser_path = Path(browser)
                if browser_path.exists():
                    mywebbrowser.register(
                        'custom-browser', None,
                        mywebbrowser.BackgroundBrowser(browser_path.abspath()),
                        -1)
                    self.config.browser = mywebbrowser.get('custom-browser')
                else:
                    raise e
            self.config.configParser.set('system', 'browser', browser)

            showPreferencesOnStart = request.args['showPreferencesOnStart'][0]
            self.config.showPreferencesOnStart = showPreferencesOnStart
            self.config.configParser.set('user', 'showPreferencesOnStart',
                                         showPreferencesOnStart)
        except Exception as e:
            log.exception(e)
            return json.dumps({
                'success': False,
                'errorMessage': _("Failed to save preferences")
            })
        return json.dumps({'success': True, 'data': data})
Beispiel #36
0
    def handleExport(self, client, exportType, filename, print_callback=''):
        """
        Called by js. 
        Exports the current package to one of the above formats
        'exportType' can be one of 'singlePage' 'webSite' 'zipFile' 'ipod'
                     'textFile' or 'scorm'
        'filename' is a file for scorm pages, and a directory for websites
        """ 
        webDir     = Path(self.config.webDir)
        stylesDir  = webDir.joinpath('style', self.package.style)

        exportDir  = Path(filename).dirname()
        if exportDir and not exportDir.exists():
            client.alert(_(u'Cannot access directory named ') +
                         unicode(exportDir) +
                         _(u'. Please use ASCII names.'))
            return

        """ 
        adding the print feature in using the same export functionality:
        """
        if exportType == 'singlePage' or exportType == 'printSinglePage':
            printit = 0
            if exportType == 'printSinglePage':
                printit = 1
            exported_dir = self.exportSinglePage(client, filename, webDir, \
                                                 stylesDir, printit)
            # the above will return None if the desired exported directory
            # already exists (printing always goes to a new temp dir, though):
            if printit == 1 and not exported_dir is None:
                web_printdir = self.get_printdir_relative2web(exported_dir)
                # now that this has ben exported, go ahead and trigger 
                # the requested printing callback:
                client.call(print_callback, filename, exported_dir, \
                            web_printdir)

        elif exportType == 'webSite':
            self.exportWebSite(client, filename, stylesDir)
            
        elif exportType == 'zipFile':
            filename = self.b4save(client, filename, '.zip', _(u'EXPORT FAILED!'))
            self.exportWebZip(client, filename, stylesDir)
        elif exportType == 'textFile':
            self.exportText(client, filename)
        elif exportType == 'ipod':
            self.exportIpod(client, filename)
        elif exportType == "scorm":
            filename = self.b4save(client, filename, '.zip', _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "scorm1.2")
        elif exportType == "scorm2004":
            filename = self.b4save(client, filename, '.zip', _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "scorm2004")
        elif exportType == "commoncartridge":
            filename = self.b4save(client, filename, '.zip', _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "commoncartridge")
        else:
            filename = self.b4save(client, filename, '.zip', _(u'EXPORT FAILED!'))
            self.exportIMS(client, filename, stylesDir)
 def checkImageVersionsExist(self, imgPath, package, exetocEl):
     imgResProfs = exetocEl.getAttribute("resolutions").split(",")
     
     for profileName in imgResProfs:
         if profileName == "":
             return 
         newFileName = imgPath.namebase + "-" + profileName + imgPath.ext
         profileImgPath = Path(imgPath.parent/newFileName)
         self.assertTrue(profileImgPath.exists(), "Image ")
Beispiel #38
0
 def exportWebZip(self, client, filename, stylesDir):
     filename = Path(filename)
     log.debug(u"exportWebsite, filename=%s" % filename)
     if not filename.ext.lower() == '.zip': 
         filename += '.zip'
     if filename.exists(): 
         filename.remove()
     websiteExport = WebsiteExport(self.config, stylesDir, filename)
     websiteExport.exportZip(self.package)
     client.alert(_(u'Exported to %s') % filename)
Beispiel #39
0
 def exportText(self, client, filename):
     filename = Path(filename)
     log.debug(u"exportWebsite, filename=%s" % filename)
     if not filename.ext.lower() == '.txt': 
         filename += '.txt'
     if filename.exists(): 
         filename.remove()
     textExport = TextExport(filename)
     textExport.export(self.package)
     client.alert(_(u'Exported to %s') % filename)
Beispiel #40
0
    def __loadIdevice(self):
        """
        Load IDevice configuration from its config.xml file
        """
        try:
            if self._valid:
                # Check if the folder has a config.xml file
                configFile = Path(self._iDeviceDir + '/config.xml')
                if configFile.exists():
                    # Get config data
                    configData = open(configFile).read()
                    try:
                        newConfigData = configData.decode()
                    except UnicodeDecodeError:
                        configCharset = chardet.detect(configData)
                        newConfigData = configData.decode(
                            configCharset['encoding'], 'replace')

                    # Parse the XML file
                    xmlConfig = minidom.parseString(newConfigData)

                    # Get main element
                    xmlIdevice = xmlConfig.getElementsByTagName('idevice')

                    # Initialize results variable
                    result = dict()

                    # If there is a main element tag
                    if (len(xmlIdevice) > 0):
                        # Go over all the child nodes
                        for tag in xmlIdevice[0].childNodes:
                            # Only process the node if it is an Element
                            # This means only tags get processed
                            if (isinstance(tag, minidom.Element)):
                                # Add the tag name and value to the result dictionary
                                result.update(
                                    {tag.tagName: tag.firstChild.nodeValue})

                        if 'title' in result and 'css-class' in result:
                            return result
                        else:
                            raise InvalidConfigJsIdevice(
                                Path(self._iDeviceDir).basename(),
                                'Mandatory fields not found.')
                else:
                    raise InvalidConfigJsIdevice(
                        Path(self._iDeviceDir).basename(),
                        'config.xml file doesn\'t exist.')
        except IOError as ioerror:
            # If we can't load an iDevice, we simply continue with the rest (and log it)
            log.debug("iDevice " + Path(self._iDeviceDir).basename() +
                      " doesn't appear to have a valid \"config.xml\" file")
            raise InvalidConfigJsIdevice(
                Path(self._iDeviceDir).basename(), ioerror.message)
Beispiel #41
0
 def handleTinyMCEimageChoice(self, client, tinyMCEwin, tinyMCEwin_name, \
                          tinyMCEfield, local_filename, preview_filename):
     """
     Once an image is selected in the file browser that is spawned by the 
     TinyMCE image dialog, copy this file (which is local to the user's 
     machine) into the server space, under a preview directory 
     (after checking if this exists, and creating it if necessary).
     Note that this IS a "cheat", in violation of the client-server 
     separation, but can be done since we know that the eXe server is 
     actually sitting on the client host.
     """
     server_filename = ""
     callback_errors = ""
     errors = 0
     webDir     = Path(self.config.webDir)
     previewDir  = webDir.joinpath('previews')
     if not previewDir.exists():
         log.debug("image previews directory does not yet exist; " \
                 + "creating as %s " % previewDir)
         previewDir.makedirs()
     elif not previewDir.isdir():
         client.alert( \
             _(u'Preview directory %s is a file, cannot replace it') \
             % previewDir)
         log.error("Couldn't preview tinyMCE-chosen image: "+
                   "Preview dir %s is a file, cannot replace it" \
                   % previewDir)
         callback_errors =  "Preview dir is a file, cannot replace"
         errors += 1
     if errors == 0:
         localImagePath = Path(local_filename)
         if not localImagePath.exists() or not localImagePath.isfile():
             client.alert( \
                  _(u'Image file %s is not found, cannot preview it') \
                  % localImagePath)
             log.error("Couldn't find tinyMCE-chosen image: %s" \
                     % localImagePath)
             callback_errors = "Image file %s not found, cannot preview" \
                     % localImagePath
             errors += 1
     try:
         server_filename = previewDir.joinpath(preview_filename);
         log.debug("handleTinyMCEimageChoice copying image from \'"\
                 + local_filename + "\' to \'" \
                 + server_filename.abspath().encode('utf-8') + "\'.");
         shutil.copyfile(local_filename, \
                 server_filename.abspath().encode('utf-8'));
     except Exception, e:
         client.alert(_('SAVE FAILED!\n%s' % str(e)))
         log.error("handleTinyMCEimageChoice unable to copy local image "\
                 +"file to server prevew, error = " + str(e))
         raise
Beispiel #42
0
 def exportScorm(self, client, filename, stylesDir, scormType):
     """
     Exports this package to a scorm package file
     """
     filename = Path(filename)
     log.debug(u"exportScorm, filename=%s" % filename)
     if not filename.ext.lower() == '.zip': 
         filename += '.zip'
     if filename.exists(): 
         filename.remove()
     scormExport = ScormExport(self.config, stylesDir, filename, scormType)
     scormExport.export(self.package)
     client.alert(_(u'Exported to %s') % filename)
Beispiel #43
0
 def exportIMS(self, client, filename, stylesDir):
     """
     Exports this package to a ims package file
     """
     log.debug(u"exportIMS")
     if not filename.lower().endswith('.zip'): 
         filename += '.zip'
     filename = Path(filename)
     if filename.exists(): 
         filename.remove()
     imsExport = IMSExport(self.config, stylesDir, filename)
     imsExport.export(self.package)
     client.alert(_(u'Exported to %s' % filename))
Beispiel #44
0
 def __renderIcons(self, style):
     """
     Return xhtml string for dispay all icons
     """
     iconpath  = Path(G.application.config.stylesDir/style)
     iconfiles = iconpath.files("icon_*")
     html = '<div id="styleIcons"><div style="height:300px;overflow:auto">'
     
     for iconfile in iconfiles:
         iconname = iconfile.namebase
         icon     = iconname.split("_", 1)[1]
         
         iconExists = False
         iconExtension = "gif"
         myIcon = Path(G.application.config.stylesDir/style/iconname + ".gif")
         if myIcon.exists():
             iconExists = True
             iconValue = icon+'.'+iconExtension  
             iconSrc = '/style/%s/icon_%s' % (style, iconValue)
         else:
             myIcon = Path(G.application.config.stylesDir/style/iconname + ".png")
             if myIcon.exists():
                 iconExists = True 
                 iconExtension = "png"
                 iconValue = icon+'.'+iconExtension
                 iconSrc = '/style/%s/icon_%s' % (style, iconValue)
         
         if iconExists:
             filename = "/style/%s/%s.%s" % (style, iconname, iconExtension)
             html += u'<div style="float:left; text-align:center; width:105px;\n'
             html += u'margin-right:10px; margin-bottom:15px" > '
             html += u'<img src="%s" \n' % filename
             html += u"style=\"border:1px solid #E8E8E8;padding:5px;cursor:pointer;max-width:60px;height:auto\" onclick=\"window[0].selectStyleIcon('%s',this, '%s', '%s')\" title=\"%s.%s\">\n" % (icon, iconSrc, self.id, icon ,iconExtension)
             html += u'<br /><span style="display:inline-block;width:100px;overflow:hidden;text-overflow:ellipsis">%s.%s</span></div>\n' % (icon, iconExtension)
     
     html += '</div></div>'
     
     return html
Beispiel #45
0
 def __renderIcons(self):
     """
     Return xhtml string for dispay all icons
     """
     iconpath  = self.style.get_style_dir()
     iconfiles = iconpath.files("icon_*")
     html = '<div id="styleIcons"><div style="height:300px;overflow:auto">'
     
     for iconfile in iconfiles:
         iconname = iconfile.namebase
         icon     = iconname.split("_", 1)[1]
         
         iconExists = False
         iconExtension = "gif"
         myIcon = Path(G.application.config.stylesDir/self.style.get_dirname()/iconname + ".gif")
         if myIcon.exists():
             iconExists = True
         else:
             myIcon = Path(G.application.config.stylesDir/self.style.get_dirname()/iconname + ".png")
             if myIcon.exists():
                 iconExists = True 
                 iconExtension = "png"
         
         if iconExists:
             filename = "/style/%s/%s.%s" % (self.style.get_dirname(), iconname, iconExtension)
             html += u'<div style="float:left; text-align:center; width:105px;\n'
             html += u'margin-right:10px; margin-bottom:15px" > '
             html += u'<img src="%s" \n' % filename
             # html += u' alt="%s" ' % _("Submit")
             # window[1] because we use Ext.MessageBox instead of libot_drag.js
             html += u"style=\"border:1px solid #E8E8E8;padding:5px;cursor:pointer;max-width:60px;height:auto\" onclick=\"window[1].selectStyleIcon('%s',this)\" title=\"%s.%s\">\n" % (icon, icon, iconExtension)
             # html += u"style=\"cursor:pointer\" onclick=\"window[1].submitLink('selectIcon','%s',1)\">\n" % icon
             html += u'<br /><span style="display:inline-block;width:100px;overflow:hidden;text-overflow:ellipsis">%s.%s</span></div>\n' % (icon, iconExtension)
     
     html += '</div></div>'
     
     return html
Beispiel #46
0
 def _setupConfigFile(self, configParser):
     """
     Setup our own config file
     """
     utils.SuperTestCase._setupConfigFile(self, configParser)
     # Create an empty dir to stick the config file
     tmp = Path('tmp')
     if not tmp.exists():
         tmp.mkdir()
     logfn = tmp / 'exe.log'
     if logfn.exists():
         try:
             logfn.remove()
         except OSError:
             pass
     configParser.system.configDir = tmp
     configParser.logging.root = 'ERROR'
     configParser.logging.foo = 'DEBUG'
     configParser.logging.foo = 'DEBUG'
 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 #48
0
 def testReferenceCounting(self):
     """
     Make 3 resources with different names but same md5, ensure they are reference counted properly
     """
     res1 = Path('my.resource1.bin')
     res2 = Path('my.resource2.bin')
     res3 = Path('my.resource3.bin')
     for res in (res1, res2, res3):
         res.write_bytes('SOME NICE DATA')
     res1md5 = res1.md5
     res4 = Path('tmp/my.resource1.bin')
     if not res4.dirname().exists():
         res4.dirname().makedirs()
     res4.write_bytes('SOME *DIFFERENT* DATA')
     res4md5 = res4.md5
     res1, res2, res3, res4 = map(lambda f: Resource(self.package, f),
                                  (res1, res2, res3, res4))
     assert res1.storageName == 'my.resource1.bin', res1.storageName
     assert res2.storageName == 'my.resource1.bin', res2.storageName
     assert res3.storageName == 'my.resource1.bin', res3.storageName
     assert res4.storageName == 'my.resource1.1.bin', res4.storageName
     assert res4.userName == 'my.resource1.bin', res4.userName
     assert len(self.package.resources) == 2
     assert len(self.package.resources[res1.path.md5]) == 3
     assert len(self.package.resources[res4.path.md5]) == 1
     assert self.package.resources[res4md5][0] is res4
     # Now start deleting things
     res4path = Path(res4.path)
     assert res4path.exists()
     res4.delete()
     assert not res4path.exists()
     assert res4md5 not in self.package.resources
     assert not res4path.exists()
     res1path = Path(res1.path)
     assert res1path.exists()
     res2.delete()
     assert res1path.exists()
     assert res2 not in self.package.resources[res1md5]
     res1.delete()
     assert res1path.exists()
     assert res1 not in self.package.resources[res1md5]
     res3.delete()
     assert res1md5 not in self.package.resources
     assert not res1path.exists()
Beispiel #49
0
 def get_export_folder(self):
     export_folder = Path(self.get_jsidevice_dir()) / 'export'
     if export_folder.exists():
         return str(Path(self.get_dirname() + '/export/'))
    def handleExport(self, client, exportType, filename, print_callback=''):
        """
        Called by js. 
        Exports the current package to one of the above formats
        'exportType' can be one of 'singlePage' 'webSite' 'zipFile' 'ipod'
                     'textFile' or 'scorm'
        'filename' is a file for scorm pages, and a directory for websites
        """
        webDir = Path(self.config.webDir)
        stylesDir = webDir.joinpath('style', self.package.style)

        exportDir = Path(filename).dirname()
        if exportDir and not exportDir.exists():
            client.alert(
                _(u'Cannot access directory named ') + unicode(exportDir) +
                _(u'. Please use ASCII names.'))
            return
        """ 
        adding the print feature in using the same export functionality:
        """
        if exportType == 'singlePage' or exportType == 'printSinglePage':
            printit = 0
            if exportType == 'printSinglePage':
                printit = 1
            exported_dir = self.exportSinglePage(client, filename, webDir, \
                                                 stylesDir, printit)
            # the above will return None if the desired exported directory
            # already exists (printing always goes to a new temp dir, though):
            if printit == 1 and not exported_dir is None:
                web_printdir = self.get_printdir_relative2web(exported_dir)
                # now that this has ben exported, go ahead and trigger
                # the requested printing callback:
                client.call(print_callback, filename, exported_dir, \
                            web_printdir)

        elif exportType == 'webSite':
            self.exportWebSite(client, filename, stylesDir)

        elif exportType == 'zipFile':
            filename = self.b4save(client, filename, '.zip',
                                   _(u'EXPORT FAILED!'))
            self.exportWebZip(client, filename, stylesDir)
        elif exportType == 'textFile':
            self.exportText(client, filename)
        elif exportType == 'ipod':
            self.exportIpod(client, filename)
        elif exportType == "scorm":
            filename = self.b4save(client, filename, '.zip',
                                   _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "scorm1.2")
        elif exportType == "scorm2004":
            filename = self.b4save(client, filename, '.zip',
                                   _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "scorm2004")
        elif exportType == "commoncartridge":
            filename = self.b4save(client, filename, '.zip',
                                   _(u'EXPORT FAILED!'))
            self.exportScorm(client, filename, stylesDir, "commoncartridge")
        else:
            filename = self.b4save(client, filename, '.zip',
                                   _(u'EXPORT FAILED!'))
            self.exportIMS(client, filename, stylesDir)
    def handleTinyMCEimageChoice(self, client, tinyMCEwin, tinyMCEwin_name, \
                             tinyMCEfield, local_filename, preview_filename):
        """
        Once an image is selected in the file browser that is spawned by the 
        TinyMCE image dialog, copy this file (which is local to the user's 
        machine) into the server space, under a preview directory 
        (after checking if this exists, and creating it if necessary).
        Note that this IS a "cheat", in violation of the client-server 
        separation, but can be done since we know that the eXe server is 
        actually sitting on the client host.
        """
        server_filename = ""
        callback_errors = ""
        errors = 0

        log.debug('handleTinyMCEimageChoice: image local = ' + local_filename +
                  ', base=' + os.path.basename(local_filename))

        webDir = Path(G.application.tempWebDir)
        previewDir = webDir.joinpath('previews')

        if not previewDir.exists():
            log.debug("image previews directory does not yet exist; " \
                    + "creating as %s " % previewDir)
            previewDir.makedirs()
        elif not previewDir.isdir():
            client.alert( \
                _(u'Preview directory %s is a file, cannot replace it') \
                % previewDir)
            log.error("Couldn't preview tinyMCE-chosen image: "+
                      "Preview dir %s is a file, cannot replace it" \
                      % previewDir)
            callback_errors = "Preview dir is a file, cannot replace"
            errors += 1

        if errors == 0:
            log.debug('handleTinyMCEimageChoice: originally, local_filename=' +
                      local_filename)
            local_filename = unicode(local_filename, 'utf-8')
            log.debug('handleTinyMCEimageChoice: in unicode, local_filename=' +
                      local_filename)

            localImagePath = Path(local_filename)
            log.debug(
                'handleTinyMCEimageChoice: after Path, localImagePath= ' +
                localImagePath)
            if not localImagePath.exists() or not localImagePath.isfile():
                client.alert( \
                     _(u'Local file %s is not found, cannot preview it') \
                     % localImagePath)
                log.error("Couldn't find tinyMCE-chosen image: %s" \
                        % localImagePath)
                callback_errors = "Image file %s not found, cannot preview" \
                        % localImagePath
                errors += 1

        try:
            # joinpath needs its join arguments to already be in Unicode:
            #preview_filename = toUnicode(preview_filename);
            # but that's okay, cuz preview_filename is now URI safe, right?
            log.debug('URIencoded preview filename=' + preview_filename)

            server_filename = previewDir.joinpath(preview_filename)
            log.debug("handleTinyMCEimageChoice copying image from \'"\
                    + local_filename + "\' to \'" \
                    + server_filename.abspath() + "\'.")
            shutil.copyfile(local_filename, \
                    server_filename.abspath())

            # new optional description file to provide the
            # actual base filename, such that once it is later processed
            # copied into the resources directory, it can be done with
            # only the basename.   Otherwise the resource filenames
            # are too long for some users, preventing them from making
            # backup CDs of the content, for example.
            #
            # Remember that the full path of the
            # file is only used here as an easy way to keep the names
            # unique WITHOUT requiring a roundtrip call from the Javascript
            # to this server, and back again, a process which does not
            # seem to work with tinyMCE in the mix.  BUT, once tinyMCE's
            # part is done, and this image processed, it can be returned
            # to just its basename, since the resource parts have their
            # own unique-ification mechanisms already in place.

            descrip_file_path = Path(server_filename + ".exe_info")
            log.debug("handleTinyMCEimageChoice creating preview " \
                    + "description file \'" \
                    + descrip_file_path.abspath() + "\'.")
            descrip_file = open(descrip_file_path, 'wb')

            # safety measures against TinyMCE, otherwise it will
            # later take ampersands and entity-escape them into '&amp;',
            # and filenames with hash signs will not be found, etc.:
            unspaced_filename = local_filename.replace(' ', '_')
            unhashed_filename = unspaced_filename.replace('#', '_num_')
            unamped_local_filename = unhashed_filename.replace('&', '_and_')
            log.debug("and setting new file basename as: " +
                      unamped_local_filename)
            my_basename = os.path.basename(unamped_local_filename)
            descrip_file.write((u"basename=" + my_basename).encode('utf-8'))

            descrip_file.flush()
            descrip_file.close()

        except Exception, e:
            client.alert(_('SAVE FAILED!\n%s' % str(e)))
            log.error("handleTinyMCEimageChoice unable to copy local image "\
                    +"file to server prevew, error = " + str(e))
            raise
Beispiel #52
0
    def export(self, package):
        """
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        self.metadataType = package.exportMetadataType


        # Copy the style files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += self.styleDir.files("*.*")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        self.styleDir.copylist(styleFiles, outputDir)

        # copy the package's resource files
        for resourceFile in package.resourceDir.walkfiles():
            file = package.resourceDir.relpathto(resourceFile)

            if ("/" in file):
                Dir = Path(outputDir/file[:file.rindex("/")])
                if not Dir.exists():
                    Dir.makedirs()

                resourceFile.copy(outputDir/Dir)
            else:
                resourceFile.copy(outputDir)

        listCSSFiles=getFilesCSSToMinify('ims', self.styleDir)
        exportMinFileCSS(listCSSFiles, outputDir)

        # Export the package content
        self.pages = [ IMSPage("index", 1, package.root,
           metadataType=self.metadataType) ]

        self.generatePages(package.root, 2)
        uniquifyNames(self.pages)

        for page in self.pages:
            page.save(outputDir, self.pages)

        # Create the manifest file
        manifest = Manifest(self.config, outputDir, package, self.pages, self.metadataType)
        manifest.save("imsmanifest.xml")

        # Create lang file
        langGameFile = open(outputDir + '/common_i18n.js', "w")
        langGameFile.write(common.getJavaScriptStrings(False))
        langGameFile.close()

        # jQuery
        my_style = G.application.config.styleStore.getStyle(page.node.package.style)
        if my_style.hasValidConfig():
            if my_style.get_jquery() == True:
                jsFile = (self.scriptsDir/'exe_jquery.js')
                jsFile.copyfile(outputDir/'exe_jquery.js')

        else:
            jsFile = (self.scriptsDir/'exe_jquery.js')
            jsFile.copyfile(outputDir/'exe_jquery.js')

        dT = common.getExportDocType()
        if dT == "HTML5":
            jsFile = (self.scriptsDir/'exe_html5.js')
            jsFile.copyfile(outputDir/'exe_html5.js')

        listFiles=getFilesJSToMinify('ims', self.scriptsDir)
        exportMinFileJS(listFiles, outputDir)

        self.schemasDir.copylist(('imscp_v1p1.xsd',
                                  'imsmd_v1p2p2.xsd',
                                  'lom.xsd',
                                  'lomCustom.xsd',
                                  'ims_xml.xsd'), outputDir)

        # copy players for media idevices.
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False
        hasGallery        = False
        hasFX             = False
        hasSH             = False
        hasGames          = False
        hasElpLink        = False
        hasWikipedia      = False
        isBreak           = False
        hasInstructions   = False
        hasMediaelement   = False
        hasTooltips       = False
        hasABCMusic       = False
        listIdevicesFiles = []

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery and hasFX and hasSH and hasGames and hasElpLink and hasWikipedia and hasInstructions and hasMediaelement and hasTooltips and hasABCMusic):
                    isBreak = True
                    break
                if not hasFlowplayer:
                    if 'flowPlayer.swf' in idevice.systemResources:
                        hasFlowplayer = True
                if not hasMagnifier:
                    if 'mojomagnify.js' in idevice.systemResources:
                        hasMagnifier = True
                if not hasXspfplayer:
                    if 'xspf_player.swf' in idevice.systemResources:
                        hasXspfplayer = True
                if not hasGallery:
                    hasGallery = common.ideviceHasGallery(idevice)
                if not hasFX:
                    hasFX = common.ideviceHasFX(idevice)
                if not hasSH:
                    hasSH = common.ideviceHasSH(idevice)
                if not hasGames:
                    hasGames = common.ideviceHasGames(idevice)
                if not hasElpLink:
                    hasElpLink = common.ideviceHasElpLink(idevice,package)
                if not hasWikipedia:
                    if 'WikipediaIdevice' == idevice.klass:
                        hasWikipedia = True
                if not hasInstructions:
                    if 'TrueFalseIdevice' == idevice.klass or 'MultichoiceIdevice' == idevice.klass or 'VerdaderofalsofpdIdevice' == idevice.klass or 'EleccionmultiplefpdIdevice' == idevice.klass:
                        hasInstructions = True
                if not hasMediaelement:
                    hasMediaelement = common.ideviceHasMediaelement(idevice)
                if not hasTooltips:
                    hasTooltips = common.ideviceHasTooltips(idevice)
                if not hasABCMusic:
                    hasABCMusic = common.ideviceHasABCMusic(idevice)
                if hasattr(idevice, "_iDeviceDir"):
                    listIdevicesFiles.append((idevice.get_jsidevice_dir()/'export'))

            common.exportJavaScriptIdevicesFiles(page.node.idevices, outputDir);

        if hasFlowplayer:
            videofile = (self.templatesDir/'flowPlayer.swf')
            videofile.copyfile(outputDir/'flowPlayer.swf')
            controlsfile = (self.templatesDir/'flowplayer.controls.swf')
            controlsfile.copyfile(outputDir/'flowplayer.controls.swf')
        if hasMagnifier:
            videofile = (self.templatesDir/'mojomagnify.js')
            videofile.copyfile(outputDir/'mojomagnify.js')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(outputDir/'xspf_player.swf')
        if hasGallery:
            exeLightbox = (self.scriptsDir/'exe_lightbox')
            exeLightbox.copyfiles(outputDir)
        if hasFX:
            exeEffects = (self.scriptsDir/'exe_effects')
            exeEffects.copyfiles(outputDir)
        if hasSH:
            exeSH = (self.scriptsDir/'exe_highlighter')
            exeSH.copyfiles(outputDir)
        if hasGames:
            exeGames = (self.scriptsDir/'exe_games')
            exeGames.copyfiles(outputDir)
            # Add game js string to common_i18n
            langGameFile = open(outputDir + '/common_i18n.js', "a")
            langGameFile.write(common.getGamesJavaScriptStrings(False))
            langGameFile.close()
        if hasElpLink or package.get_exportElp():
            # Export the elp file
            currentPackagePath = Path(package.filename)
            currentPackagePath.copyfile(outputDir/package.name+'.elp')
        if hasWikipedia:
            wikipediaCSS = (self.cssDir/'exe_wikipedia.css')
            wikipediaCSS.copyfile(outputDir/'exe_wikipedia.css')
        if hasInstructions:
            common.copyFileIfNotInStyle('panel-amusements.png', self, outputDir)
            common.copyFileIfNotInStyle('stock-stop.png', self, outputDir)
        if hasMediaelement:
            mediaelement = (self.scriptsDir/'mediaelement')
            mediaelement.copyfiles(outputDir)
            if dT != "HTML5":
                jsFile = (self.scriptsDir/'exe_html5.js')
                jsFile.copyfile(outputDir/'exe_html5.js')
        if hasTooltips:
            exe_tooltips = (self.scriptsDir/'exe_tooltips')
            exe_tooltips.copyfiles(outputDir)
        if hasABCMusic:
            pluginScripts = (self.scriptsDir/'tinymce_4/js/tinymce/plugins/abcmusic/export')
            pluginScripts.copyfiles(outputDir)
        if hasattr(package, 'exportSource') and package.exportSource:
            (G.application.config.webDir/'templates'/'content.xsd').copyfile(outputDir/'content.xsd')
            (outputDir/'content.data').write_bytes(encodeObject(package))
            (outputDir/'contentv3.xml').write_bytes(encodeObjectToXML(package))


        if package.license == "license GFDL":
            # include a copy of the GNU Free Documentation Licence
            (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')

        # Zip it up!
        self.filename.safeSave(self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'), outputDir)
        # Clean up the temporary dir
        outputDir.rmtree()
Beispiel #53
0
    def export(self, package):
        """
        Export epub 3 package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()
        '''
        fileDir = outputDir/"META-INF"
        fileDir.mkdir()
        fileDir = outputDir/"Content"
        fileDir.mkdir()
        '''

        metainfPages = Path(outputDir.abspath() + '/META-INF')
        # metainfPages = outputDir/'META-INF'
        metainfPages.mkdir()
        contentPages = Path(outputDir.abspath() + '/EPUB')
        # contentPages = outputDir/'Content'
        contentPages.mkdir()
        # print contentPages.abspath()
        # print outputDir.abspath()

        # Export the package content
        self.pages = [Epub3Cover("cover", 1, package.root)]

        self.generatePages(package.root, 2)
        uniquifyNames(self.pages)

        cover = None
        for page in self.pages:
            page.save(contentPages, self.pages)
            if hasattr(page, 'cover'):
                cover = page.cover

        # Create mimetype file
        mimetypeFile = open(outputDir.abspath() + '/mimetype', "w")
        mimetypeFile.write('application/epub+zip')
        mimetypeFile.close()

        # Create common_i18n file
        langFile = open(contentPages + '/common_i18n.js', "w")
        langFile.write(common.getJavaScriptStrings(False))
        langFile.close()

        # Copy the style files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / '..' / 'popup_bg.gif']
        styleFiles += [
            f for f in self.styleDir.files("*.*")
            if f.basename() not in ['nav.css']
        ]

        # FIXME for now, only copy files referenced in Common Cartridge
        # this really should apply to all exports, but without a manifest
        # of the files needed by an included stylesheet it is too restrictive

        # Add fallback document for possible image links
        if Path(self.styleDir / 'fallback.xhtml').exists():
            styleFiles += [self.styleDir / 'fallback.xhtml']
        else:
            styleFiles += [self.styleDir / '..' / 'fallback.xhtml']

        # copy the package's resource files
        for resourceFile in package.resourceDir.walkfiles():
            fn = package.resourceDir.relpathto(resourceFile)

            if ("/" in fn):
                Dir = Path(contentPages / fn[:fn.rindex("/")])
                if not Dir.exists():
                    Dir.makedirs()

                resourceFile.copy(contentPages / Dir)
            else:
                resourceFile.copy(contentPages)

        self.styleDir.copylist(styleFiles, contentPages)

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        hasGallery = False
        hasFX = False
        hasSH = False
        hasGames = False
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasTooltips = False
        hasABCMusic = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer
                        and hasGallery and hasFX and hasSH and hasGames
                        and hasWikipedia and hasInstructions and hasTooltips
                        and hasABCMusic):
                    isBreak = True
                    break
                if not hasFlowplayer:
                    if 'flowPlayer.swf' in idevice.systemResources:
                        hasFlowplayer = True
                if not hasMagnifier:
                    if 'mojomagnify.js' in idevice.systemResources:
                        hasMagnifier = True
                if not hasXspfplayer:
                    if 'xspf_player.swf' in idevice.systemResources:
                        hasXspfplayer = True
                if not hasGallery:
                    hasGallery = common.ideviceHasGallery(idevice)
                if not hasFX:
                    hasFX = common.ideviceHasFX(idevice)
                if not hasSH:
                    hasSH = common.ideviceHasSH(idevice)
                if not hasGames:
                    hasGames = common.ideviceHasGames(idevice)
                if not hasWikipedia:
                    if 'WikipediaIdevice' == idevice.klass:
                        hasWikipedia = True
                if not hasInstructions:
                    if 'TrueFalseIdevice' == idevice.klass or 'MultichoiceIdevice' == idevice.klass or 'VerdaderofalsofpdIdevice' == idevice.klass or 'EleccionmultiplefpdIdevice' == idevice.klass:
                        hasInstructions = True
                if not hasTooltips:
                    hasTooltips = common.ideviceHasTooltips(idevice)
                if not hasABCMusic:
                    hasABCMusic = common.ideviceHasABCMusic(idevice)

            common.exportJavaScriptIdevicesFiles(page.node.idevices,
                                                 contentPages)

        if hasFlowplayer:
            videofile = (self.templatesDir / 'flowPlayer.swf')
            videofile.copyfile(contentPages / 'flowPlayer.swf')
            controlsfile = (self.templatesDir / 'flowplayer.controls.swf')
            controlsfile.copyfile(contentPages / 'flowplayer.controls.swf')
        if hasMagnifier:
            videofile = (self.templatesDir / 'mojomagnify.js')
            videofile.copyfile(contentPages / 'mojomagnify.js')
        if hasXspfplayer:
            videofile = (self.templatesDir / 'xspf_player.swf')
            videofile.copyfile(contentPages / 'xspf_player.swf')
        if hasGallery:
            exeLightbox = (self.scriptsDir / 'exe_lightbox')
            exeLightbox.copyfiles(contentPages)
        if hasFX:
            exeEffects = (self.scriptsDir / 'exe_effects')
            exeEffects.copyfiles(contentPages)
        if hasSH:
            exeSH = (self.scriptsDir / 'exe_highlighter')
            exeSH.copyfiles(contentPages)
        if hasGames:
            exeGames = (self.scriptsDir / 'exe_games')
            exeGames.copyfiles(contentPages)
            # Add game js string to common_i18n
            langGameFile = open(contentPages + '/common_i18n.js', "a")
            langGameFile.write(common.getGamesJavaScriptStrings(False))
            langGameFile.close()
        if hasWikipedia:
            wikipediaCSS = (self.cssDir / 'exe_wikipedia.css')
            wikipediaCSS.copyfile(contentPages / 'exe_wikipedia.css')
        if hasInstructions:
            common.copyFileIfNotInStyle('panel-amusements.png', self,
                                        contentPages)
            common.copyFileIfNotInStyle('stock-stop.png', self, contentPages)
        if hasTooltips:
            exe_tooltips = (self.scriptsDir / 'exe_tooltips')
            exe_tooltips.copyfiles(contentPages)
        if hasABCMusic:
            pluginScripts = (self.scriptsDir /
                             'tinymce_4/js/tinymce/plugins/abcmusic/export')
            pluginScripts.copyfiles(contentPages)

        my_style = G.application.config.styleStore.getStyle(package.style)
        if my_style.hasValidConfig:
            if my_style.get_jquery() == True:
                jsFile = (self.scriptsDir / 'exe_jquery.js')
                jsFile.copyfile(contentPages / 'exe_jquery.js')
        else:
            jsFile = (self.scriptsDir / 'exe_jquery.js')
            jsFile.copyfile(contentPages / 'exe_jquery.js')

        # Copy and minify CSS files
        css_files = getFilesCSSToMinify('epub3', self.styleDir)
        exportMinFileCSS(css_files, contentPages)

        # Copy and minify JS files
        js_files = getFilesJSToMinify('epub3', self.scriptsDir)
        exportMinFileJS(js_files, contentPages)

        #         if hasattr(package, 'exportSource') and package.exportSource:
        #             (G.application.config.webDir / 'templates' / 'content.xsd').copyfile(outputDir / 'content.xsd')
        #             (outputDir / 'content.data').write_bytes(encodeObject(package))
        #             (outputDir / 'contentv3.xml').write_bytes(encodeObjectToXML(package))

        if package.license == "license GFDL":
            # include a copy of the GNU Free Documentation Licence
            (self.templatesDir / 'fdl.html').copyfile(contentPages /
                                                      'fdl.html')

        # Create the nav.xhtml file
        container = NavEpub3(self.pages, contentPages)
        container.save()

        # Create the publication file
        publication = PublicationEpub3(self.config, contentPages, package,
                                       self.pages, cover)
        publication.save("package.opf")

        # Create the container file
        container = ContainerEpub3(metainfPages)
        container.save("container.xml")

        # Zip it up!
        self.filename.safeSave(
            self.doZip, _(u'EXPORT FAILED!\nLast succesful export is %s.'),
            outputDir)
        # Clean up the temporary dir

        outputDir.rmtree()
Beispiel #54
0
    def export(self, package):
        """
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        self.metadataType = package.exportMetadataType

        # copy the package's resource files
        for resourceFile in package.resourceDir.walkfiles():
            file = package.resourceDir.relpathto(resourceFile)

            if ("/" in file):
                Dir = Path(outputDir / file[:file.rindex("/")])

                if not Dir.exists():
                    Dir.makedirs()

                resourceFile.copy(outputDir / Dir)
            else:
                resourceFile.copy(outputDir)

        # copy the package's resource files, only non existant in outputDir
#        outputDirFiles = outputDir.files()
#        for rfile in package.resourceDir.files():
#            if rfile not in outputDirFiles:
#                rfile.copy(outputDir)

# copy the package's resource files, only indexed in package.resources
#        for md5 in package.resources.values():
#            for resource in md5:
#                resource.path.copy(outputDir)

# Export the package content
# Import the Scorm Page class , if the secure mode is off.  If the style has it's own page class
# use that, else use the default one.
        if self.styleSecureMode == "0":
            if (self.styleDir / "scormpage.py").exists():
                global ScormPage
                module = imp.load_source("ScormPage",
                                         self.styleDir / "scormpage.py")
                ScormPage = module.ScormPage

        self.pages = [
            ScormPage("index",
                      1,
                      package.root,
                      scormType=self.scormType,
                      metadataType=self.metadataType)
        ]

        self.generatePages(package.root, 2)
        uniquifyNames(self.pages)

        for page in self.pages:
            page.save(outputDir, self.pages)
            if not self.hasForum:
                for idevice in page.node.idevices:
                    if hasattr(idevice, "isForum"):
                        if idevice.forum.lms.lms == "moodle":
                            self.hasForum = True
                            break

        # Create the manifest file
        manifest = Manifest(self.config, outputDir, package, self.pages,
                            self.scormType, self.metadataType)
        modifiedMetaData = manifest.save("imsmanifest.xml")

        # Create lang file
        langFile = open(outputDir + '/common_i18n.js', "w")
        langFile.write(common.getJavaScriptStrings(False))
        langFile.close()

        if self.hasForum:
            manifest.save("discussionforum.xml")

        # Copy the style files to the output dir

        styleFiles = [self.styleDir / '..' / 'popup_bg.gif']
        # And with all the files of the style we avoid problems:
        styleFiles += self.styleDir.files("*.*")
        if self.scormType == "commoncartridge":
            for sf in styleFiles[:]:
                if sf.basename() not in manifest.dependencies:
                    styleFiles.remove(sf)
        self.styleDir.copylist(styleFiles, outputDir)

        listCSSFiles = getFilesCSSToMinify('scorm', self.styleDir)
        exportMinFileCSS(listCSSFiles, outputDir)

        # Copy the scripts

        dT = common.getExportDocType()
        if dT == "HTML5":
            #listFiles+=[self.scriptsDir/'exe_html5.js']
            #listOutFiles+=[outputDir/'exe_html5.js']
            jsFile = (self.scriptsDir / 'exe_html5.js')
            jsFile.copyfile(outputDir / 'exe_html5.js')

        # jQuery
        my_style = G.application.config.styleStore.getStyle(
            page.node.package.style)
        if my_style.hasValidConfig():
            if my_style.get_jquery() == True:
                #listFiles+=[self.scriptsDir/'exe_jquery.js']
                #listOutFiles+=[outputDir/'exe_jquery.js']
                jsFile = (self.scriptsDir / 'exe_jquery.js')
                jsFile.copyfile(outputDir / 'exe_jquery.js')
        else:
            #listFiles+=[self.scriptsDir/'exe_jquery.js']
            #listOutFiles+=[outputDir/'exe_jquery.js']
            jsFile = (self.scriptsDir / 'exe_jquery.js')
            jsFile.copyfile(outputDir / 'exe_jquery.js')

        if self.scormType == "commoncartridge" or self.scormType == "scorm2004" or self.scormType == "scorm1.2":
            listFiles = getFilesJSToMinify('scorm', self.scriptsDir)

        exportMinFileJS(listFiles, outputDir)

        if self.scormType == "scorm2004" or self.scormType == "scorm1.2":
            self.scriptsDir.copylist(
                ('SCORM_API_wrapper.js', 'SCOFunctions.js'), outputDir)

        # about SCHEMAS:
        schemasDir = ""
        if self.scormType == "scorm1.2":
            schemasDir = self.schemasDir / "scorm1.2"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                 'imsmd_rootv1p2p1.xsd', 'adlcp_rootv1p2.xsd',
                                 'lom.xsd', 'lomCustom.xsd', 'ims_xml.xsd'),
                                outputDir)
        elif self.scormType == "scorm2004":
            schemasDir = self.schemasDir / "scorm2004"
            schemasDir.copylist(
                ('adlcp_v1p3.xsd', 'adlnav_v1p3.xsd', 'adlseq_v1p3.xsd',
                 'datatypes.dtd', 'imscp_v1p1.xsd', 'imsssp_v1p0.xsd',
                 'imsss_v1p0.xsd', 'imsss_v1p0auxresource.xsd',
                 'imsss_v1p0control.xsd', 'imsss_v1p0delivery.xsd',
                 'imsmd_rootv1p2p1.xsd', 'imsss_v1p0limit.xsd',
                 'imsss_v1p0objective.xsd', 'imsss_v1p0random.xsd',
                 'imsss_v1p0rollup.xsd', 'imsss_v1p0seqrule.xsd',
                 'imsss_v1p0util.xsd', 'ims_xml.xsd', 'lom.xsd',
                 'lomCustom.xsd', 'xml.xsd', 'XMLSchema.dtd'), outputDir)
            try:
                import shutil, errno
                shutil.copytree(schemasDir / "common", outputDir / "common")
                shutil.copytree(schemasDir / "extend", outputDir / "extend")
                shutil.copytree(schemasDir / "unique", outputDir / "unique")
                shutil.copytree(schemasDir / "vocab", outputDir / "vocab")
            except OSError as exc:
                if exc.errno == errno.ENOTDIR:
                    shutil.copy(schemasDir, outputDir)
                else:
                    raise

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        hasGallery = False
        hasFX = False
        hasSH = False
        hasGames = False
        hasElpLink = False
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasMediaelement = False
        hasTooltips = False
        hasABCMusic = False
        listIdevicesFiles = []

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer
                        and hasGallery and hasFX and hasSH and hasGames
                        and hasElpLink and hasWikipedia and hasInstructions
                        and hasMediaelement and hasTooltips and hasABCMusic):
                    isBreak = True
                    break
                if not hasFlowplayer:
                    if 'flowPlayer.swf' in idevice.systemResources:
                        hasFlowplayer = True
                if not hasMagnifier:
                    if 'mojomagnify.js' in idevice.systemResources:
                        hasMagnifier = True
                if not hasXspfplayer:
                    if 'xspf_player.swf' in idevice.systemResources:
                        hasXspfplayer = True
                if not hasGallery:
                    hasGallery = common.ideviceHasGallery(idevice)
                if not hasFX:
                    hasFX = common.ideviceHasFX(idevice)
                if not hasSH:
                    hasSH = common.ideviceHasSH(idevice)
                if not hasGames:
                    hasGames = common.ideviceHasGames(idevice)
                if not hasElpLink:
                    hasElpLink = common.ideviceHasElpLink(idevice, package)
                if not hasWikipedia:
                    if 'WikipediaIdevice' == idevice.klass:
                        hasWikipedia = True
                if not hasInstructions:
                    if 'TrueFalseIdevice' == idevice.klass or 'MultichoiceIdevice' == idevice.klass or 'VerdaderofalsofpdIdevice' == idevice.klass or 'EleccionmultiplefpdIdevice' == idevice.klass:
                        hasInstructions = True
                if not hasMediaelement:
                    hasMediaelement = common.ideviceHasMediaelement(idevice)
                if not hasTooltips:
                    hasTooltips = common.ideviceHasTooltips(idevice)
                if not hasABCMusic:
                    hasABCMusic = common.ideviceHasABCMusic(idevice)
                if hasattr(idevice, "_iDeviceDir"):
                    listIdevicesFiles.append(
                        (idevice.get_jsidevice_dir() / 'export'))

            common.exportJavaScriptIdevicesFiles(page.node.idevices, outputDir)

        if hasFlowplayer:
            videofile = (self.templatesDir / 'flowPlayer.swf')
            videofile.copyfile(outputDir / 'flowPlayer.swf')
            controlsfile = (self.templatesDir / 'flowplayer.controls.swf')
            controlsfile.copyfile(outputDir / 'flowplayer.controls.swf')
        if hasMagnifier:
            videofile = (self.templatesDir / 'mojomagnify.js')
            videofile.copyfile(outputDir / 'mojomagnify.js')
        if hasXspfplayer:
            videofile = (self.templatesDir / 'xspf_player.swf')
            videofile.copyfile(outputDir / 'xspf_player.swf')
        if hasGallery:
            exeLightbox = (self.scriptsDir / 'exe_lightbox')
            exeLightbox.copyfiles(outputDir)
        if hasFX:
            exeEffects = (self.scriptsDir / 'exe_effects')
            exeEffects.copyfiles(outputDir)
        if hasSH:
            exeSH = (self.scriptsDir / 'exe_highlighter')
            exeSH.copyfiles(outputDir)
        if hasGames:
            exeGames = (self.scriptsDir / 'exe_games')
            exeGames.copyfiles(outputDir)
            # Add game js string to common_i18n
            langGameFile = open(outputDir + '/common_i18n.js', "a")
            langGameFile.write(common.getGamesJavaScriptStrings(False))
            langGameFile.close()
        if hasElpLink or package.get_exportElp():
            # Export the elp file
            currentPackagePath = Path(package.filename)
            currentPackagePath.copyfile(outputDir / package.name + '.elp')
        if hasWikipedia:
            wikipediaCSS = (self.cssDir / 'exe_wikipedia.css')
            wikipediaCSS.copyfile(outputDir / 'exe_wikipedia.css')
        if hasInstructions:
            common.copyFileIfNotInStyle('panel-amusements.png', self,
                                        outputDir)
            common.copyFileIfNotInStyle('stock-stop.png', self, outputDir)
        if hasMediaelement:
            mediaelement = (self.scriptsDir / 'mediaelement')
            mediaelement.copyfiles(outputDir)
            if dT != "HTML5":
                jsFile = (self.scriptsDir / 'exe_html5.js')
        if hasTooltips:
            exe_tooltips = (self.scriptsDir / 'exe_tooltips')
            exe_tooltips.copyfiles(outputDir)
        if hasABCMusic:
            pluginScripts = (self.scriptsDir /
                             'tinymce_4/js/tinymce/plugins/abcmusic/export')
            pluginScripts.copyfiles(outputDir)
        ext = ".html"
        if G.application.config.cutFileName == "1":
            ext = ".htm"

        if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
            if package.license == "license GFDL":
                # include a copy of the GNU Free Documentation Licence
                (self.templatesDir / 'fdl' + ext).copyfile(outputDir / 'fdl' +
                                                           ext)

        if hasattr(package, 'scowsinglepage') and package.scowsinglepage:
            page = SinglePage("singlepage_index", 1, package.root)
            page.save(outputDir / "singlepage_index" + ext)
            # Incluide eXe's icon if the Style doesn't have one
            themePath = Path(G.application.config.stylesDir / package.style)
            themeFavicon = themePath.joinpath("favicon.ico")
            if not themeFavicon.exists():
                faviconFile = (self.imagesDir / 'favicon.ico')
                faviconFile.copyfile(outputDir / 'favicon.ico')
        if hasattr(package, 'scowwebsite') and package.scowwebsite:
            website = WebsiteExport(self.config, self.styleDir, outputDir,
                                    "website_")
            website.export(package)
            (self.styleDir / 'nav.css').copyfile(outputDir / 'nav.css')
            # Incluide eXe's icon if the Style doesn't have one
            themePath = Path(G.application.config.stylesDir / package.style)
            themeFavicon = themePath.joinpath("favicon.ico")
            if not themeFavicon.exists():
                faviconFile = (self.imagesDir / 'favicon.ico')
                faviconFile.copyfile(outputDir / 'favicon.ico')
        if hasattr(package, 'exportSource') and package.exportSource:
            (G.application.config.webDir / 'templates' /
             'content.xsd').copyfile(outputDir / 'content.xsd')
            (outputDir / 'content.data').write_bytes(encodeObject(package))
            (outputDir / 'contentv3.xml').write_bytes(
                encodeObjectToXML(package))

        # Zip it up!
        self.filename.safeSave(
            self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'),
            outputDir)
        # Clean up the temporary dir
        outputDir.rmtree()

        return modifiedMetaData
class SinglePageExport(object):
    """
    SinglePageExport will export a package as a website of HTML pages
    """
    def __init__(self, stylesDir, outputDir, imagesDir, scriptsDir, cssDir,
                 templatesDir):
        """
        'stylesDir' is the directory where we can copy the stylesheets from
        'outputDir' is the directory that will be [over]written
        with the website
        """
        self.html = ""
        self.style = None
        self.name = None
        self.stylesDir = Path(stylesDir)
        self.outputDir = Path(outputDir)
        self.imagesDir = Path(imagesDir)
        self.scriptsDir = Path(scriptsDir)
        self.cssDir = Path(cssDir)
        self.templatesDir = Path(templatesDir)
        self.page = None

        # Create the output dir if it doesn't already exist
        if not self.outputDir.exists():
            self.outputDir.mkdir()

    def export(self, package, for_print=0):
        """ 
        Export web site
        Cleans up the previous packages pages and performs the export
        """
        self.style = package.style

        self.page = SinglePage("index", 1, package.root)
        ext = 'html'
        if G.application.config.cutFileName == "1":
            ext = 'htm'

        self.page.save(self.outputDir / "index" + '.' + ext, for_print)
        if hasattr(package,
                   'exportSource') and package.exportSource and not for_print:
            (G.application.config.webDir / 'templates' /
             'content.xsd').copyfile(self.outputDir / 'content.xsd')
            (self.outputDir / 'content.data').write_bytes(
                encodeObject(package))
            (self.outputDir / 'contentv3.xml').write_bytes(
                encodeObjectToXML(package))

        self.copyFiles(package)

    def copyFiles(self, package):
        """
        Copy all the files used by the website.
        """
        # Copy the style files to the output dir
        # But not nav.css
        if os.path.isdir(self.stylesDir):
            styleFiles = [self.stylesDir / '..' / 'popup_bg.gif']
            styleFiles += self.stylesDir.files("*.*")
            if "nav.css" in styleFiles:
                styleFiles.remove("nav.css")
            self.stylesDir.copylist(styleFiles, self.outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(self.outputDir)

        listCSSFiles = getFilesCSSToMinify('singlepage', self.stylesDir)
        exportMinFileCSS(listCSSFiles, self.outputDir)

        # copy script files.
        my_style = G.application.config.styleStore.getStyle(package.style)

        # jQuery
        if my_style.hasValidConfig:
            if my_style.get_jquery() == True:
                jsFile = (self.scriptsDir / 'exe_jquery.js')
                jsFile.copyfile(self.outputDir / 'exe_jquery.js')
        else:
            jsFile = (self.scriptsDir / 'exe_jquery.js')
            jsFile.copyfile(self.outputDir / 'exe_jquery.js')

        dT = common.getExportDocType()
        if dT == "HTML5":
            jsFile = (self.scriptsDir / 'exe_html5.js')
            jsFile.copyfile(self.outputDir / 'exe_html5.js')

        # Minify common.js file
        listFiles = getFilesJSToMinify('singlepage', self.scriptsDir)
        exportMinFileJS(listFiles, self.outputDir)

        # Incluide eXe's icon if the Style doesn't have one
        themePath = Path(G.application.config.stylesDir / package.style)
        themeFavicon = themePath.joinpath("favicon.ico")
        if not themeFavicon.exists():
            faviconFile = (self.imagesDir / 'favicon.ico')
            faviconFile.copyfile(self.outputDir / 'favicon.ico')

        #JR Metemos los reproductores necesarios
        self.compruebaReproductores(self.page.node)

        if package.license == "license GFDL":
            # include a copy of the GNU Free Documentation Licence
            ext = 'html'
            if G.application.config.cutFileName == "1":
                ext = 'htm'
            (self.templatesDir / 'fdl' + '.' +
             ext).copyfile(self.outputDir / 'fdl' + '.' + ext)

    def compruebaReproductores(self, node):
        """
        Comprobamos si hay que meter algun reproductor
        """

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        hasGallery = False
        hasFX = False
        hasSH = False
        hasGames = False
        hasWikipedia = False
        hasInstructions = False
        hasMediaelement = False
        hasTooltips = False
        hasABCMusic = False

        for idevice in node.idevices:
            if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery
                    and hasFX and hasSH and hasGames and hasWikipedia
                    and hasInstructions and hasMediaelement and hasTooltips
                    and hasABCMusic):
                break
            if not hasFlowplayer:
                if 'flowPlayer.swf' in idevice.systemResources:
                    hasFlowplayer = True
            if not hasMagnifier:
                if 'mojomagnify.js' in idevice.systemResources:
                    hasMagnifier = True
            if not hasXspfplayer:
                if 'xspf_player.swf' in idevice.systemResources:
                    hasXspfplayer = True
            if not hasGallery:
                hasGallery = common.ideviceHasGallery(idevice)
            if not hasFX:
                hasFX = common.ideviceHasFX(idevice)
            if not hasSH:
                hasSH = common.ideviceHasSH(idevice)
            if not hasGames:
                hasGames = common.ideviceHasGames(idevice)
            if not hasWikipedia:
                if 'WikipediaIdevice' == idevice.klass:
                    hasWikipedia = True
            if not hasInstructions:
                if 'TrueFalseIdevice' == idevice.klass or 'MultichoiceIdevice' == idevice.klass or 'VerdaderofalsofpdIdevice' == idevice.klass or 'EleccionmultiplefpdIdevice' == idevice.klass:
                    hasInstructions = True
            if not hasMediaelement:
                hasMediaelement = common.ideviceHasMediaelement(idevice)
            if not hasTooltips:
                hasTooltips = common.ideviceHasTooltips(idevice)
            if not hasABCMusic:
                hasABCMusic = common.ideviceHasABCMusic(idevice)

        if hasFlowplayer:
            videofile = (self.templatesDir / 'flowPlayer.swf')
            videofile.copyfile(self.outputDir / 'flowPlayer.swf')
            controlsfile = (self.templatesDir / 'flowplayer.controls.swf')
            controlsfile.copyfile(self.outputDir / 'flowplayer.controls.swf')
        if hasMagnifier:
            videofile = (self.templatesDir / 'mojomagnify.js')
            videofile.copyfile(self.outputDir / 'mojomagnify.js')
        if hasXspfplayer:
            videofile = (self.templatesDir / 'xspf_player.swf')
            videofile.copyfile(self.outputDir / 'xspf_player.swf')
        if hasGallery:
            exeLightbox = (self.scriptsDir / 'exe_lightbox')
            exeLightbox.copyfiles(self.outputDir)
        if hasFX:
            exeEffects = (self.scriptsDir / 'exe_effects')
            exeEffects.copyfiles(self.outputDir)
        if hasSH:
            exeSH = (self.scriptsDir / 'exe_highlighter')
            exeSH.copyfiles(self.outputDir)
        if hasGames:
            exeGames = (self.scriptsDir / 'exe_games')
            exeGames.copyfiles(self.outputDir)
        if hasWikipedia:
            wikipediaCSS = (self.cssDir / 'exe_wikipedia.css')
            wikipediaCSS.copyfile(self.outputDir / 'exe_wikipedia.css')
        if hasInstructions:
            common.copyFileIfNotInStyle('panel-amusements.png', self,
                                        self.outputDir)
            common.copyFileIfNotInStyle('stock-stop.png', self, self.outputDir)
        if hasMediaelement:
            mediaelement = (self.scriptsDir / 'mediaelement')
            mediaelement.copyfiles(self.outputDir)
            dT = common.getExportDocType()
            if dT != "HTML5":
                jsFile = (self.scriptsDir / 'exe_html5.js')
                jsFile.copyfile(self.outputDir / 'exe_html5.js')
        if hasTooltips:
            exe_tooltips = (self.scriptsDir / 'exe_tooltips')
            exe_tooltips.copyfiles(self.outputDir)
        if hasABCMusic:
            pluginScripts = (self.scriptsDir /
                             'tinymce_4/js/tinymce/plugins/abcmusic/export')
            pluginScripts.copyfiles(self.outputDir)

        for child in node.children:
            self.compruebaReproductores(child)

    def hasUncutResources(self):
        """
        Check if any of the resources in the exported package has an uncut filename
        """
        for idevice in self.page.node.idevices:
            for resource in idevice.userResources:
                if type(resource) == Resource and len(
                        resource.storageName) > 12:
                    return True
        return False
Beispiel #56
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 #57
0
class WinConfig(Config):
    """
    The WinConfig overrides the Config class with Windows specific
    configuration
    """
    def _overrideDefaultVals(self):
        """Sets the default values
        for windows"""
        self.exePath = Path(sys.argv[0]).abspath()
        if not self.exePath.exists():
            self.exePath = Path(self.exePath + ".exe")
        exeDir = self.exePath.dirname()
        self.dataDir = Path(self.__getWinFolder(MYDOCUMENTS))
        self.lastDir = Path(self.__getWinFolder(MYDOCUMENTS))
        self.configDir = Path(self.__getWinFolder(APPDATA)) / 'exe'
        self.stylesDir = Path(self.configDir) / 'style'

        self.videoMediaConverter_ogv = ""
        self.videoMediaConverter_3gp = 'ffmpeg -i %(infile)s -s qcif -vcodec h263 -acodec libvo_aacenc -ac 1 -ar 8000 -r 25 -ab 32 -y %(outfile)s'
        self.videoMediaConverter_mpg = "ffmpeg -i %(infile)s -s qcif -vcodec mpeg1 -acodec wav -ac 1 -ar 8000 -r 25 -ab 32 -y %(outfile)s"
        self.audioMediaConverter_au = "sox %(infile)s %(outfile)s"
        self.audioMediaConverter_wav = "sox %(infile)s %(outfile)s"
        self.audioMediaConverter_mp3 = "sox %(infile)s -t wav - | lame -b 32 - %(outfile)s"
        self.ffmpegPath = "ffmpeg"

    def _getConfigPathOptions(self):
        """
        Returns the best options for the
        location of the config file under windows
        """
        # Find out where our nice config file is
        folders = map(self.__getWinFolder, [APPDATA, COMMON_APPDATA])
        # Add unique dir names
        folders = [folder / 'exe' for folder in folders]
        folders.append(self.__getInstallDir())
        folders.append('.')
        # Filter out non existant folders
        options = [folder / 'exe.conf' for folder in map(Path, folders)]
        return options

    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 __getInstallDir(self):
        """
        Returns the path to where we were installed
        """
        from _winreg import OpenKey, QueryValue, HKEY_LOCAL_MACHINE
        try:
            exeKey = None
            softwareKey = None
            try:
                softwareKey = OpenKey(HKEY_LOCAL_MACHINE, 'SOFTWARE')
                exeKey = OpenKey(softwareKey, 'exe')
                return Path(QueryValue(exeKey, ''))
            finally:
                if exeKey:
                    exeKey.Close()
                if softwareKey:
                    softwareKey.Close()
        except WindowsError:
            return Path('')

    def getLongPathName(self, path):
        """
        Convert from Win32 short pathname to long pathname
        """
        from ctypes import windll, create_unicode_buffer
        buf = create_unicode_buffer(260)
        r = windll.kernel32.GetLongPathNameW(unicode(path), buf, 260)
        if r == 0 or r > 260:
            return path
        else:
            return buf.value
Beispiel #58
0
class SinglePageExport(object):
    """
    SinglePageExport will export a package as a website of HTML pages
    """
    def __init__(self, stylesDir, outputDir, imagesDir, scriptsDir, templatesDir):
        """
        'stylesDir' is the directory where we can copy the stylesheets from
        'outputDir' is the directory that will be [over]written
        with the website
        """
        self.html         = ""
        self.style        = None
        self.name         = None
        self.stylesDir    = Path(stylesDir)
        self.outputDir    = Path(outputDir)
        self.imagesDir    = Path(imagesDir)
        self.scriptsDir   = Path(scriptsDir)
        self.templatesDir = Path(templatesDir)
	self.page         = None

        # Create the output dir if it doesn't already exist
        if not self.outputDir.exists(): 
            self.outputDir.mkdir()


    def export(self, package, for_print=0):
        """ 
        Export web site
        Cleans up the previous packages pages and performs the export
        """
        self.style = package.style       
	
	self.page = SinglePage("index", 1, package.root)

        self.page.save(self.outputDir/"index.html", for_print)
	
	self.copyFiles(package)


    def copyFiles(self, package):
        """
        Copy all the files used by the website.
        """
        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles  = [self.stylesDir/'..'/'base.css']
	styleFiles += [self.stylesDir/'..'/'popup_bg.gif']
        styleFiles += self.stylesDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.stylesDir.files("*.jpg")
        styleFiles += self.stylesDir.files("*.gif")
        styleFiles += self.stylesDir.files("*.png")
        styleFiles += self.stylesDir.files("*.js")
        styleFiles += self.stylesDir.files("*.html")
        self.stylesDir.copylist(styleFiles, self.outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(self.outputDir)

        # copy script files. - modification by lernmodule.net
        self.scriptsDir.copylist(('libot_drag.js', 'common.js','lernmodule_net.js'), 
                                     self.outputDir)
	
	# copy players for media idevices.                
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False

	for idevice in self.page.node.idevices:
	    if (hasFlowplayer and hasMagnifier and hasXspfplayer):
		break
	    if not hasFlowplayer:
		if 'flowPlayer.swf' in idevice.systemResources:
		    hasFlowplayer = True
	    if not hasMagnifier:
		if 'magnifier.swf' in idevice.systemResources:
		    hasMagnifier = True
	    if not hasXspfplayer:
		if 'xspf_player.swf' in idevice.systemResources:
		    hasXspfplayer = True
                        
        if hasFlowplayer:
            videofile = (self.templatesDir/'flowPlayer.swf')
            videofile.copyfile(self.outputDir/'flowPlayer.swf')
        if hasMagnifier:
            videofile = (self.templatesDir/'magnifier.swf')
            videofile.copyfile(self.outputDir/'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(self.outputDir/'xspf_player.swf')


        if package.license == "GNU Free Documentation License":
            # include a copy of the GNU Free Documentation Licence
            (self.templatesDir/'fdl.html').copyfile(self.outputDir/'fdl.html')