示例#1
0
    def testExport(self):
        # Delete the output dir
        outdir = TempDirPath()

        G.application = Application()

        G.application.loadConfiguration()
        G.application.preLaunch()

        # Load a package
        package = Package.load('testing/testPackage2.elp')
        # Do the export
        style_dir = G.application.config.stylesDir / package.style

        exporter = WebsiteExport(G.application.config, style_dir, outdir)

        exporter.export(package)
        # Check that it all exists now
        assert outdir.isdir()
        assert (outdir / 'index.html').isfile()
        # Check that the style sheets have been copied
        for filename in style_dir.files():
            assert ((outdir / filename.basename()).exists(),
                    'Style file "%s" not copied' %
                    (outdir / filename.basename()))

        # Check that each node in the package has had a page made
        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, outdir)
示例#2
0
 def export(self, package):
     """ 
     Export SCORM package
     """
     outputDir = TempDirPath()
     styleFiles  = [self.styleDir/'..'/'base.css']
     styleFiles += [self.styleDir/'..'/'popup_bg.gif']
     styleFiles += self.styleDir.files("*.css")
     if "nav.css" in styleFiles:
         styleFiles.remove("nav.css")
     styleFiles += self.styleDir.files("*.jpg")
     styleFiles += self.styleDir.files("*.gif")
     styleFiles += self.styleDir.files("*.png")
     styleFiles += self.styleDir.files("*.js")
     styleFiles += self.styleDir.files("*.html")
     self.styleDir.copylist(styleFiles, outputDir)
     package.resourceDir.copyfiles(outputDir)
     self.pages = [ IMSPage("index", 1, package.root) ]
     self.generatePages(package.root, 2)
     uniquifyNames(self.pages)
     for page in self.pages:
         page.save(outputDir)
     manifest = Manifest(self.config, outputDir, package, self.pages)
     manifest.save()
     self.scriptsDir.copylist(('libot_drag.js',
                               'common.js'), outputDir)
     self.schemasDir.copylist(('imscp_v1p1.xsd',
                               'imsmd_v1p2p2.xsd',
                               'ims_xml.xsd'), outputDir)
     self.templatesDir.copylist(('videoContainer.swf', 'magnifier.swf',
                                 'xspf_player.swf'),outputDir)
     (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
     self.filename.safeSave(self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'), outputDir)
     outputDir.rmtree()
示例#3
0
    def exportZip(self, package):
	""" 
        Export web site
        Cleans up the previous packages pages and performs the export
        """
	
	outputDir = TempDirPath()
        self.copyFiles(package, outputDir)
        if (self.stylesDir/"websitepage.py").exists():
            global WebsitePage
            module = imp.load_source("websitepage", 
                                     self.stylesDir/"websitepage.py")
            WebsitePage = module.WebsitePage
        self.pages = [ WebsitePage("index", 1, package.root) ]
        self.generatePages(package.root, 1)
        uniquifyNames(self.pages)
        prevPage = None
        thisPage = self.pages[0]
        for nextPage in self.pages[1:]:
            thisPage.save(outputDir, prevPage, nextPage, self.pages)
            prevPage = thisPage
            thisPage = nextPage
        thisPage.save(outputDir, prevPage, None, self.pages)
	
        zipped = ZipFile(self.filename, "w")
        for scormFile in outputDir.files():
            zipped.write(scormFile,
                         scormFile.basename().encode('utf8'),
                         ZIP_DEFLATED)
        zipped.close()
        outputDir.rmtree()
    def testExport(self):
        # Delete the output dir
        outdir = TempDirPath()
        # Load a package
        package = Package.load('testPackage.elp')
        # Do the export
        exporter = WebsiteExport('../exe/webui/style/default', 
                                 outdir,
                                 '../exe/webui/images', 
                                 '../exe/webui/scripts',
                                 '../exe/webui/templates')
        exporter.export(package)
        # Check that it all exists now
        assert outdir.isdir()
        assert (outdir / 'index.html').isfile()
        # Check that the style sheets have been copied
        for filename in Path('../exe/webui/style/default').files():
            assert ((outdir / filename.basename()).exists(),
                    'Style file "%s" not copied' % (outdir / filename.basename()))

        # Check that each node in the package has had a page made
        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, outdir)
    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId    = 0
        # For looking up nodes by ids
        self._nodeIdDict    = {} 

        self._levelNames    = self.defaultLevelNames[:]
        self.name           = name
        self._title         = u''
        self._backgroundImg = u''
        self.backgroundImgTile = False

        # Empty if never saved/loaded
        self.filename      = u''

        self.root          = Node(self, None, _(u"Home"))
        self.currentNode   = self.root
        self.style         = u"default"
        self.isChanged     = False
        self.idevices      = []
        self.dublinCore    = DublinCore()
        self.scolinks      = False
        self.license       = "None"
        self.footer        = ""

        # Temporary directory to hold resources in
        self.resourceDir = TempDirPath()
        self.resources = {} # Checksum-[_Resource(),..]
示例#6
0
    def testExport(self):
        # Delete the output dir
        outdir = TempDirPath()
        
        G.application = Application()
        
        G.application.loadConfiguration()
        G.application.preLaunch()
        
        # Load a package
        package = Package.load('testing/testPackage2.elp')
        # Do the export
        style_dir = G.application.config.stylesDir / package.style
        
        exporter = WebsiteExport(G.application.config,
                                 style_dir, 
                                 outdir)
        
        exporter.export(package)
        # Check that it all exists now
        assert outdir.isdir()
        assert (outdir / 'index.html').isfile()
        # Check that the style sheets have been copied
        for filename in style_dir.files():
            assert ((outdir / filename.basename()).exists(),
                    'Style file "%s" not copied' % (outdir / filename.basename()))

        # Check that each node in the package has had a page made
        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, outdir)
示例#7
0
    def exportZip(self, package):
        """ 
        Export web site
        Cleans up the previous packages pages and performs the export
        """
        
        outputDir = TempDirPath()

        # Import the Website Page class.  If the style has it's own page class
        # use that, else use the default one.
        if (self.stylesDir/"websitepage.py").exists():
            global WebsitePage
            module = imp.load_source("websitepage", 
                                     self.stylesDir/"websitepage.py")
            WebsitePage = module.WebsitePage

        self.pages = [ WebsitePage("index", 1, package.root) ]
        self.generatePages(package.root, 1)
        uniquifyNames(self.pages)

        prevPage = None
        thisPage = self.pages[0]

        for nextPage in self.pages[1:]:
            thisPage.save(outputDir, prevPage, nextPage, self.pages)
            prevPage = thisPage
            thisPage = nextPage
            

        thisPage.save(outputDir, prevPage, None, self.pages)
        self.copyFiles(package, outputDir)
        # Zip up the website package
        self.filename.safeSave(self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'), outputDir)
        # Clean up the temporary dir
        outputDir.rmtree()
示例#8
0
 def export(self, package):
     """ 
     Export SCORM package
     """
     outputDir = TempDirPath()
     styleFiles  = [self.styleDir/'..'/'base.css']
     styleFiles += [self.styleDir/'..'/'popup_bg.gif']
     styleFiles += self.styleDir.files("*.css")
     if "nav.css" in styleFiles:
         styleFiles.remove("nav.css")
     styleFiles += self.styleDir.files("*.jpg")
     styleFiles += self.styleDir.files("*.gif")
     styleFiles += self.styleDir.files("*.png")
     styleFiles += self.styleDir.files("*.js")
     styleFiles += self.styleDir.files("*.html")
     self.styleDir.copylist(styleFiles, outputDir)
     package.resourceDir.copyfiles(outputDir)
     self.pages = [ ScormPage("index", 1, package.root) ]
     self.generatePages(package.root, 2)
     uniquifyNames(self.pages)
     for page in self.pages:
         page.save(outputDir)
         if not self.hasForum:
             for idevice in page.node.idevices:
                 if hasattr(idevice, "isForum"):
                     if idevice.forum.lms.lms == "moodle":
                         self.hasForum = True
                         break
     manifest = Manifest(self.config, outputDir, package, self.pages, self.scormType)
     manifest.save("imsmanifest.xml")
     if self.hasForum:
         manifest.save("discussionforum.xml")
     self.scriptsDir.copylist(('APIWrapper.js', 
                               'imscp_rootv1p1p2.xsd',
                               'imsmd_rootv1p2p1.xsd',
                               'ims_xml.xsd',
                               'adlcp_rootv1p2.xsd',
                               'SCOFunctions.js', 
                               'libot_drag.js',
                               'common.js'), outputDir)
     self.templatesDir.copylist(('videoContainer.swf', 'magnifier.swf',
                                 'xspf_player.swf'),outputDir)
     (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
     zipped = ZipFile(self.filename, "w")
     for scormFile in outputDir.files():
         zipped.write(scormFile,
                      scormFile.basename().encode('utf8'),
                      ZIP_DEFLATED)
     zipped.close()
     outputDir.rmtree()
示例#9
0
 def __init__(self, name):
     """
     Initialize 
     """
     log.debug(u"init " + repr(name))
     self._nextIdeviceId = 0
     self._nextNodeId    = 0
     self._nodeIdDict    = {} 
     self._levelNames    = self.defaultLevelNames[:]
     self.name           = name
     self._title         = u''
     self._backgroundImg = u''
     self.backgroundImgTile = False
     self.filename      = u''
     self.root          = Node(self, None, _(u"Home"))
     self.currentNode   = self.root
     self.style         = u"default"
     self.isChanged     = False
     self.idevices      = []
     self.dublinCore    = DublinCore()
     self.scolinks      = False
     self.license       = "None"
     self.footer        = ""
     self.resourceDir = TempDirPath()
     self.resources = {} # Checksum-[_Resource(),..]
    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId = 0
        # For looking up nodes by ids
        self._nodeIdDict = {}

        self._levelNames = self.defaultLevelNames[:]
        self.name = name
        self._title = u""
        self._backgroundImg = u""
        self.backgroundImgTile = False

        # Empty if never saved/loaded
        self.filename = u""

        self.root = Node(self, None, _(u"Home"))
        self.currentNode = self.root
        self.style = u"default"
        self.isChanged = False
        self.idevices = []
        self.dublinCore = DublinCore()
        self.scolinks = False
        self.license = "None"
        self.footer = ""

        # Temporary directory to hold resources in
        self.resourceDir = TempDirPath()
        self.resources = {}  # Checksum-[_Resource(),..]
示例#11
0
 def testExport(self):
     outdir = TempDirPath()
     package = Package.load('testPackage.elp')
     exporter = WebsiteExport('../exe/webui/style/default', 
                              outdir,
                              '../exe/webui/images', 
                              '../exe/webui/scripts',
                              '../exe/webui/templates')
     exporter.export(package)
     assert outdir.isdir()
     assert (outdir / 'index.html').isfile()
     for filename in Path('../exe/webui/style/default').files():
         assert ((outdir / filename.basename()).exists(),
                 'Style file "%s" not copied' % (outdir / filename.basename()))
     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, outdir)
示例#12
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        outputDir = TempDirPath()
	styleFiles  = [self.styleDir/'..'/'base.css']
	styleFiles += [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        self.styleDir.copylist(styleFiles, outputDir)
        package.resourceDir.copyfiles(outputDir)
        self.pages = [ IMSPage("index", 1, package.root) ]
        self.generatePages(package.root, 2)
        uniquifyNames(self.pages)
        for page in self.pages:
            page.save(outputDir)
        manifest = Manifest(self.config, outputDir, package, self.pages)
        manifest.save()
        self.scriptsDir.copylist(('libot_drag.js',
                                  'imscp_v1p1.xsd',
                                  'imsmd_v1p2p2.xsd',
                                  'ims_xml.xsd',
                                  'common.js'), outputDir)
        self.templatesDir.copylist(('videoContainer.swf', 'magnifier.swf',
                                    'xspf_player.swf'),outputDir)
        (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
        zipped = ZipFile(self.filename, "w")
        for scormFile in outputDir.files():
            zipped.write(scormFile,
                         scormFile.basename().encode('utf8'),
                         ZIP_DEFLATED)
        zipped.close()
        outputDir.rmtree()
示例#13
0
 def __init__(self, name):
     """
     Initialize 
     """
     log.debug(u"init " + repr(name))
     self._nextIdeviceId = 0
     self._nextNodeId    = 0
     self._nodeIdDict    = {} 
     self._levelNames    = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]
     self.name           = name
     self._title         = u''
     self.filename      = u''
     self.root          = Node(self, None, _(u"Home"))
     self.currentNode   = self.root
     self.style         = u"default"
     self.isChanged     = 0
     self.idevices      = []
     self.dublinCore    = DublinCore()
     self.resourceDir = TempDirPath()
示例#14
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

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

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

        for page in self.pages:
            page.save(outputDir)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / '..' / 'base.css']
        styleFiles += [self.styleDir / '..' / 'popup_bg.gif']
        styleFiles += [
            f for f in self.styleDir.files("*.css")
            if f.basename() <> "nav.css"
        ]
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        # 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
        if self.scormType == "commoncartridge":
            for sf in styleFiles[:]:
                if sf.basename() not in manifest.dependencies:
                    styleFiles.remove(sf)
        self.styleDir.copylist(styleFiles, outputDir)

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

        # Copy the scripts
        if self.scormType == "commoncartridge":
            self.scriptsDir.copylist(('libot_drag.js', 'common.js'), outputDir)
        else:
            self.scriptsDir.copylist(('APIWrapper.js', 'SCOFunctions.js',
                                      'libot_drag.js', 'common.js'), outputDir)
        schemasDir = ""
        if self.scormType == "scorm1.2":
            schemasDir = self.schemasDir / "scorm1.2"
            schemasDir.copylist(
                ('imscp_rootv1p1p2.xsd', 'imsmd_rootv1p2p1.xsd',
                 'adlcp_rootv1p2.xsd', 'ims_xml.xsd'), outputDir)
        elif self.scormType == "scorm2004":
            schemasDir = self.schemasDir / "scorm2004"
            schemasDir.copylist(
                ('imscp_rootv1p1p2.xsd', 'imsmd_rootv1p2p1.xsd',
                 'adlcp_rootv1p2.xsd', 'ims_xml.xsd'), outputDir)

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        isBreak = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer):
                    isBreak = True
                    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(outputDir / 'flowPlayer.swf')
        if hasMagnifier:
            videofile = (self.templatesDir / 'magnifier.swf')
            videofile.copyfile(outputDir / 'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir / 'xspf_player.swf')
            videofile.copyfile(outputDir / 'xspf_player.swf')

        if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
            if package.license == "GNU Free Documentation License":
                # 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()
示例#15
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

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

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

        for page in self.pages:
            page.save(outputDir)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")
        
        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles  = [self.styleDir/'..'/'base.css']
        styleFiles += [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += [f for f in self.styleDir.files("*.css")
                if f.basename() <> "nav.css"] 
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        # 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
        if self.scormType == "commoncartridge":
            for sf in styleFiles[:]:
                if sf.basename() not in manifest.dependencies:
                    styleFiles.remove(sf)
        self.styleDir.copylist(styleFiles, outputDir)

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

        # Copy the scripts
        if self.scormType == "commoncartridge":
            self.scriptsDir.copylist(('libot_drag.js',
                                      'common.js'), outputDir)
        else:
            self.scriptsDir.copylist(('APIWrapper.js', 
                                      'SCOFunctions.js', 
                                      'libot_drag.js',
                                      'common.js'), outputDir)
        schemasDir = ""
        if self.scormType == "scorm1.2":
            schemasDir = self.schemasDir/"scorm1.2"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                'imsmd_rootv1p2p1.xsd',
                                'adlcp_rootv1p2.xsd',
                                'ims_xml.xsd'), outputDir)
        elif self.scormType == "scorm2004":
            schemasDir = self.schemasDir/"scorm2004"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                'imsmd_rootv1p2p1.xsd',
                                'adlcp_rootv1p2.xsd',
                                'ims_xml.xsd'), outputDir)
 

        # copy players for media idevices.                
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False
        isBreak           = False
        
        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer):
                    isBreak = True
                    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(outputDir/'flowPlayer.swf')
        if hasMagnifier:
            videofile = (self.templatesDir/'magnifier.swf')
            videofile.copyfile(outputDir/'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(outputDir/'xspf_player.swf')

        if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
            if package.license == "GNU Free Documentation License":
                # 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()
示例#16
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()
示例#17
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
        package.resourceDir.copyfiles(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)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")

        # Copy the style sheet files to the output dir
        styleFiles = [self.styleDir / ".." / "base.css"]
        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)

        # Copy the scripts
        dT = common.getExportDocType()
        if dT == "HTML5":
            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:
                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")

        if self.scormType == "commoncartridge":
            jsFile = self.scriptsDir / "common.js"
            jsFile.copyfile(outputDir / "common.js")

        if self.scormType == "scorm2004" or self.scormType == "scorm1.2":
            self.scriptsDir.copylist(("SCORM_API_wrapper.js", "SCOFunctions.js", "common.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
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasMediaelement = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (
                    hasFlowplayer
                    and hasMagnifier
                    and hasXspfplayer
                    and hasGallery
                    and hasWikipedia
                    and hasInstructions
                    and hasMediaelement
                ):
                    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 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 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:
            imageGalleryCSS = self.cssDir / "exe_lightbox.css"
            imageGalleryCSS.copyfile(outputDir / "exe_lightbox.css")
            imageGalleryJS = self.scriptsDir / "exe_lightbox.js"
            imageGalleryJS.copyfile(outputDir / "exe_lightbox.js")
            self.imagesDir.copylist(
                (
                    "exe_lightbox_close.png",
                    "exe_lightbox_loading.gif",
                    "exe_lightbox_next.png",
                    "exe_lightbox_prev.png",
                ),
                outputDir,
            )
        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 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.html").copyfile(outputDir / "fdl.html")

        if hasattr(package, "scowsinglepage") and package.scowsinglepage:
            page = SinglePage("singlepage_index", 1, package.root)
            page.save(outputDir / "singlepage_index.html")
            # 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()
示例#18
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)
            if hasattr(page, 'cover'):
                cover = page.cover

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

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / '..' / 'base.css']
        styleFiles += [self.styleDir / '..' / 'popup_bg.gif']
        styleFiles += [f for f in self.styleDir.files("*.css") if f.basename() != "nav.css"]
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        # 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

        package.resourceDir.copyfiles(contentPages)

        self.styleDir.copylist(styleFiles, contentPages)
        self.scriptsDir.copylist(('common.js',), contentPages)

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        hasGallery = False
        hasFX = False
        hasGames = False
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasTooltips = 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 hasGames and hasWikipedia):
                    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 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 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 hasGames:
            exeGames = (self.scriptsDir / 'exe_games')
            exeGames.copyfiles(contentPages)
        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)

        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')

#         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()
class Package(Persistable):
    """
    Package represents the collection of resources the user is editing
    i.e. the "package".
    """

    persistenceVersion = 9
    nonpersistant = ["resourceDir", "filename"]
    # Name is used in filenames and urls (saving and navigating)
    _name = ""
    tempFile = False  # This is set when the package is saved as a temp copy file
    # Title is rendered in exports
    _title = ""
    _author = ""
    _description = ""
    _backgroundImg = ""
    # This is like a constant
    defaultLevelNames = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]

    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId = 0
        # For looking up nodes by ids
        self._nodeIdDict = {}

        self._levelNames = self.defaultLevelNames[:]
        self.name = name
        self._title = u""
        self._backgroundImg = u""
        self.backgroundImgTile = False

        # Empty if never saved/loaded
        self.filename = u""

        self.root = Node(self, None, _(u"Home"))
        self.currentNode = self.root
        self.style = u"default"
        self.isChanged = False
        self.idevices = []
        self.dublinCore = DublinCore()
        self.scolinks = False
        self.license = "None"
        self.footer = ""

        # Temporary directory to hold resources in
        self.resourceDir = TempDirPath()
        self.resources = {}  # Checksum-[_Resource(),..]

    # Property Handlers

    def set_name(self, value):
        self._name = toUnicode(value)

    def set_title(self, value):
        self._title = toUnicode(value)

    def set_author(self, value):
        self._author = toUnicode(value)

    def set_description(self, value):
        self._description = toUnicode(value)

    def get_backgroundImg(self):
        """Get the background image for this package"""
        if self._backgroundImg:
            return "file://" + self._backgroundImg.path
        else:
            return ""

    def set_backgroundImg(self, value):
        """Set the background image for this package"""
        if self._backgroundImg:
            self._backgroundImg.delete()

        if value:
            if value.startswith("file://"):
                value = value[7:]

            imgFile = Path(value)
            self._backgroundImg = Resource(self, Path(imgFile))
        else:
            self._backgroundImg = u""

    def get_level1(self):
        return self.levelName(0)

    def set_level1(self, value):
        if value != "":
            self._levelNames[0] = value
        else:
            self._levelNames[0] = self.defaultLevelNames[0]

    def get_level2(self):
        return self.levelName(1)

    def set_level2(self, value):
        if value != "":
            self._levelNames[1] = value
        else:
            self._levelNames[1] = self.defaultLevelNames[1]

    def get_level3(self):
        return self.levelName(2)

    def set_level3(self, value):
        if value != "":
            self._levelNames[2] = value
        else:
            self._levelNames[2] = self.defaultLevelNames[2]

    # Properties

    name = property(lambda self: self._name, set_name)
    title = property(lambda self: self._title, set_title)
    author = property(lambda self: self._author, set_author)
    description = property(lambda self: self._description, set_description)

    backgroundImg = property(get_backgroundImg, set_backgroundImg)

    level1 = property(get_level1, set_level1)
    level2 = property(get_level2, set_level2)
    level3 = property(get_level3, set_level3)

    def findNode(self, nodeId):
        """
        Finds a node from its nodeId
        (nodeId can be a string or a list/tuple)
        """
        log.debug(u"findNode" + repr(nodeId))
        node = self._nodeIdDict.get(nodeId)
        if node and node.package is self:
            return node
        else:
            return None

    def levelName(self, level):
        """
        Return the level name
        """
        if level < len(self._levelNames):
            return _(self._levelNames[level])
        else:
            return _(u"?????")

    def save(self, filename=None, tempFile=False):
        """
        Save package to disk
        pass an optional filename
        """
        self.tempFile = tempFile
        # Get the filename
        if filename:
            filename = Path(filename)
            # If we are being given a new filename...
            # Change our name to match our new filename
            name = filename.splitpath()[1]
            if not tempFile:
                self.name = name.basename().splitext()[0]
        elif self.filename:
            # Otherwise use our last saved/loaded from filename
            filename = Path(self.filename)
        else:
            # If we don't have a last saved/loaded from filename,
            # raise an exception because, we need to have a new
            # file passed when a brand new package is saved
            raise AssertionError(u"No name passed when saving a new package")
        # Store our new filename for next file|save, and save the package
        log.debug(u"Will save %s to: %s" % (self.name, filename))
        if tempFile:
            self.nonpersistant.remove("filename")
            oldFilename, self.filename = self.filename, unicode(self.filename)
            try:
                filename.safeSave(self.doSave, _("SAVE FAILED!\nLast succesful save is %s."))
            finally:
                self.nonpersistant.append("filename")
                self.filename = oldFilename
        else:
            # Update our new filename for future saves
            self.filename = filename
            filename.safeSave(self.doSave, _("SAVE FAILED!\nLast succesful save is %s."))
            self.isChanged = False
            self.updateRecentDocuments(filename)

    def updateRecentDocuments(self, filename):
        """
        Updates the list of recent documents
        """
        # Don't update the list for the generic.data "package"
        genericData = G.application.config.configDir / "idevices" / "generic.data"
        if genericData.isfile() or genericData.islink():
            if Path(filename).samefile(genericData):
                return
        # Save in recentDocuments list
        recentProjects = G.application.config.recentProjects
        if filename in recentProjects:
            # If we're already number one, carry on
            if recentProjects[0] == filename:
                return
            recentProjects.remove(filename)
        recentProjects.insert(0, filename)
        del recentProjects[5:]  # Delete any older names from the list
        G.application.config.configParser.write()  # Save the settings

    def doSave(self, fileObj):
        """
        Actually performs the save to 'fileObj'.
        """
        zippedFile = zipfile.ZipFile(fileObj, "w", zipfile.ZIP_DEFLATED)
        try:
            for resourceFile in self.resourceDir.files():
                zippedFile.write(
                    unicode(resourceFile.normpath()), resourceFile.name.encode("utf8"), zipfile.ZIP_DEFLATED
                )

            zinfo = zipfile.ZipInfo(filename="content.data", date_time=time.localtime()[0:6])
            zinfo.external_attr = 0100644 << 16L
            zippedFile.writestr(zinfo, encodeObject(self))
        finally:
            zippedFile.close()

    def extractNode(self):
        """
        Clones and extracts the currently selected node into a new package.
        """
        newPackage = Package("NoName")  # Name will be set once it is saved..
        newPackage.title = self.currentNode.title
        newPackage.style = self.style
        newPackage.author = self.author
        newPackage._nextNodeId = self._nextNodeId
        # Copy the nodes from the original package
        # and merge into the root of the new package
        self.currentNode.copyToPackage(newPackage)
        return newPackage

    @staticmethod
    def load(filename, newLoad=True, destinationPackage=None):
        """
        Load package from disk, returns a package.
        """
        if not zipfile.is_zipfile(filename):
            return None

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

        try:
            # Get the jellied package data
            toDecode = zippedFile.read(u"content.data")
        except KeyError:
            log.info("no content.data, trying Common Cartridge/Content Package")
            newPackage = loadCC(zippedFile, filename)
            newPackage.tempFile = False
            newPackage.isChanged = False
            newPackage.filename = Path(filename)

            return newPackage

        # Need to add a TempDirPath because it is a nonpersistant member
        resourceDir = TempDirPath()

        # Extract resource files from package to temporary directory
        for fn in zippedFile.namelist():
            if unicode(fn, "utf8") != u"content.data":
                outFile = open(resourceDir / fn, "wb")
                outFile.write(zippedFile.read(fn))
                outFile.flush()
                outFile.close()

        try:
            newPackage = decodeObjectRaw(toDecode)
            G.application.afterUpgradeHandlers = []
            newPackage.resourceDir = resourceDir
            G.application.afterUpgradeZombies2Delete = []

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

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

                doUpgrade(newPackage)

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

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

                log.debug(
                    'load() about to merge doUpgrade newPackage "'
                    + newPackage._name
                    + '" '
                    + repr(newPackage)
                    + ' INTO destinationPackage "'
                    + destinationPackage._name
                    + '" '
                    + repr(destinationPackage)
                )

                log.debug("using their resourceDirs:")
                if hasattr(newPackage, "resourceDir"):
                    log.debug("   newPackage resourceDir = " + newPackage.resourceDir)
                else:
                    log.error("newPackage has NO resourceDir!")
                if hasattr(destinationPackage, "resourceDir"):
                    log.debug("   destinationPackage resourceDir = " + destinationPackage.resourceDir)
                else:
                    log.error("destinationPackage has NO resourceDir!")

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

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

        except:
            import traceback

            traceback.print_exc()
            raise

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

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

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

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

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

        G.application.afterUpgradeHandlers = []

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

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

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

    def cleanUpResources(self):
        """
        Removes duplicate resource files
        """
        # Delete unused resources.
        # Only really needed for upgrading to version 0.20,
        # but upgrading of resources and package happens in no particular order
        # and must be done after all resources have been upgraded

        # some earlier .elp files appear to have been corrupted with
        # two packages loaded, *possibly* from some strange extract/merge
        # functionality in earlier eXe versions?
        # Regardless, only the real package will have a resourceDir,
        # and the other will fail.
        # For now, then, put in this quick and easy safety check:
        if not hasattr(self, "resourceDir"):
            log.warn("cleanUpResources called on a redundant package")
            return

        existingFiles = set([fn.basename() for fn in self.resourceDir.files()])
        usedFiles = set([reses[0].storageName for reses in self.resources.values()])
        for fn in existingFiles - usedFiles:
            (self.resourceDir / fn).remove()

    def findResourceByName(self, queryName):
        """
        Support for merging, and anywhere else that unique names might be
        checked before actually comparing against the files (as will be 
        done by the resource class itself in its _addOurselvesToPackage() )
        """
        foundResource = None
        queryResources = self.resources
        for this_checksum in queryResources:
            for this_resource in queryResources[this_checksum]:
                if queryName == this_resource.storageName:
                    foundResource = this_resource
                    return foundResource
        return foundResource

    def upgradeToVersion1(self):
        """
        Called to upgrade from 0.3 release
        """
        self._nextNodeId = 0
        self._nodeIdDict = {}

        # Also upgrade all the nodes.
        # This needs to be done here so that draft gets id 0
        # If it's done in the nodes, the ids are assigned in reverse order
        draft = getattr(self, "draft")
        draft._id = self._regNewNode(draft)
        draft._package = self
        setattr(self, "editor", Node(self, None, _(u"iDevice Editor")))

        # Add a default idevice to the editor
        idevice = GenericIdevice("", "", "", "", "")
        editor = getattr(self, "editor")
        idevice.parentNode = editor
        editor.addIdevice(idevice)

        def superReg(node):
            """Registers all our nodes
            because in v0 they were not registered
            in this way"""
            node._id = self._regNewNode(node)
            node._package = self
            for child in node.children:
                superReg(child)

        superReg(self.root)

    def _regNewNode(self, node):
        """
        Called only by nodes, 
        stores the node in our id lookup dict
        returns a new unique id
        """
        id_ = unicode(self._nextNodeId)
        self._nextNodeId += 1
        self._nodeIdDict[id_] = node
        return id_

    def getNewIdeviceId(self):
        """
        Returns an iDevice Id which is unique for this package.
        """
        id_ = unicode(self._nextIdeviceId)
        self._nextIdeviceId += 1
        return id_

    def upgradeToVersion2(self):
        """
        Called to upgrade from 0.4 release
        """
        getattr(self, "draft").delete()
        getattr(self, "editor").delete()
        delattr(self, "draft")
        delattr(self, "editor")
        # Need to renumber nodes because idevice node and draft nodes are gone
        self._nextNodeId = 0

        def renumberNode(node):
            """
            Gives the old node a number
            """
            node._id = self._regNewNode(node)
            for child in node.children:
                renumberNode(child)

        renumberNode(self.root)

    def upgradeToVersion3(self):
        """
        Also called to upgrade from 0.4 release
        """
        self._nextIdeviceId = 0

    def upgradeToVersion4(self):
        """
        Puts properties in their place
        Also called to upgrade from 0.8 release
        """
        self._name = toUnicode(self.__dict__["name"])
        self._author = toUnicode(self.__dict__["author"])
        self._description = toUnicode(self.__dict__["description"])

    def upgradeToVersion5(self):
        """
        For version 0.11
        """
        self._levelNames = self.levelNames
        del self.levelNames

    def upgradeToVersion6(self):
        """
        For version 0.14
        """
        self.dublinCore = DublinCore()
        # Copy some of the package properties to dublin core
        self.title = self.root.title
        self.dublinCore.title = self.root.title
        self.dublinCore.creator = self._author
        self.dublinCore.description = self._description
        self.scolinks = False

    def upgradeToVersion7(self):
        """
        For version 0.15
        """
        self._backgroundImg = ""
        self.backgroundImgTile = False

    def upgradeToVersion8(self):
        """
        For version 0.20, alpha, for nightlies r2469
        """
        self.license = "None"
        self.footer = ""
        self.idevices = []

    def upgradeToVersion9(self):
        """
        For version >= 0.20.4
        """
        if not hasattr(self, "resources"):
            # The hasattr is needed, because sometimes, Resource instances are upgraded
            # first and they also set this attribute on the package
            self.resources = {}
        G.application.afterUpgradeHandlers.append(self.cleanUpResources)
示例#20
0
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]
        # Calc the svn branch name
        branch = 'http://exe.cfdl.auckland.ac.nz/svn/exe/branches/%s' % version
        # Get the original exe dir
        origDir = Path(sys.argv[0]).abspath().dirname()
        # Make the temp dir
        tmp = TempDirPath()
        os.chdir(tmp)
        # Do the export
        os.system('svn export %s exe' % branch)
        # Copy firefox accross
        (origDir/'../../exe/webui/firefox').copytree(tmp/'exe/exe/webui/firefox')
        # Now make the tarball
        os.chdir(tmp/'exe')
        tarball = Path('../exe-%s-source.tgz' % version).abspath()
        os.system('tar czf %s *' % tarball)
        os.chdir(tmp)
        # Upload it
        if '--local' not in sys.argv:
            # Connect with sftp
            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()
            # See that the directory structure looks good
            f.chdir('/home/pub/exe')
            f.put(tarball.encode('utf8'), tarball.basename().encode('utf8'))
        # If we're root, copy the tarball to the portage cache dir to save
        # downloading it when emerging (for me anyway)
        if os.getuid() == 0:
            tarball.copyfile('/usr/portage/distfiles/' + tarball.basename())
        # Copy the ebuild file
        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 we're root, rebuild the digests and remake the install
        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)
            # Copy the patch file
            filesDir = ebuildDir/'files'
            filesDir.makedirs()
            Path(tmp/'exe/installs/gentoo/all-config.patch').copy(filesDir)
            # Remove any old source if it exists and we're supposed to download
            # it
            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())
示例#21
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((Path(idevice._iDeviceDir)/'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
示例#22
0
 def export(self, package):
     """ 
     Export SCORM package
     """
     outputDir = TempDirPath()
     styleFiles = [self.styleDir / ".." / "base.css"]
     styleFiles += [self.styleDir / ".." / "popup_bg.gif"]
     styleFiles += self.styleDir.files("*.css")
     if "nav.css" in styleFiles:
         styleFiles.remove("nav.css")
     styleFiles += self.styleDir.files("*.jpg")
     styleFiles += self.styleDir.files("*.gif")
     styleFiles += self.styleDir.files("*.png")
     styleFiles += self.styleDir.files("*.js")
     styleFiles += self.styleDir.files("*.html")
     self.styleDir.copylist(styleFiles, outputDir)
     package.resourceDir.copyfiles(outputDir)
     self.pages = [ScormPage("index", 1, package.root, scormType=self.scormType)]
     self.generatePages(package.root, 2)
     uniquifyNames(self.pages)
     for page in self.pages:
         page.save(outputDir)
         if not self.hasForum:
             for idevice in page.node.idevices:
                 if hasattr(idevice, "isForum"):
                     if idevice.forum.lms.lms == "moodle":
                         self.hasForum = True
                         break
     manifest = Manifest(self.config, outputDir, package, self.pages, self.scormType)
     manifest.save("imsmanifest.xml")
     if self.hasForum:
         manifest.save("discussionforum.xml")
     self.scriptsDir.copylist(("APIWrapper.js", "SCOFunctions.js", "libot_drag.js", "common.js"), outputDir)
     schemasDir = ""
     if self.scormType == "scorm1.2":
         schemasDir = self.schemasDir / "scorm1.2"
         schemasDir.copylist(
             ("imscp_rootv1p1p2.xsd", "imsmd_rootv1p2p1.xsd", "adlcp_rootv1p2.xsd", "ims_xml.xsd"), outputDir
         )
     elif self.scormType == "scorm2004":
         schemasDir = self.schemasDir / "scorm2004"
         schemasDir.copylist(
             ("imscp_rootv1p1p2.xsd", "imsmd_rootv1p2p1.xsd", "adlcp_rootv1p2.xsd", "ims_xml.xsd"), outputDir
         )
     hasFlowplayer = False
     hasMagnifier = False
     hasXspfplayer = False
     isBreak = False
     for page in self.pages:
         if isBreak:
             break
         for idevice in page.node.idevices:
             if hasFlowplayer and hasMagnifier and hasXspfplayer:
                 isBreak = True
                 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(outputDir / "flowPlayer.swf")
     if hasMagnifier:
         videofile = self.templatesDir / "magnifier.swf"
         videofile.copyfile(outputDir / "magnifier.swf")
     if hasXspfplayer:
         videofile = self.templatesDir / "xspf_player.swf"
         videofile.copyfile(outputDir / "xspf_player.swf")
     if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
         (self.templatesDir / "fdl.html").copyfile(outputDir / "fdl.html")
     self.filename.safeSave(self.doZip, _("EXPORT FAILED!\nLast succesful export is %s."), outputDir)
     outputDir.rmtree()
class WikipediaIdevice(Idevice):
    """
    A Wikipedia Idevice is one built from a Wikipedia article.
    """
    persistenceVersion = 8

    def __init__(self, defaultSite):
        Idevice.__init__(self, x_(u"Wiki Article"), 
                         x_(u"University of Auckland"), 
                         x_(u"""<p>The Wikipedia iDevice allows you to locate 
existing content from within Wikipedia and download this content into your eXe 
resource. The Wikipedia Article iDevice takes a snapshot copy of the article 
content. Changes in Wikipedia will not automatically update individual snapshot 
copies in eXe, a fresh copy of the article will need to be taken. Likewise, 
changes made in eXe will not be updated in Wikipedia. </p> <p>Wikipedia content 
is covered by the GNU free documentation license.</p>"""), 
                         u"", u"")
        self.emphasis         = Idevice.NoEmphasis
        self.articleName      = u""
        self.article          = TextAreaField(x_(u"Article"))
        self.article.idevice  = self
        self.images           = {}
        self.site             = defaultSite
        self.icon             = u"inter"
        self.systemResources += ["fdl.html"]
        self._langInstruc      = x_(u"""Select the appropriate language version 
of Wikipedia to search and enter search term.""")
        self._searchInstruc    = x_("""Enter a phrase or term you wish to search 
within Wikipedia.""")
        self.ownUrl               = ""

        
    # Properties
    langInstruc      = lateTranslate('langInstruc')
    searchInstruc    = lateTranslate('searchInstruc')
   
    def loadArticle(self, name):
        """
        Load the article from Wikipedia
        """
        self.articleName = name
        url = ""
        name = urllib.quote(name.replace(" ", "_").encode('utf-8'))
        try:
            url  = (self.site or self.ownUrl)
            if not url.endswith('/') and name <> '': url += '/'
            if '://' not in url: url = 'http://' + url
            url += name
            net  = urllib.urlopen(url)
            page = net.read()
            net.close()
        except IOError, error:
            log.warning(unicode(error))
            self.article.content = _(u"Unable to download from %s <br/>Please check the spelling and connection and try again.") % url
            self.article.content_w_resourcePaths = self.article.content
            self.article.content_wo_resourcePaths = self.article.content
            return

        page = unicode(page, "utf8")
        # FIXME avoid problems with numeric entities in attributes
        page = page.replace(u'&#160;', u'&nbsp;')

        # avoidParserProblems is set to False because BeautifulSoup's
        # cleanup was causing a "concatenating Null+Str" error,
        # and Wikipedia's HTML doesn't need cleaning up.
        # BeautifulSoup is faster this way too.
        soup = BeautifulSoup(page, False)
        content = soup.first('div', {'id': "content"})

        # remove the wiktionary, wikimedia commons, and categories boxes
        #  and the protected icon and the needs citations box
        if content:
            infoboxes = content.findAll('div',
                    {'class' : 'infobox sisterproject'})
            [infobox.extract() for infobox in infoboxes]
            catboxes = content.findAll('div', {'id' : 'catlinks'})
            [catbox.extract() for catbox in catboxes]
            amboxes = content.findAll('table',
                    {'class' : re.compile(r'.*\bambox\b.*')})
            [ambox.extract() for ambox in amboxes]
            protecteds = content.findAll('div', {'id' : 'protected-icon'})
            [protected.extract() for protected in protecteds]
        else:
            content = soup.first('body')

        if not content:
            log.error("no content")
            self.article.content = _(u"Unable to download from %s <br/>Please check the spelling and connection and try again.") % url
            # set the other elements as well
            self.article.content_w_resourcePaths = self.article.content
            self.article.content_wo_resourcePaths = self.article.content
            return

        # clear out any old images
        while self.userResources:
            self.userResources[0].delete()
        self.images        = {}

        # Download the images
        bits = url.split('/')
        netloc = '%s//%s' % (bits[0], bits[2])
        path = '/'.join(bits[3:-1])
        tmpDir = TempDirPath()
        for imageTag in content.fetch('img'):
            imageSrc  = unicode(imageTag['src'])
            imageName = imageSrc.split('/')[-1]
            # Search if we've already got this image
            if imageName not in self.images:
                if not imageSrc.startswith("http://"):
                    if imageSrc.startswith("/"):
                        imageSrc = netloc + imageSrc
                    else:
                        imageSrc = '%s/%s/%s' % (netloc, path, imageSrc)
                urllib.urlretrieve(imageSrc, tmpDir/imageName)
                new_resource = Resource(self, tmpDir/imageName)
                if new_resource._storageName != imageName:
                    # looks like it was changed due to a possible conflict,
                    # so reset the imageName accordingly for the content:
                    imageName = new_resource._storageName
                self.images[imageName] = True
            # We have to use absolute URLs if we want the images to
            # show up in edit mode inside FCKEditor
            imageTag['src'] = (u"/" + self.parentNode.package.name + u"/resources/" + imageName)
        self.article.content = self.reformatArticle(netloc, unicode(content))
        # now that these are supporting images, any direct manipulation
        # of the content field must also store this updated information
        # into the other corresponding fields of TextAreaField:
        # (perhaps eventually a property should be made for TextAreaField 
        #  such that these extra set's are not necessary, but for now, here:)
        self.article.content_w_resourcePaths = self.article.content
        self.article.content_wo_resourcePaths = self.article.content
示例#24
0
            print '"ncftpget" not found. Go: sudo apt-get install ncftp'
        if not ok:
            sys.exit(1)
        os.system("fakeroot debian/rules binary")
    else:
        raise Exception('You need to copy the firefox installation to "exe/webui/firefox"')
packages = (exeDir / "..").glob("*.deb")
if not packages:
    print "No packages found"
    sys.exit(1)
packages.sort()
package = packages[-1]
tmp = None
if "index" in sys.argv:
    print "Creating Index..."
    tmp = TempDirPath()
    pool = tmp / "pool"
    pool.mkdir()
    package.copyfile(pool / package.basename())
    pool.chdir()
    tmp.chdir()
    os.system("dpkg-scanpackages pool /dev/null | gzip -9c > pool/Packages.gz")
if "copy" in sys.argv:
    if "index" in sys.argv:
        print "copying index file to", exeDir
        (pool / "Packages.gz").copy(exeDir)
    pool = exeDir
if server:
    print "connecting to %s..." % server
    from socket import socket, gethostbyname
示例#25
0
class Package(Persistable):
    """
    Package represents the collection of resources the user is editing
    i.e. the "package".
    """
    persistenceVersion = 9
    nonpersistant      = ['resourceDir', 'filename']
    _name              = '' 
    tempFile           = False # This is set when the package is saved as a temp copy file
    _title             = '' 
    _author            = ''
    _description       = ''
    _backgroundImg     = ''
    defaultLevelNames  = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]
    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId    = 0
        self._nodeIdDict    = {} 
        self._levelNames    = self.defaultLevelNames[:]
        self.name           = name
        self._title         = u''
        self._backgroundImg = u''
        self.backgroundImgTile = False
        self.filename      = u''
        self.root          = Node(self, None, _(u"Home"))
        self.currentNode   = self.root
        self.style         = u"default"
        self.isChanged     = False
        self.idevices      = []
        self.dublinCore    = DublinCore()
        self.scolinks      = False
        self.license       = "None"
        self.footer        = ""
        self.resourceDir = TempDirPath()
        self.resources = {} # Checksum-[_Resource(),..]
    def set_name(self, value):
        self._name = toUnicode(value)
    def set_title(self, value):
        self._title = toUnicode(value)
    def set_author(self, value):
        self._author = toUnicode(value)
    def set_description(self, value):
        self._description = toUnicode(value)
    def get_backgroundImg(self):
        """Get the background image for this package"""
        if self._backgroundImg:
            return "file://" + self._backgroundImg.path
        else:
            return ""
    def set_backgroundImg(self, value):
        """Set the background image for this package"""
        if self._backgroundImg:
            self._backgroundImg.delete()
        if value:
            if value.startswith("file://"):
                value = value[7:]
            imgFile = Path(value)
            self._backgroundImg = Resource(self, Path(imgFile))
        else:
            self._backgroundImg = u''
    def get_level1(self):
        return self.levelName(0)
    def set_level1(self, value):
        if value != '':
            self._levelNames[0] = value 
        else:
            self._levelNames[0] = self.defaultLevelNames[0]
    def get_level2(self):
        return self.levelName(1)
    def set_level2(self, value):
        if value != '':
            self._levelNames[1] = value 
        else:
            self._levelNames[1] = self.defaultLevelNames[1]
    def get_level3(self):
        return self.levelName(2)
    def set_level3(self, value):
        if value != '':
            self._levelNames[2] = value 
        else:
            self._levelNames[2] = self.defaultLevelNames[2]
    name          = property(lambda self:self._name, set_name)
    title         = property(lambda self:self._title, set_title)
    author        = property(lambda self:self._author, set_author)
    description   = property(lambda self:self._description, set_description)
    backgroundImg = property(get_backgroundImg, set_backgroundImg)
    level1 = property(get_level1, set_level1)
    level2 = property(get_level2, set_level2)
    level3 = property(get_level3, set_level3)
    def findNode(self, nodeId):
        """
        Finds a node from its nodeId
        (nodeId can be a string or a list/tuple)
        """
        log.debug(u"findNode" + repr(nodeId))
        node = self._nodeIdDict.get(nodeId)
        if node and node.package is self:
            return node
        else: 
            return None
    def levelName(self, level):
        """
        Return the level name
        """
        if level < len(self._levelNames):
            return _(self._levelNames[level])
        else:
            return _(u"?????")
    def save(self, filename=None, tempFile=False):
        """
        Save package to disk
        pass an optional filename
        """
        self.tempFile = tempFile
        if filename:
            filename = Path(filename)
            name = filename.splitpath()[1]
            if not tempFile:
                self.name = name.basename().splitext()[0]
        elif self.filename:
            filename = Path(self.filename)
        else:
            raise AssertionError(u'No name passed when saving a new package')
        log.debug(u"Will save %s to: %s" % (self.name, filename))
        if tempFile:
            self.nonpersistant.remove('filename')
            oldFilename, self.filename = self.filename, unicode(self.filename)
            try:
                filename.safeSave(self.doSave, _('SAVE FAILED!\nLast succesful save is %s.'))
            finally:
                self.nonpersistant.append('filename')
                self.filename = oldFilename
        else:
            self.filename = filename
            filename.safeSave(self.doSave, _('SAVE FAILED!\nLast succesful save is %s.'))
            self.isChanged = False
            self.updateRecentDocuments(filename)
    def updateRecentDocuments(self, filename):
        """
        Updates the list of recent documents
        """
        genericData = G.application.config.configDir/'idevices'/'generic.data'
        if genericData.isfile() or genericData.islink():
            if Path(filename).samefile(genericData):
                return
        recentProjects = G.application.config.recentProjects
        if filename in recentProjects:
            if recentProjects[0] == filename:
                return
            recentProjects.remove(filename)
        recentProjects.insert(0, filename)
        del recentProjects[5:] # Delete any older names from the list
        G.application.config.configParser.write() # Save the settings
    def doSave(self, fileObj):
        """
        Actually performs the save to 'fileObj'.
        """
        zippedFile = zipfile.ZipFile(fileObj, "w", zipfile.ZIP_DEFLATED)
        try:
            for resourceFile in self.resourceDir.files():
                zippedFile.write(unicode(resourceFile.normpath()),
                        resourceFile.name.encode('utf8'), zipfile.ZIP_DEFLATED)
            zinfo = zipfile.ZipInfo(filename='content.data',
                    date_time=time.localtime()[0:6])
            zinfo.external_attr = 0100644<<16L
            zippedFile.writestr(zinfo, encodeObject(self))
        finally:
            zippedFile.close()
    def extractNode(self):
        """
        Clones and extracts the currently selected node into a new package.
        """
        newPackage = Package('NoName') # Name will be set once it is saved..
        newPackage.title  = self.currentNode.title
        newPackage.style  = self.style
        newPackage.author = self.author
        newPackage._nextNodeId = self._nextNodeId
        self.currentNode.copyToPackage(newPackage)
        return newPackage
    @staticmethod
    def load(filename, newLoad=True, destinationPackage=None):
        """
        Load package from disk, returns a package.
        """
        if not zipfile.is_zipfile(filename):
            return None
        zippedFile = zipfile.ZipFile(filename, "r")
        toDecode   = zippedFile.read(u"content.data")
        resourceDir = TempDirPath()
        for fn in zippedFile.namelist():
            if unicode(fn, 'utf8') != u"content.data":
                outFile = open(resourceDir/fn, "wb")
                outFile.write(zippedFile.read(fn))
                outFile.flush()
                outFile.close()
        try:
            newPackage = decodeObjectRaw(toDecode)
            G.application.afterUpgradeHandlers = []
            newPackage.resourceDir = resourceDir
            G.application.afterUpgradeZombies2Delete = []
            if newLoad: 
                log.debug("load() about to doUpgrade newPackage \"" 
                        + newPackage._name + "\" " + repr(newPackage) )
                if hasattr(newPackage, 'resourceDir'):
                    log.debug("newPackage resourceDir = "
                            + newPackage.resourceDir)
                else:
                    log.error("newPackage resourceDir has NO resourceDir!")
                doUpgrade(newPackage)
            else: 
                log.debug("load() about to merge doUpgrade newPackage \"" 
                        + newPackage._name + "\" " + repr(newPackage)
                        + " INTO destinationPackage \"" 
                        + destinationPackage._name + "\" " 
                        + repr(destinationPackage))
                log.debug("using their resourceDirs:")
                if hasattr(newPackage, 'resourceDir'):
                    log.debug("   newPackage resourceDir = " 
                            + newPackage.resourceDir)
                else:
                    log.error("newPackage has NO resourceDir!")
                if hasattr(destinationPackage, 'resourceDir'):
                    log.debug("   destinationPackage resourceDir = " 
                            + destinationPackage.resourceDir)
                else:
                    log.error("destinationPackage has NO resourceDir!")
                doUpgrade(destinationPackage, 
                        isMerge=True, preMergePackage=newPackage)
        except:
            import traceback
            traceback.print_exc()
            raise
        if newPackage.tempFile:
            newPackage.tempFile = False
        else:
            newPackage.filename = Path(filename)
        for handler_priority in range(3):
          for handler in G.application.afterUpgradeHandlers:
            if handler_priority == 0 and \
            repr(handler.im_class)=="<class 'exe.engine.resource.Resource'>":
                handler()
            elif handler_priority == 1 and \
            repr(handler.im_class)=="<class 'exe.engine.package.Package'>":
                if handler.im_self == newPackage: 
                    handler()
                else:
                    log.warn("Extra package object found, " \
                       + "ignoring its afterUpgradeHandler: " \
                       + repr(handler))
            elif handler_priority == 2 and \
            repr(handler.im_class)!="<class 'exe.engine.resource.Resource'>" \
            and \
            repr(handler.im_class)!="<class 'exe.engine.package.Package'>":
                handler()
        G.application.afterUpgradeHandlers = []
        num_zombies = len(G.application.afterUpgradeZombies2Delete)
        for i in range(num_zombies-1, -1, -1):
            zombie = G.application.afterUpgradeZombies2Delete[i]
            zombie_is_node = False
            if isinstance(zombie, Node):
                zombie_is_node = True
            if zombie_is_node: 
                zombie.delete(pruningZombies=True) 
            else:
                zombie.delete() 
            del zombie
        G.application.afterUpgradeZombies2Delete = []
        newPackage.updateRecentDocuments(newPackage.filename)
        newPackage.isChanged = False
        return newPackage
    def cleanUpResources(self):
        """
        Removes duplicate resource files
        """
        if not hasattr(self,'resourceDir'):
            log.warn("cleanUpResources called on a redundant package")
            return
        existingFiles = set([fn.basename() for fn in self.resourceDir.files()])
        usedFiles = set([reses[0].storageName for reses in self.resources.values()])
        for fn in existingFiles - usedFiles:
            (self.resourceDir/fn).remove()
    def findResourceByName(self, queryName):
        """
        Support for merging, and anywhere else that unique names might be
        checked before actually comparing against the files (as will be 
        done by the resource class itself in its _addOurselvesToPackage() )
        """
        foundResource = None
        queryResources = self.resources
        for this_checksum in queryResources:
            for this_resource in queryResources[this_checksum]:
                if queryName == this_resource.storageName:
                    foundResource = this_resource
                    return foundResource
        return foundResource
    def upgradeToVersion1(self):
        """
        Called to upgrade from 0.3 release
        """
        self._nextNodeId = 0
        self._nodeIdDict = {}
        draft = getattr(self, 'draft')
        draft._id = self._regNewNode(draft)
        draft._package = self
        setattr(self, 'editor', Node(self, None, _(u"iDevice Editor")))
        idevice = GenericIdevice("", "", "", "", "")
        editor = getattr(self, 'editor')
        idevice.parentNode = editor
        editor.addIdevice(idevice)
        def superReg(node):
            """Registers all our nodes
            because in v0 they were not registered
            in this way"""
            node._id = self._regNewNode(node)
            node._package = self
            for child in node.children:
                superReg(child)
        superReg(self.root)
    def _regNewNode(self, node):
        """
        Called only by nodes, 
        stores the node in our id lookup dict
        returns a new unique id
        """
        id_ = unicode(self._nextNodeId)
        self._nextNodeId += 1
        self._nodeIdDict[id_] = node
        return id_
    def getNewIdeviceId(self):
        """
        Returns an iDevice Id which is unique for this package.
        """
        id_ = unicode(self._nextIdeviceId)
        self._nextIdeviceId += 1
        return id_
    def upgradeToVersion2(self):
        """
        Called to upgrade from 0.4 release
        """
        getattr(self, 'draft').delete()
        getattr(self, 'editor').delete()
        delattr(self, 'draft')
        delattr(self, 'editor')
        self._nextNodeId = 0
        def renumberNode(node):
            """
            Gives the old node a number
            """
            node._id = self._regNewNode(node)
            for child in node.children:
                renumberNode(child)
        renumberNode(self.root)
    def upgradeToVersion3(self):
        """
        Also called to upgrade from 0.4 release
        """
        self._nextIdeviceId = 0
    def upgradeToVersion4(self):
        """
        Puts properties in their place
        Also called to upgrade from 0.8 release
        """
        self._name = toUnicode(self.__dict__['name'])
        self._author = toUnicode(self.__dict__['author'])
        self._description = toUnicode(self.__dict__['description'])
    def upgradeToVersion5(self):
        """
        For version 0.11
        """
        self._levelNames = self.levelNames
        del self.levelNames
    def upgradeToVersion6(self):
        """
        For version 0.14
        """
        self.dublinCore = DublinCore()
        self.title = self.root.title
        self.dublinCore.title = self.root.title
        self.dublinCore.creator = self._author
        self.dublinCore.description = self._description
        self.scolinks = False
    def upgradeToVersion7(self):
        """
        For version 0.15
        """
        self._backgroundImg = ''
        self.backgroundImgTile = False
    def upgradeToVersion8(self):
        """
        For version 0.20, alpha, for nightlies r2469
        """
        self.license = 'None'
        self.footer = ""
        self.idevices = []
    def upgradeToVersion9(self):
        """
        For version >= 0.20.4
        """
        if not hasattr(self, 'resources'):
            self.resources = {}
        G.application.afterUpgradeHandlers.append(self.cleanUpResources)
示例#26
0
class Package(Persistable):
    """
    Package represents the collection of resources the user is editing
    i.e. the "package".
    """

    persistenceVersion = 8
    nonpersistant = ["resourceDir", "filename"]
    _name = ""
    tempFile = False  # This is set when the package is saved as a temp copy file
    _title = ""
    _author = ""
    _description = ""
    _backgroundImg = ""
    defaultLevelNames = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]

    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId = 0
        self._nodeIdDict = {}
        self._levelNames = self.defaultLevelNames[:]
        self.name = name
        self._title = u""
        self._backgroundImg = u""
        self.backgroundImgTile = False
        self.filename = u""
        self.root = Node(self, None, _(u"Home"))
        self.currentNode = self.root
        self.style = u"default"
        self.isChanged = 0
        self.idevices = []
        self.dublinCore = DublinCore()
        self.scolinks = False
        self.license = "None"
        self.footer = ""
        self.resourceDir = TempDirPath()

    def set_name(self, value):
        self._name = toUnicode(value)

    def set_title(self, value):
        self._title = toUnicode(value)

    def set_author(self, value):
        self._author = toUnicode(value)

    def set_description(self, value):
        self._description = toUnicode(value)

    def get_backgroundImg(self):
        """Get the background image for this package"""
        if self._backgroundImg:
            return "file://" + self._backgroundImg.path
        else:
            return ""

    def set_backgroundImg(self, value):
        """Set the background image for this package"""
        if self._backgroundImg:
            self._backgroundImg.delete()
        if value:
            if value.startswith("file://"):
                value = value[7:]
            imgFile = Path(value)
            self._backgroundImg = Resource(self, Path(imgFile))
        else:
            self._backgroundImg = u""

    def get_level1(self):
        return self.levelName(0)

    def set_level1(self, value):
        if value != "":
            self._levelNames[0] = value
        else:
            self._levelNames[0] = self.defaultLevelNames[0]

    def get_level2(self):
        return self.levelName(1)

    def set_level2(self, value):
        if value != "":
            self._levelNames[1] = value
        else:
            self._levelNames[1] = self.defaultLevelNames[1]

    def get_level3(self):
        return self.levelName(2)

    def set_level3(self, value):
        if value != "":
            self._levelNames[2] = value
        else:
            self._levelNames[2] = self.defaultLevelNames[2]

    name = property(lambda self: self._name, set_name)
    title = property(lambda self: self._title, set_title)
    author = property(lambda self: self._author, set_author)
    description = property(lambda self: self._description, set_description)
    backgroundImg = property(get_backgroundImg, set_backgroundImg)
    level1 = property(get_level1, set_level1)
    level2 = property(get_level2, set_level2)
    level3 = property(get_level3, set_level3)

    def findNode(self, nodeId):
        """
        Finds a node from its nodeId
        (nodeId can be a string or a list/tuple)
        """
        log.debug(u"findNode" + repr(nodeId))
        node = self._nodeIdDict.get(nodeId)
        if node and node.package is self:
            return node
        else:
            return None

    def levelName(self, level):
        """
        Return the level name
        """
        if level < len(self._levelNames):
            return _(self._levelNames[level])
        else:
            return _(u"?????")

    def save(self, filename=None, tempFile=False):
        """
        Save package to disk
        pass an optional filename
        """
        self.tempFile = tempFile
        if filename:
            filename = Path(filename)
            name = filename.splitpath()[1]
            if not tempFile:
                self.name = name.basename().splitext()[0]
        elif self.filename:
            filename = Path(self.filename)
        else:
            raise AssertionError(u"No name passed when saving a new package")
        log.debug(u"Will save %s to: %s" % (self.name, filename))
        if tempFile:
            self.nonpersistant.remove("filename")
            oldFilename, self.filename = self.filename, unicode(self.filename)
            try:
                filename.safeSave(self.doSave, _("SAVE FAILED!\nLast succesful save is %s."))
            finally:
                self.nonpersistant.append("filename")
                self.filename = oldFilename
        else:
            self.filename = filename
            filename.safeSave(self.doSave, _("SAVE FAILED!\nLast succesful save is %s."))
            self.isChanged = 0
            self.updateRecentDocuments(filename)

    def updateRecentDocuments(self, filename):
        """
        Updates the list of recent documents
        """
        from exe.application import application

        genericData = application.config.configDir / "idevices" / "generic.data"
        if genericData.isfile() or genericData.islink():
            if Path(filename).samefile(genericData):
                return
        recentProjects = application.config.recentProjects
        fn = filename.encode("utf-8")
        if fn in recentProjects:
            if recentProjects[0] == fn:
                return
            recentProjects.remove(fn)
        recentProjects.insert(0, filename)
        del recentProjects[5:]  # Delete any older names from the list
        application.config.configParser.write()  # Save the settings

    def doSave(self, fileObj):
        """
        Actually performs the save to 'fileObj'.
        """
        zippedFile = zipfile.ZipFile(fileObj, "w", zipfile.ZIP_DEFLATED)
        try:
            for resourceFile in self.resourceDir.files():
                zippedFile.write(
                    unicode(resourceFile.normpath()), resourceFile.name.encode("utf8"), zipfile.ZIP_DEFLATED
                )
            zippedFile.writestr("content.data", encodeObject(self))
        finally:
            zippedFile.close()

    @staticmethod
    def load(filename):
        """
        Load package from disk, returns a package
        """
        if not zipfile.is_zipfile(filename):
            return None
        zippedFile = zipfile.ZipFile(filename, "r", zipfile.ZIP_DEFLATED)
        toDecode = zippedFile.read(u"content.data")
        try:
            newPackage = decodeObjectRaw(toDecode)
            newPackage.afterUpgradeHandlers = []
            doUpgrade()
        except:
            import traceback

            traceback.print_exc()
            raise
        if newPackage.tempFile:
            newPackage.tempFile = False
        else:
            newPackage.filename = Path(filename)
        newPackage.resourceDir = TempDirPath()
        for filename in zippedFile.namelist():
            if unicode(filename, "utf8") != u"content.data":
                outFile = open(newPackage.resourceDir / filename, "wb")
                outFile.write(zippedFile.read(filename))
        for handler in newPackage.afterUpgradeHandlers:
            handler()
        del newPackage.afterUpgradeHandlers
        newPackage.updateRecentDocuments(newPackage.filename)
        return newPackage

    def upgradeToVersion1(self):
        """
        Called to upgrade from 0.3 release
        """
        self._nextNodeId = 0
        self._nodeIdDict = {}
        draft = getattr(self, "draft")
        draft._id = self._regNewNode(draft)
        draft._package = self
        setattr(self, "editor", Node(self, None, _(u"iDevice Editor")))
        idevice = GenericIdevice("", "", "", "", "")
        editor = getattr(self, "editor")
        idevice.parentNode = editor
        editor.addIdevice(idevice)

        def superReg(node):
            """Registers all our nodes
            because in v0 they were not registered
            in this way"""
            node._id = self._regNewNode(node)
            node._package = self
            for child in node.children:
                superReg(child)

        superReg(self.root)

    def _regNewNode(self, node):
        """
        Called only by nodes, 
        stores the node in our id lookup dict
        returns a new unique id
        """
        id_ = unicode(self._nextNodeId)
        self._nextNodeId += 1
        self._nodeIdDict[id_] = node
        return id_

    def getNewIdeviceId(self):
        """
        Returns an iDevice Id which is unique for this package.
        """
        id_ = unicode(self._nextIdeviceId)
        self._nextIdeviceId += 1
        return id_

    def upgradeToVersion2(self):
        """
        Called to upgrade from 0.4 release
        """
        getattr(self, "draft").delete()
        getattr(self, "editor").delete()
        delattr(self, "draft")
        delattr(self, "editor")
        self._nextNodeId = 0

        def renumberNode(node):
            """
            Gives the old node a number
            """
            node._id = self._regNewNode(node)
            for child in node.children:
                renumberNode(child)

        renumberNode(self.root)

    def upgradeToVersion3(self):
        """
        Also called to upgrade from 0.4 release
        """
        self._nextIdeviceId = 0

    def upgradeToVersion4(self):
        """
        Puts properties in their place
        Also called to upgrade from 0.8 release
        """
        self._name = toUnicode(self.__dict__["name"])
        self._author = toUnicode(self.__dict__["author"])
        self._description = toUnicode(self.__dict__["description"])

    def upgradeToVersion5(self):
        """
        For version 0.11
        """
        self._levelNames = self.levelNames
        del self.levelNames

    def upgradeToVersion6(self):
        """
        For version 0.14
        """
        self.dublinCore = DublinCore()
        self.title = self.root.title
        self.dublinCore.title = self.root.title
        self.dublinCore.creator = self._author
        self.dublinCore.description = self._description
        self.scolinks = False

    def upgradeToVersion7(self):
        """
        For version 0.15
        """
        self._backgroundImg = ""
        self.backgroundImgTile = False

    def upgradeToVersion8(self):
        """
        For version 0.20
        """
        self.license = "None"
        self.footer = ""
示例#27
0
 def export(self, package):
     """ 
     Export SCORM package
     """
     outputDir = TempDirPath()
     styleFiles  = [self.styleDir/'..'/'base.css']
     styleFiles += [self.styleDir/'..'/'popup_bg.gif']
     styleFiles += self.styleDir.files("*.css")
     if "nav.css" in styleFiles:
         styleFiles.remove("nav.css")
     styleFiles += self.styleDir.files("*.jpg")
     styleFiles += self.styleDir.files("*.gif")
     styleFiles += self.styleDir.files("*.png")
     styleFiles += self.styleDir.files("*.js")
     styleFiles += self.styleDir.files("*.html")
     self.styleDir.copylist(styleFiles, outputDir)
     package.resourceDir.copyfiles(outputDir)
     self.pages = [ IMSPage("index", 1, package.root) ]
     self.generatePages(package.root, 2)
     uniquifyNames(self.pages)
     for page in self.pages:
         page.save(outputDir)
     manifest = Manifest(self.config, outputDir, package, self.pages)
     manifest.save()
     self.scriptsDir.copylist(('libot_drag.js',
                               'common.js'), outputDir)
     self.schemasDir.copylist(('imscp_v1p1.xsd',
                               'imsmd_v1p2p2.xsd',
                               'ims_xml.xsd'), outputDir)
     hasFlowplayer     = False
     hasMagnifier      = False
     hasXspfplayer     = False
     isBreak           = False
     for page in self.pages:
         if isBreak:
             break
         for idevice in page.node.idevices:
             if (hasFlowplayer and hasMagnifier and hasXspfplayer):
                 isBreak = True
                 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(outputDir/'flowPlayer.swf')
     if hasMagnifier:
         videofile = (self.templatesDir/'magnifier.swf')
         videofile.copyfile(outputDir/'magnifier.swf')
     if hasXspfplayer:
         videofile = (self.templatesDir/'xspf_player.swf')
         videofile.copyfile(outputDir/'xspf_player.swf')
     (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
     self.filename.safeSave(self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'), outputDir)
     outputDir.rmtree()
示例#28
0
文件: imsexport.py 项目: RichDijk/eXe
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        self.metadataType = package.exportMetadataType

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / ".." / "base.css"]
        styleFiles += [self.styleDir / ".." / "popup_bg.gif"]
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        self.styleDir.copylist(styleFiles, outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(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)

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

        # Copy the scripts

        # 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")

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

        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
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasMediaelement = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (
                    hasFlowplayer
                    and hasMagnifier
                    and hasXspfplayer
                    and hasGallery
                    and hasWikipedia
                    and hasInstructions
                    and hasMediaelement
                ):
                    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 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 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:
            imageGalleryCSS = self.cssDir / "exe_lightbox.css"
            imageGalleryCSS.copyfile(outputDir / "exe_lightbox.css")
            imageGalleryJS = self.scriptsDir / "exe_lightbox.js"
            imageGalleryJS.copyfile(outputDir / "exe_lightbox.js")
            self.imagesDir.copylist(
                (
                    "exe_lightbox_close.png",
                    "exe_lightbox_loading.gif",
                    "exe_lightbox_next.png",
                    "exe_lightbox_prev.png",
                ),
                outputDir,
            )
        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 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()
示例#29
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
        package.resourceDir.copyfiles(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)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")
        
        # Copy the style sheet files to the output dir
        styleFiles  = [self.styleDir/'..'/'base.css']
        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)
        
        # Copy the scripts
        dT = common.getExportDocType()
        if dT == "HTML5":
            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:
                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')
            
        if self.scormType == "commoncartridge":
            jsFile = (self.scriptsDir/'common.js')
            jsFile.copyfile(outputDir/'common.js')

        if self.scormType == "scorm2004" or self.scormType == "scorm1.2":
            self.scriptsDir.copylist(('SCORM_API_wrapper.js',
                                      'SCOFunctions.js', 
                                      'lernmodule_net.js',
                                      'lernmodule_net_custom.js',
                                      'common.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
        hasWikipedia      = False
        isBreak           = False
        hasInstructions   = False
        hasMediaelement   = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery and hasWikipedia and hasInstructions and hasMediaelement):
                    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 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 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:
            imageGalleryCSS = (self.cssDir/'exe_lightbox.css')
            imageGalleryCSS.copyfile(outputDir/'exe_lightbox.css') 
            imageGalleryJS = (self.scriptsDir/'exe_lightbox.js')
            imageGalleryJS.copyfile(outputDir/'exe_lightbox.js') 
            self.imagesDir.copylist(('exe_lightbox_close.png', 'exe_lightbox_loading.gif', 'exe_lightbox_next.png', 'exe_lightbox_prev.png'), outputDir)
        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 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.html').copyfile(outputDir/'fdl.html')
        
        if hasattr(package, 'scowsinglepage') and package.scowsinglepage:
            page = SinglePage("singlepage_index", 1, package.root)
            page.save(outputDir/"singlepage_index.html")
            # 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()
    def load(filename, newLoad=True, destinationPackage=None):
        """
        Load package from disk, returns a package.
        """
        if not zipfile.is_zipfile(filename):
            return None

        zippedFile = zipfile.ZipFile(filename, "r")
        
        try:
            # Get the jellied package data
            toDecode   = zippedFile.read(u"content.data")
        except KeyError:
            log.info("no content.data, trying Common Cartridge/Content Package")
            newPackage = loadCC(zippedFile, filename)
            newPackage.tempFile = False
            newPackage.isChanged = False
            newPackage.filename = Path(filename)

            return newPackage
            
        # Need to add a TempDirPath because it is a nonpersistant member
        resourceDir = TempDirPath()

        # Extract resource files from package to temporary directory
        for fn in zippedFile.namelist():
            if unicode(fn, 'utf8') != u"content.data":
                outFile = open(resourceDir/fn, "wb")
                outFile.write(zippedFile.read(fn))
                outFile.flush()
                outFile.close()

        try:
            newPackage = decodeObjectRaw(toDecode)
            G.application.afterUpgradeHandlers = []
            newPackage.resourceDir = resourceDir
            G.application.afterUpgradeZombies2Delete = []

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

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

                doUpgrade(newPackage)

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

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

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

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

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

        except:
            import traceback
            traceback.print_exc()
            raise

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

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

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

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

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

        G.application.afterUpgradeHandlers = []

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

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

        newPackage.updateRecentDocuments(newPackage.filename)
        newPackage.isChanged = False
        return newPackage
示例#31
0
文件: imsexport.py 项目: Rafav/iteexe
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        self.metadataType = package.exportMetadataType

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / '..' / 'base.css']
        styleFiles += [self.styleDir / '..' / 'popup_bg.gif']
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        self.styleDir.copylist(styleFiles, outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(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)

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

        # Copy the scripts

        # 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')

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

        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
        hasWikipedia = False
        isBreak = False
        hasInstructions = False
        hasMediaelement = False
        hasTooltips = 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 hasMediaelement and hasTooltips):
                    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 hasMediaelement:
                    hasMediaelement = common.ideviceHasMediaelement(idevice)
                if not hasTooltips:
                    hasTooltips = common.ideviceHasTooltips(idevice)

        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)
        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 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()
示例#32
0
 def export(self, package):
     """ 
     Export SCORM package
     """
     outputDir = TempDirPath()
     self.pages = [ ScormPage("index", 1, package.root,
         scormType=self.scormType) ]
     self.generatePages(package.root, 2)
     uniquifyNames(self.pages)
     for page in self.pages:
         page.save(outputDir)
         if not self.hasForum:
             for idevice in page.node.idevices:
                 if hasattr(idevice, "isForum"):
                     if idevice.forum.lms.lms == "moodle":
                         self.hasForum = True
                         break
     manifest = Manifest(self.config, outputDir, package, self.pages, self.scormType)
     manifest.save("imsmanifest.xml")
     if self.hasForum:
         manifest.save("discussionforum.xml")
     styleFiles  = [self.styleDir/'..'/'base.css']
     styleFiles += [self.styleDir/'..'/'popup_bg.gif']
     styleFiles += [f for f in self.styleDir.files("*.css")
             if f.basename() <> "nav.css"] 
     styleFiles += self.styleDir.files("*.jpg")
     styleFiles += self.styleDir.files("*.gif")
     styleFiles += self.styleDir.files("*.png")
     styleFiles += self.styleDir.files("*.js")
     styleFiles += self.styleDir.files("*.html")
     if self.scormType == "commoncartridge":
         for sf in styleFiles[:]:
             if sf.basename() not in manifest.dependencies:
                 styleFiles.remove(sf)
     self.styleDir.copylist(styleFiles, outputDir)
     package.resourceDir.copyfiles(outputDir)
     if self.scormType == "commoncartridge":
         self.scriptsDir.copylist(('libot_drag.js',
                                   'common.js'), outputDir)
     else:
         self.scriptsDir.copylist(('APIWrapper.js', 
                                   'SCOFunctions.js', 
                                   'libot_drag.js',
                                   'common.js'), outputDir)
     schemasDir = ""
     if self.scormType == "scorm1.2":
         schemasDir = self.schemasDir/"scorm1.2"
         schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                             'imsmd_rootv1p2p1.xsd',
                             'adlcp_rootv1p2.xsd',
                             'ims_xml.xsd'), outputDir)
     elif self.scormType == "scorm2004":
         schemasDir = self.schemasDir/"scorm2004"
         schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                             'imsmd_rootv1p2p1.xsd',
                             'adlcp_rootv1p2.xsd',
                             'ims_xml.xsd'), outputDir)
     hasFlowplayer     = False
     hasMagnifier      = False
     hasXspfplayer     = False
     isBreak           = False
     for page in self.pages:
         if isBreak:
             break
         for idevice in page.node.idevices:
             if (hasFlowplayer and hasMagnifier and hasXspfplayer):
                 isBreak = True
                 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(outputDir/'flowPlayer.swf')
     if hasMagnifier:
         videofile = (self.templatesDir/'magnifier.swf')
         videofile.copyfile(outputDir/'magnifier.swf')
     if hasXspfplayer:
         videofile = (self.templatesDir/'xspf_player.swf')
         videofile.copyfile(outputDir/'xspf_player.swf')
     if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
         (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
     self.filename.safeSave(self.doZip, _('EXPORT FAILED!\nLast succesful export is %s.'), outputDir)
     outputDir.rmtree()
示例#33
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
示例#34
0
class WikipediaIdevice(Idevice):
    """
    A Wikipedia Idevice is one built from a Wikipedia article.
    """
    persistenceVersion = 9

    def __init__(self, defaultSite):
        Idevice.__init__(
            self, x_(u"Wiki Article"), x_(u"University of Auckland"),
            x_(u"""<p>The Wikipedia iDevice allows you to locate 
existing content from within Wikipedia and download this content into your eXe 
resource. The Wikipedia Article iDevice takes a snapshot copy of the article 
content. Changes in Wikipedia will not automatically update individual snapshot 
copies in eXe, a fresh copy of the article will need to be taken. Likewise, 
changes made in eXe will not be updated in Wikipedia. </p> <p>Wikipedia content 
is covered by the GNU Free Documentation 1.2 License, and since 2009 additionally
by the Creative Commons Attribution-ShareAlike 3.0 Unported License.</p>"""),
            u"", u"")
        self.emphasis = Idevice.NoEmphasis
        self.articleName = u""
        self.article = TextAreaField(x_(u"Article"))
        self.article.idevice = self
        self.images = {}
        self.site = defaultSite
        self.icon = u"inter"
        self._langInstruc = x_(u"""Select the appropriate language version 
of Wikipedia to search and enter search term.""")
        self._searchInstruc = x_("""Enter a phrase or term you wish to search 
within Wikipedia.""")
        self.ownUrl = ""
        self.systemResources += ['exe_wikipedia.css']

    # Properties
    langInstruc = lateTranslate('langInstruc')
    searchInstruc = lateTranslate('searchInstruc')

    def loadArticle(self, name):
        """
        Load the article from Wikipedia
        """
        self.articleName = name
        url = ''
        name = urllib.quote(name.replace(" ", "_").encode('utf-8'))

        # Get the full URL of the site
        url = self.site or self.ownUrl
        if not url.endswith('/') and name != '':
            url += '/'
        if '://' not in url:
            url = 'http://' + url
        url += name

        # Get the site content
        try:
            net = urllib.urlopen(url)
            page = net.read()
            net.close()
        except IOError, error:
            log.warning(unicode(error))
            self.article.content = _(
                u"Unable to download from %s <br/>Please check the spelling and connection and try again."
            ) % url
            self.article.content_w_resourcePaths = self.article.content
            self.article.content_wo_resourcePaths = self.article.content
            return

        page = unicode(page, "utf8")
        # FIXME avoid problems with numeric entities in attributes
        page = page.replace(u'&#160;', u'&nbsp;')
        # avoidParserProblems is set to False because BeautifulSoup's
        # cleanup was causing a "concatenating Null+Str" error,
        # and Wikipedia's HTML doesn't need cleaning up.
        # BeautifulSoup is faster this way too.
        soup = BeautifulSoup(page, False)
        content = soup.first('div', {'id': "content"})
        # Fix bug #1359: El estilo ITE no respeta ancho de página al exportar
        # a páginas web si se usa iDevice wikipedia
        content['id'] = "wikipedia-content"

        # remove the wiktionary, wikimedia commons, and categories boxes
        # and the protected icon and the needs citations box
        if content:
            infoboxes = content.findAll('div',
                                        {'class': 'infobox sisterproject'})
            [infobox.extract() for infobox in infoboxes]
            catboxes = content.findAll('div', {'id': 'catlinks'})
            [catbox.extract() for catbox in catboxes]
            amboxes = content.findAll('table',
                                      {'class': re.compile(r'.*\bambox\b.*')})
            [ambox.extract() for ambox in amboxes]
            protecteds = content.findAll('div', {'id': 'protected-icon'})
            [protected.extract() for protected in protecteds]
            # Extract HTML comments
            comments = content.findAll(
                text=lambda text: isinstance(text, Comment))
            [comment.extract() for comment in comments]
        else:
            content = soup.first('body')

        # If we still don't have content it means there is a problem with the article
        if not content:
            log.error(u"No content on Wikipedia article: %s" % url)
            self.article.content = _(
                u"Unable to download from %s <br/>Please check the spelling and connection and try again."
            ) % url
            # Set the other elements as well
            self.article.content_w_resourcePaths = self.article.content
            self.article.content_wo_resourcePaths = self.article.content
            return

        # Clear out any old images
        while self.userResources:
            self.userResources[0].delete()
        self.images = {}

        # Download the images
        bits = url.split('/')
        netloc = '%s//%s' % (bits[0], bits[2])
        path = '/'.join(bits[3:-1])
        tmpDir = TempDirPath()

        # Fetch all images from content
        for imageTag in content.fetch('img'):
            # Get src and image filename
            imageSrc = unicode(imageTag['src'])
            imageName = imageSrc.split('/')[-1]
            imageName = imageName.replace('&gt;', '>')
            imageName = imageName.replace('&lt;', '<')
            imageName = imageName.replace('&quot;', '"')
            imageName = imageName.replace('&nbsp;', '')
            imageName = imageName.replace('%2C', ',')
            imageName = imageName.replace('%22', '"')
            imageName = imageName.replace('%28', '(')
            imageName = imageName.replace('%29', ')')
            imageName = imageName.replace('%C3%A5', 'å')
            # Decode image name
            imageName = urllib.unquote(imageName)
            # Search if we've already got this image
            if imageName not in self.images:
                if not re.match("^http(s)?:\/\/", imageSrc):
                    if imageSrc.startswith("/"):
                        imageSrc = bits[0] + imageSrc
                    else:
                        imageSrc = '%s/%s/%s' % (netloc, path, imageSrc)
                try:
                    # download with its original name... in ASCII:
                    ## er... just because some repositories do not undestand no ascii names of files:
                    imageName = imageName.encode('ascii', 'ignore')

                    # If the image file doesn't have an extension try to guess it
                    if not re.match('^.*\.(.){1,}', imageName):
                        # Open a conecction with the image and get the headers
                        online_resource = urllib.urlopen(imageSrc)
                        image_info = online_resource.info()
                        online_resource.close()

                        # Try to guess extension from mimetype
                        extension = mimetypes.guess_extension(
                            image_info['content-type'])
                        # Wikimedia uses mainly SVG images so we can safely say that
                        # this image is in svg (if it wasn't if wouldn't be shown anyway)
                        extension = extenion or '.svg'
                        imageName = imageName + extension

                    # Download image
                    urllib.urlretrieve(imageSrc, tmpDir / imageName)
                    # Add the new resource
                    new_resource = Resource(self, tmpDir / imageName)
                except:
                    log.error(u'Unable to download file: %s' % imageSrc)
                    # If there is an exception try to get the next one
                    continue
                if new_resource._storageName != imageName:
                    # looks like it was changed due to a possible conflict,
                    # so reset the imageName accordingly for the content:
                    imageName = new_resource._storageName
                self.images[imageName] = True
            imageTag['src'] = u"resources/" + imageName
        self.article.content = self.reformatArticle(netloc, unicode(content))
        # now that these are supporting images, any direct manipulation
        # of the content field must also store this updated information
        # into the other corresponding fields of TextAreaField:
        # (perhaps eventually a property should be made for TextAreaField
        #  such that these extra set's are not necessary, but for now, here:)
        self.article.content_w_resourcePaths = self.article.content
        self.article.content_wo_resourcePaths = self.article.content
示例#35
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
        hasElpLink = 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 hasElpLink 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 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 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 hasElpLink or package.get_exportElp():
            # Export the elp file
            currentPackagePath = Path(package.filename)
            currentPackagePath.copyfile(contentPages/package.name+'.elp')
        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()
示例#36
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 sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        self.styleDir.copylist(styleFiles, outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(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)

        # Create the manifest file
        manifest = Manifest(self.config, outputDir, package, self.pages, self.metadataType)
        manifest.save("imsmanifest.xml")
        
        # Copy the scripts
        
        # 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
        hasWikipedia      = False
        isBreak           = False
        hasInstructions   = False
        hasMediaelement   = False
        hasTooltips       = 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 hasMediaelement and hasTooltips):
                    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 hasMediaelement:
                    hasMediaelement = common.ideviceHasMediaelement(idevice)
                if not hasTooltips:
                    hasTooltips = common.ideviceHasTooltips(idevice)

        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)
        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 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()
示例#37
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        # copy the package's resource files
        package.resourceDir.copyfiles(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
        self.pages = [ ScormPage("index", 1, package.root,
            scormType=self.scormType) ]

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

        for page in self.pages:
            page.save(outputDir)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")
        
        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles  = [self.styleDir/'..'/'base.css']
        styleFiles += [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += [f for f in self.styleDir.files("*.css")
                if f.basename() <> "nav.css"] 
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        # 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
        if self.scormType == "commoncartridge":
            for sf in styleFiles[:]:
                if sf.basename() not in manifest.dependencies:
                    styleFiles.remove(sf)
        self.styleDir.copylist(styleFiles, outputDir)

        # Copy the scripts
        if self.scormType == "commoncartridge":
            self.scriptsDir.copylist(('libot_drag.js',
                                      'common.js'), outputDir)
        else:
            self.scriptsDir.copylist(('APIWrapper.js', 
                                      'lernmodule_net.js',
                                      'SCOFunctions.js', 
                                      'libot_drag.js',
                                      'common.js'), outputDir)
        schemasDir = ""
        if self.scormType == "scorm1.2":
            schemasDir = self.schemasDir/"scorm1.2"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                'imsmd_rootv1p2p1.xsd',
                                'adlcp_rootv1p2.xsd',
                                'ims_xml.xsd'), outputDir)
        elif self.scormType == "scorm2004":
            schemasDir = self.schemasDir/"scorm2004"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                'imsmd_rootv1p2p1.xsd',
                                'adlcp_rootv1p2.xsd',
                                'ims_xml.xsd'), outputDir)
 
        # copy players for media idevices.                
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False
        hasGallery        = False
        isBreak           = False
        
        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery):
                    isBreak = True
                    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 not hasGallery:
                    if 'GalleryIdevice' == idevice.klass:
                        hasGallery = True
                        
        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/'magnifier.swf')
            videofile.copyfile(outputDir/'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(outputDir/'xspf_player.swf')
        if hasGallery:
            imageGalleryCSS = (self.cssDir/'exe_lightbox.css')
            imageGalleryCSS.copyfile(outputDir/'exe_lightbox.css') 
            imageGalleryJS = (self.scriptsDir/'exe_lightbox.js')
            imageGalleryJS.copyfile(outputDir/'exe_lightbox.js') 
            self.imagesDir.copylist(('exeGallery_actions.png', 'exeGallery_loading.gif'), outputDir)

        if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
            if package.license == "GNU Free Documentation License":
                # include a copy of the GNU Free Documentation Licence
                (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
        
        if hasattr(package, 'scowsinglepage') and package.scowsinglepage:
            page = SinglePage("singlepage_index", 1, package.root)
            page.save(outputDir/"singlepage_index.html")
        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')
        if hasattr(package, 'scowsource') and package.scowsource:
            (G.application.config.xulDir/'templates'/'content.xsd').copyfile(outputDir/'content.xsd')
            (outputDir/'content.data').write_bytes(encodeObject(package))
            (outputDir/'contentv2.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()
示例#38
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')
        quizContentPages = Path(outputDir.abspath() + '/EPUB/tools/quiz')
        quizImagesPages = Path(quizContentPages.abspath() + '/images')
        quizScriptsPages = Path(quizContentPages.abspath() + '/scripts')
        quizVideoPages = Path(quizContentPages.abspath() + '/video')
        quizCssPages = Path(quizContentPages.abspath() + '/css')
        quizFilesPages = Path(quizContentPages.abspath() + '/css')
        # contentPages = outputDir/'Content'
        contentPages.mkdir()
        quizContentPages.makedirs()
        quizImagesPages.mkdir()
        quizScriptsPages.mkdir()
        quizVideoPages.mkdir()
        quizCssPages.mkdir()
        quizFilesPages.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)
            if hasattr(page, 'cover'):
                cover = page.cover

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

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

        imgStyleFiles = [self.styleDir / '..' / 'popup_bg.gif']
        imgStyleFiles += self.styleDir.files("*.jpg")
        imgStyleFiles += self.styleDir.files("*.gif")
        imgStyleFiles += self.styleDir.files("*.png")

        scriptStyleFiles = self.styleDir.files("*.js")

        filesStyleFiles = self.styleDir.files("*.html")
        filesStyleFiles += self.styleDir.files("*.ttf")
        filesStyleFiles += self.styleDir.files("*.eot")
        filesStyleFiles += self.styleDir.files("*.otf")
        filesStyleFiles += self.styleDir.files("*.woff")
        # 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

        package.resourceDir.copyfiles(contentPages)

        self.styleDir.copylist(cssStyleFiles, quizCssPages)
        self.styleDir.copylist(imgStyleFiles, quizImagesPages)
        self.styleDir.copylist(scriptStyleFiles, quizScriptsPages)
        self.styleDir.copylist(filesStyleFiles, quizFilesPages)


        self.scriptsDir.copylist(('common.js',), quizScriptsPages)

        # 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

        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):
                    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 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)
        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)

        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')

#         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()
示例#39
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / '..' / 'base.css']
        styleFiles += [self.styleDir / '..' / 'popup_bg.gif']
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        self.styleDir.copylist(styleFiles, outputDir)

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

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

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

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

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

        # Copy the scripts - with modification by lernmodule.net
        self.scriptsDir.copylist(
            ('libot_drag.js', 'lernmodule_net.js', 'common.js'), outputDir)

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

        # copy players for media idevices.
        hasFlowplayer = False
        hasMagnifier = False
        hasXspfplayer = False
        hasGallery = False
        isBreak = False

        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer
                        and hasGallery):
                    isBreak = True
                    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 not hasGallery:
                    if 'GalleryIdevice' == idevice.klass:
                        hasGallery = True

        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 / 'magnifier.swf')
            videofile.copyfile(outputDir / 'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir / 'xspf_player.swf')
            videofile.copyfile(outputDir / 'xspf_player.swf')
        if hasGallery:
            imageGalleryCSS = (self.cssDir / 'exe_lightbox.css')
            imageGalleryCSS.copyfile(outputDir / 'exe_lightbox.css')
            imageGalleryJS = (self.scriptsDir / 'exe_lightbox.js')
            imageGalleryJS.copyfile(outputDir / 'exe_lightbox.js')
            self.imagesDir.copylist(
                ('exeGallery_actions.png', 'exeGallery_loading.gif'),
                outputDir)

        if package.license == "GNU Free Documentation License":
            # 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()
示例#40
0
class Package(Persistable):
    """
    Package represents the collection of resources the user is editing
    i.e. the "package".
    """
    persistenceVersion = 7
    nonpersistant      = ['resourceDir', 'filename']
    _name              = '' 
    _title             = '' 
    _author            = ''
    _description       = ''
    _backgroundImg     = ''
    defaultLevelNames  = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]
    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId    = 0
        self._nodeIdDict    = {} 
        self._levelNames    = self.defaultLevelNames[:]
        self.name           = name
        self._title         = u''
        self._backgroundImg = u''
        self.backgroundImgTile = False
        self.filename      = u''
        self.root          = Node(self, None, _(u"Home"))
        self.currentNode   = self.root
        self.style         = u"default"
        self.isChanged     = 0
        self.idevices      = []
        self.dublinCore    = DublinCore()
        self.scolinks      = False
        self.resourceDir = TempDirPath()
    def set_name(self, value):
        self._name = toUnicode(value)
    def set_title(self, value):
        self._title = toUnicode(value)
    def set_author(self, value):
        self._author = toUnicode(value)
    def set_description(self, value):
        self._description = toUnicode(value)
    def get_backgroundImg(self):
        """Get the background image for this package"""
        if self._backgroundImg:
            return "file://" + self._backgroundImg.path
        else:
            return ""
    def set_backgroundImg(self, value):
        """Set the background image for this package"""
        if self._backgroundImg:
            self._backgroundImg.delete()
        if value:
            if value.startswith("file://"):
                value = value[7:]
            imgFile = Path(value)
            self._backgroundImg = Resource(self, Path(imgFile))
        else:
            self._backgroundImg = u''
    def get_level1(self):
        return self.levelName(0)
    def set_level1(self, value):
        if value != '':
            self._levelNames[0] = value 
        else:
            self._levelNames[0] = self.defaultLevelNames[0]
    def get_level2(self):
        return self.levelName(1)
    def set_level2(self, value):
        if value != '':
            self._levelNames[1] = value 
        else:
            self._levelNames[1] = self.defaultLevelNames[1]
    def get_level3(self):
        return self.levelName(2)
    def set_level3(self, value):
        if value != '':
            self._levelNames[2] = value 
        else:
            self._levelNames[2] = self.defaultLevelNames[2]
    name          = property(lambda self:self._name, set_name)
    title         = property(lambda self:self._title, set_title)
    author        = property(lambda self:self._author, set_author)
    description   = property(lambda self:self._description, set_description)
    backgroundImg = property(get_backgroundImg, set_backgroundImg)
    level1 = property(get_level1, set_level1)
    level2 = property(get_level2, set_level2)
    level3 = property(get_level3, set_level3)
    def findNode(self, nodeId):
        """
        Finds a node from its nodeId
        (nodeId can be a string or a list/tuple)
        """
        log.debug(u"findNode" + repr(nodeId))
        node = self._nodeIdDict.get(nodeId)
        if node and node.package is self:
            return node
        else: 
            return None
    def levelName(self, level):
        """
        Return the level name
        """
        if level < len(self._levelNames):
            return _(self._levelNames[level])
        else:
            return _(u"?????")
    def save(self, filename=None):
        """
        Save package to disk
        pass an optional filename
        """
        if filename:
            filename = Path(filename)
            name = filename.splitpath()[1]
            self.name = name.basename().splitext()[0]
        elif self.filename:
            filename = Path(self.filename)
        else:
            raise AssertionError(u'No name passed when saving a new package')
        self.filename = filename
        log.debug(u"Will save %s to: %s" % (self.name, filename))
        self.isChanged = 0
        zippedFile = zipfile.ZipFile(filename, "w", zipfile.ZIP_DEFLATED)
        try:
            for resourceFile in self.resourceDir.files():
                zippedFile.write(unicode(resourceFile.normpath()),
                                 resourceFile.name.encode('utf8'))
            zippedFile.writestr("content.data", encodeObject(self))
        finally:
            zippedFile.close()
    @staticmethod
    def load(filename):
        """
        Load package from disk, returns a package
        """
        if not zipfile.is_zipfile(filename):
            return None
        zippedFile = zipfile.ZipFile(filename, "r", zipfile.ZIP_DEFLATED)
        toDecode   = zippedFile.read(u"content.data")
        try:
            newPackage = decodeObjectRaw(toDecode)
            newPackage.afterUpgradeHandlers = []
            doUpgrade()
        except:
            import traceback
            traceback.print_exc()
            raise
        newPackage.filename = Path(filename)
        newPackage.resourceDir = TempDirPath()
        for filename in zippedFile.namelist():
            if unicode(filename, 'utf8') != u"content.data":
                outFile = open(newPackage.resourceDir/filename, "wb")
                outFile.write(zippedFile.read(filename))
        for handler in newPackage.afterUpgradeHandlers:
            handler()
        del newPackage.afterUpgradeHandlers
        return newPackage
    def upgradeToVersion1(self):
        """
        Called to upgrade from 0.3 release
        """
        self._nextNodeId = 0
        self._nodeIdDict = {}
        draft = getattr(self, 'draft')
        draft._id = self._regNewNode(draft)
        draft._package = self
        setattr(self, 'editor', Node(self, None, _(u"iDevice Editor")))
        idevice = GenericIdevice("", "", "", "", "")
        editor = getattr(self, 'editor')
        idevice.parentNode = editor
        editor.addIdevice(idevice)
        def superReg(node):
            """Registers all our nodes
            because in v0 they were not registered
            in this way"""
            node._id = self._regNewNode(node)
            node._package = self
            for child in node.children:
                superReg(child)
        superReg(self.root)
    def _regNewNode(self, node):
        """
        Called only by nodes, 
        stores the node in our id lookup dict
        returns a new unique id
        """
        id_ = unicode(self._nextNodeId)
        self._nextNodeId += 1
        self._nodeIdDict[id_] = node
        return id_
    def getNewIdeviceId(self):
        """
        Returns an iDevice Id which is unique for this package.
        """
        id_ = unicode(self._nextIdeviceId)
        self._nextIdeviceId += 1
        return id_
    def upgradeToVersion2(self):
        """
        Called to upgrade from 0.4 release
        """
        getattr(self, 'draft').delete()
        getattr(self, 'editor').delete()
        delattr(self, 'draft')
        delattr(self, 'editor')
        self._nextNodeId = 0
        def renumberNode(node):
            """
            Gives the old node a number
            """
            node._id = self._regNewNode(node)
            for child in node.children:
                renumberNode(child)
        renumberNode(self.root)
    def upgradeToVersion3(self):
        """
        Also called to upgrade from 0.4 release
        """
        self._nextIdeviceId = 0
    def upgradeToVersion4(self):
        """
        Puts properties in their place
        Also called to upgrade from 0.8 release
        """
        self._name = toUnicode(self.__dict__['name'])
        self._author = toUnicode(self.__dict__['author'])
        self._description = toUnicode(self.__dict__['description'])
    def upgradeToVersion5(self):
        """
        For version 0.11
        """
        self._levelNames = self.levelNames
        del self.levelNames
    def upgradeToVersion6(self):
        """
        For version 0.14
        """
        self.dublinCore = DublinCore()
        self.title = self.root.title
        self.dublinCore.title = self.root.title
        self.dublinCore.creator = self._author
        self.dublinCore.description = self._description
        self.scolinks = False
    def upgradeToVersion7(self):
        """
        For version 0.15
        """
        self._backgroundImg = ''
        self.backgroundImgTile = False
示例#41
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        # copy the package's resource files
        package.resourceDir.copyfiles(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
        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)
            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)
        manifest.save("imsmanifest.xml")
        if self.hasForum:
            manifest.save("discussionforum.xml")
        
        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles  = [self.styleDir/'..'/'base.css']
        styleFiles += [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += [f for f in self.styleDir.files("*.css")
                if f.basename() <> "nav.css"] 
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        # 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
        if self.scormType == "commoncartridge":
            for sf in styleFiles[:]:
                if sf.basename() not in manifest.dependencies:
                    styleFiles.remove(sf)
        self.styleDir.copylist(styleFiles, outputDir)

        # Copy the scripts
        if self.scormType == "commoncartridge":
            self.scriptsDir.copylist(('libot_drag.js',
                                      'common.js'), outputDir)
        if self.scormType == "scorm2004":
            self.scriptsDir.copylist(('AC_RunActiveContent.js',
                                      'SCORM_API_wrapper.js',
                                      'SCOFunctions.js', 
                                      'libot_drag.js',
                                      'common.js'), outputDir)     
        if self.scormType != "commoncartridge" and self.scormType != "scorm2004":
            self.scriptsDir.copylist(('APIWrapper.js', 
                                      'SCOFunctions.js', 
                                      'libot_drag.js',
                                      'common.js'), outputDir)
        schemasDir = ""
        if self.scormType == "scorm1.2":
            schemasDir = self.schemasDir/"scorm1.2"
            schemasDir.copylist(('imscp_rootv1p1p2.xsd',
                                'imsmd_rootv1p2p1.xsd',
                                'adlcp_rootv1p2.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',
                                '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/"lom", outputDir/"lom")
            except OSError as exc:
                if exc.errno == errno.ENOTDIR:
                    shutil.copy(schemasDir/"lom", outputDir/"lom")
                else: raise

        # copy players for media idevices.                
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False
        hasGallery        = False
        isBreak           = False
        
        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery):
                    isBreak = True
                    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 not hasGallery:
                    if 'GalleryIdevice' == idevice.klass:
                        hasGallery = True
                        
        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/'magnifier.swf')
            videofile.copyfile(outputDir/'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(outputDir/'xspf_player.swf')
        if hasGallery:
            imageGalleryCSS = (self.cssDir/'exe_lightbox.css')
            imageGalleryCSS.copyfile(outputDir/'exe_lightbox.css') 
            imageGalleryJS = (self.scriptsDir/'exe_lightbox.js')
            imageGalleryJS.copyfile(outputDir/'exe_lightbox.js') 
            self.imagesDir.copylist(('exeGallery_actions.png', 'exeGallery_loading.gif', 'stock-insert-image.png'), outputDir)

        if self.scormType == "scorm1.2" or self.scormType == "scorm2004":
            if package.license == "GNU Free Documentation License":
                # include a copy of the GNU Free Documentation Licence
                (self.templatesDir/'fdl.html').copyfile(outputDir/'fdl.html')
        
        if hasattr(package, 'scowsinglepage') and package.scowsinglepage:
            page = SinglePage("singlepage_index", 1, package.root)
            page.save(outputDir/"singlepage_index.html")
        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')
        if hasattr(package, 'scowsource') and package.scowsource:
            (G.application.config.webDir/'templates'/'content.xsd').copyfile(outputDir/'content.xsd')
            (outputDir/'content.data').write_bytes(encodeObject(package))
            (outputDir/'contentv2.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()
示例#42
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)
            if hasattr(page, "cover"):
                cover = page.cover

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

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles = [self.styleDir / ".." / "popup_bg.gif"]
        styleFiles += [f for f in self.styleDir.files("*.css") if f.basename() != "nav.css"]
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        # 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

        package.resourceDir.copyfiles(contentPages)

        self.styleDir.copylist(styleFiles, contentPages)

        listCSSFiles = getFilesCSSToMinify("epub3", self.styleDir)
        exportMinFileCSS(listCSSFiles, outputDir)

        listFiles = []
        listOutFiles = []

        listFiles += [self.scriptsDir / "common.js"]
        listOutFiles += [outputDir / "common.js"]

        # 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

        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
                ):
                    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 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)
        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)

        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")

        listFiles = getFilesJSToMinify("epub3", self.scriptsDir)
        exportMinFileJS(listFiles, 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(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()
class Package(Persistable):
    """
    Package represents the collection of resources the user is editing
    i.e. the "package".
    """
    persistenceVersion = 9
    nonpersistant      = ['resourceDir', 'filename']
    # Name is used in filenames and urls (saving and navigating)
    _name              = '' 
    tempFile           = False # This is set when the package is saved as a temp copy file
    # Title is rendered in exports
    _title             = '' 
    _author            = ''
    _description       = ''
    _backgroundImg     = ''
    # This is like a constant
    defaultLevelNames  = [x_(u"Topic"), x_(u"Section"), x_(u"Unit")]

    def __init__(self, name):
        """
        Initialize 
        """
        log.debug(u"init " + repr(name))
        self._nextIdeviceId = 0
        self._nextNodeId    = 0
        # For looking up nodes by ids
        self._nodeIdDict    = {} 

        self._levelNames    = self.defaultLevelNames[:]
        self.name           = name
        self._title         = u''
        self._backgroundImg = u''
        self.backgroundImgTile = False

        # Empty if never saved/loaded
        self.filename      = u''

        self.root          = Node(self, None, _(u"Home"))
        self.currentNode   = self.root
        self.style         = u"default"
        self.isChanged     = False
        self.idevices      = []
        self.dublinCore    = DublinCore()
        self.scolinks      = False
        self.license       = "None"
        self.footer        = ""

        # Temporary directory to hold resources in
        self.resourceDir = TempDirPath()
        self.resources = {} # Checksum-[_Resource(),..]


    # Property Handlers

    def set_name(self, value):
        self._name = toUnicode(value)
    def set_title(self, value):
        self._title = toUnicode(value)
    def set_author(self, value):
        self._author = toUnicode(value)
    def set_description(self, value):
        self._description = toUnicode(value)

    def get_backgroundImg(self):
        """Get the background image for this package"""
        if self._backgroundImg:
            return "file://" + self._backgroundImg.path
        else:
            return ""

    def set_backgroundImg(self, value):
        """Set the background image for this package"""
        if self._backgroundImg:
            self._backgroundImg.delete()

        if value:
            if value.startswith("file://"):
                value = value[7:]

            imgFile = Path(value)
            self._backgroundImg = Resource(self, Path(imgFile))
        else:
            self._backgroundImg = u''

    def get_level1(self):
        return self.levelName(0)
    def set_level1(self, value):
        if value != '':
            self._levelNames[0] = value 
        else:
            self._levelNames[0] = self.defaultLevelNames[0]

    def get_level2(self):
        return self.levelName(1)
    def set_level2(self, value):
        if value != '':
            self._levelNames[1] = value 
        else:
            self._levelNames[1] = self.defaultLevelNames[1]

    def get_level3(self):
        return self.levelName(2)
    def set_level3(self, value):
        if value != '':
            self._levelNames[2] = value 
        else:
            self._levelNames[2] = self.defaultLevelNames[2]


    # Properties

    name          = property(lambda self:self._name, set_name)
    title         = property(lambda self:self._title, set_title)
    author        = property(lambda self:self._author, set_author)
    description   = property(lambda self:self._description, set_description)

    backgroundImg = property(get_backgroundImg, set_backgroundImg)

    level1 = property(get_level1, set_level1)
    level2 = property(get_level2, set_level2)
    level3 = property(get_level3, set_level3)

    def findNode(self, nodeId):
        """
        Finds a node from its nodeId
        (nodeId can be a string or a list/tuple)
        """
        log.debug(u"findNode" + repr(nodeId))
        node = self._nodeIdDict.get(nodeId)
        if node and node.package is self:
            return node
        else: 
            return None


    def levelName(self, level):
        """
        Return the level name
        """
        if level < len(self._levelNames):
            return _(self._levelNames[level])
        else:
            return _(u"?????")
        

    def save(self, filename=None, tempFile=False):
        """
        Save package to disk
        pass an optional filename
        """
        self.tempFile = tempFile
        # Get the filename
        if filename:
            filename = Path(filename)
            # If we are being given a new filename...
            # Change our name to match our new filename
            name = filename.splitpath()[1]
            if not tempFile:
                self.name = name.basename().splitext()[0]
        elif self.filename:
            # Otherwise use our last saved/loaded from filename
            filename = Path(self.filename)
        else:
            # If we don't have a last saved/loaded from filename,
            # raise an exception because, we need to have a new
            # file passed when a brand new package is saved
            raise AssertionError(u'No name passed when saving a new package')
        # Store our new filename for next file|save, and save the package
        log.debug(u"Will save %s to: %s" % (self.name, filename))
        if tempFile:
            self.nonpersistant.remove('filename')
            oldFilename, self.filename = self.filename, unicode(self.filename)
            try:
                filename.safeSave(self.doSave, _('SAVE FAILED!\nLast succesful save is %s.'))
            finally:
                self.nonpersistant.append('filename')
                self.filename = oldFilename
        else:
            # Update our new filename for future saves
            self.filename = filename
            filename.safeSave(self.doSave, _('SAVE FAILED!\nLast succesful save is %s.'))
            self.isChanged = False
            self.updateRecentDocuments(filename)

    def updateRecentDocuments(self, filename):
        """
        Updates the list of recent documents
        """
        # Don't update the list for the generic.data "package"
        genericData = G.application.config.configDir/'idevices'/'generic.data'
        if genericData.isfile() or genericData.islink():
            if Path(filename).samefile(genericData):
                return
        # Save in recentDocuments list
        recentProjects = G.application.config.recentProjects
        if filename in recentProjects:
            # If we're already number one, carry on
            if recentProjects[0] == filename:
                return
            recentProjects.remove(filename)
        recentProjects.insert(0, filename)
        del recentProjects[5:] # Delete any older names from the list
        G.application.config.configParser.write() # Save the settings

    def doSave(self, fileObj):
        """
        Actually performs the save to 'fileObj'.
        """
        zippedFile = zipfile.ZipFile(fileObj, "w", zipfile.ZIP_DEFLATED)
        try:
            for resourceFile in self.resourceDir.files():
                zippedFile.write(unicode(resourceFile.normpath()),
                        resourceFile.name.encode('utf8'), zipfile.ZIP_DEFLATED)

            zinfo = zipfile.ZipInfo(filename='content.data',
                    date_time=time.localtime()[0:6])
            zinfo.external_attr = 0100644<<16L
            zippedFile.writestr(zinfo, encodeObject(self))
        finally:
            zippedFile.close()

    def extractNode(self):
        """
        Clones and extracts the currently selected node into a new package.
        """
        newPackage = Package('NoName') # Name will be set once it is saved..
        newPackage.title  = self.currentNode.title
        newPackage.style  = self.style
        newPackage.author = self.author
        newPackage._nextNodeId = self._nextNodeId
        # Copy the nodes from the original package
        # and merge into the root of the new package
        self.currentNode.copyToPackage(newPackage)
        return newPackage

    @staticmethod
    def load(filename, newLoad=True, destinationPackage=None):
        """
        Load package from disk, returns a package.
        """
        if not zipfile.is_zipfile(filename):
            return None

        zippedFile = zipfile.ZipFile(filename, "r")
        
        try:
            # Get the jellied package data
            toDecode   = zippedFile.read(u"content.data")
        except KeyError:
            log.info("no content.data, trying Common Cartridge/Content Package")
            newPackage = loadCC(zippedFile, filename)
            newPackage.tempFile = False
            newPackage.isChanged = False
            newPackage.filename = Path(filename)

            return newPackage
            
        # Need to add a TempDirPath because it is a nonpersistant member
        resourceDir = TempDirPath()

        # Extract resource files from package to temporary directory
        for fn in zippedFile.namelist():
            if unicode(fn, 'utf8') != u"content.data":
                outFile = open(resourceDir/fn, "wb")
                outFile.write(zippedFile.read(fn))
                outFile.flush()
                outFile.close()

        try:
            newPackage = decodeObjectRaw(toDecode)
            G.application.afterUpgradeHandlers = []
            newPackage.resourceDir = resourceDir
            G.application.afterUpgradeZombies2Delete = []

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

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

                doUpgrade(newPackage)

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

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

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

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

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

        except:
            import traceback
            traceback.print_exc()
            raise

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

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

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

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

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

        G.application.afterUpgradeHandlers = []

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

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

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

    def cleanUpResources(self):
        """
        Removes duplicate resource files
        """
        # Delete unused resources.
        # Only really needed for upgrading to version 0.20,
        # but upgrading of resources and package happens in no particular order
        # and must be done after all resources have been upgraded

        # some earlier .elp files appear to have been corrupted with 
        # two packages loaded, *possibly* from some strange extract/merge
        # functionality in earlier eXe versions?
        # Regardless, only the real package will have a resourceDir,
        # and the other will fail.
        # For now, then, put in this quick and easy safety check:
        if not hasattr(self,'resourceDir'):
            log.warn("cleanUpResources called on a redundant package")
            return

        existingFiles = set([fn.basename() for fn in self.resourceDir.files()])
        usedFiles = set([reses[0].storageName for reses in self.resources.values()])
        for fn in existingFiles - usedFiles:
            (self.resourceDir/fn).remove()

    def findResourceByName(self, queryName):
        """
        Support for merging, and anywhere else that unique names might be
        checked before actually comparing against the files (as will be 
        done by the resource class itself in its _addOurselvesToPackage() )
        """
        foundResource = None
        queryResources = self.resources
        for this_checksum in queryResources:
            for this_resource in queryResources[this_checksum]:
                if queryName == this_resource.storageName:
                    foundResource = this_resource
                    return foundResource
        return foundResource


    def upgradeToVersion1(self):
        """
        Called to upgrade from 0.3 release
        """
        self._nextNodeId = 0
        self._nodeIdDict = {}

        # Also upgrade all the nodes.
        # This needs to be done here so that draft gets id 0
        # If it's done in the nodes, the ids are assigned in reverse order
        draft = getattr(self, 'draft')
        draft._id = self._regNewNode(draft)
        draft._package = self
        setattr(self, 'editor', Node(self, None, _(u"iDevice Editor")))

        # Add a default idevice to the editor
        idevice = GenericIdevice("", "", "", "", "")
        editor = getattr(self, 'editor')
        idevice.parentNode = editor
        editor.addIdevice(idevice)
        def superReg(node):
            """Registers all our nodes
            because in v0 they were not registered
            in this way"""
            node._id = self._regNewNode(node)
            node._package = self
            for child in node.children:
                superReg(child)
        superReg(self.root)


    def _regNewNode(self, node):
        """
        Called only by nodes, 
        stores the node in our id lookup dict
        returns a new unique id
        """
        id_ = unicode(self._nextNodeId)
        self._nextNodeId += 1
        self._nodeIdDict[id_] = node
        return id_


    def getNewIdeviceId(self):
        """
        Returns an iDevice Id which is unique for this package.
        """
        id_ = unicode(self._nextIdeviceId)
        self._nextIdeviceId += 1
        return id_


    def upgradeToVersion2(self):
        """
        Called to upgrade from 0.4 release
        """
        getattr(self, 'draft').delete()
        getattr(self, 'editor').delete()
        delattr(self, 'draft')
        delattr(self, 'editor')
        # Need to renumber nodes because idevice node and draft nodes are gone
        self._nextNodeId = 0
        def renumberNode(node):
            """
            Gives the old node a number
            """
            node._id = self._regNewNode(node)
            for child in node.children:
                renumberNode(child)
        renumberNode(self.root)


    def upgradeToVersion3(self):
        """
        Also called to upgrade from 0.4 release
        """
        self._nextIdeviceId = 0


    def upgradeToVersion4(self):
        """
        Puts properties in their place
        Also called to upgrade from 0.8 release
        """
        self._name = toUnicode(self.__dict__['name'])
        self._author = toUnicode(self.__dict__['author'])
        self._description = toUnicode(self.__dict__['description'])


    def upgradeToVersion5(self):
        """
        For version 0.11
        """
        self._levelNames = self.levelNames
        del self.levelNames
    
    def upgradeToVersion6(self):
        """
        For version 0.14
        """
        self.dublinCore = DublinCore()
        # Copy some of the package properties to dublin core
        self.title = self.root.title
        self.dublinCore.title = self.root.title
        self.dublinCore.creator = self._author
        self.dublinCore.description = self._description
        self.scolinks = False

    def upgradeToVersion7(self):
        """
        For version 0.15
        """
        self._backgroundImg = ''
        self.backgroundImgTile = False
        
    def upgradeToVersion8(self):
        """
        For version 0.20, alpha, for nightlies r2469
        """
        self.license = 'None'
        self.footer = ""
        self.idevices = []

    def upgradeToVersion9(self):
        """
        For version >= 0.20.4
        """
        if not hasattr(self, 'resources'):
            # The hasattr is needed, because sometimes, Resource instances are upgraded
            # first and they also set this attribute on the package
            self.resources = {}
        G.application.afterUpgradeHandlers.append(self.cleanUpResources)
    def testExport(self):
        # Delete the output dir
        outdir = TempDirPath()
        
        G.application = Application()
        
        G.application.loadConfiguration()
        G.application.preLaunch()
        
        # Load a package
        package = Package.load('testing/testPackage2.elp')
        # Do the export
        style_dir = G.application.config.stylesDir / package.style
        
        exporter = WebsiteExport(G.application.config,
                                 style_dir, 
                                 outdir)
        
        exporter.export(package)
        # Check that it all exists now
        assert outdir.isdir()
        assert (outdir / 'index.html').isfile()
        # Check that the style sheets have been copied
        for filename in style_dir.files():
            
            #Skip the styles config.xml - that should not be included
            if filename.basename() == "config.xml":
                continue
            
            assert ((outdir / filename.basename()).exists(),
                    'Style file "%s" not copied' % (outdir / filename.basename()))
            #check the modification time is correct
            f_dst = Path(outdir/filename.basename())
            f_src = Path(filename)
            
            self.assertTrue(
                TestUtils.mod_time_diff(f_dst, f_src) < 0.1,
                "Modification time in style dir preserved")

        for res_file in package.resourceDir.files():
            dst_file = Path(outdir/ res_file.basename())
            self.assertTrue(dst_file.isfile())
            
            self.assertTrue(
                TestUtils.mod_time_diff(res_file, dst_file) < 0.1,
                "Resource file %s has same mod time as origin" \
                % res_file.basename())

        #test that everything that was copied hahs the right mod time
        copy_list = package.make_system_copy_list(style_dir, 
                                  G.application.config.webDir/"scripts" , 
                                  G.application.config.webDir/"templates", 
                                  G.application.config.webDir/"images", 
                                  G.application.config.webDir/"css", 
                                  outdir)
        TestUtils.check_copy_list_mod_time(copy_list, self)

        # Check that each node in the package has had a page made
        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, outdir)
示例#45
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((Path(idevice._iDeviceDir)/'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()
示例#46
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()
示例#47
0
    def export(self, package):
        """ 
        Export SCORM package
        """
        # First do the export to a temporary directory
        outputDir = TempDirPath()

        # Copy the style sheet files to the output dir
        # But not nav.css
        styleFiles  = [self.styleDir/'..'/'base.css']
        styleFiles += [self.styleDir/'..'/'popup_bg.gif']
        styleFiles += self.styleDir.files("*.css")
        if "nav.css" in styleFiles:
            styleFiles.remove("nav.css")
        styleFiles += self.styleDir.files("*.jpg")
        styleFiles += self.styleDir.files("*.gif")
        styleFiles += self.styleDir.files("*.png")
        styleFiles += self.styleDir.files("*.js")
        styleFiles += self.styleDir.files("*.html")
        styleFiles += self.styleDir.files("*.ttf")
        styleFiles += self.styleDir.files("*.eot")
        styleFiles += self.styleDir.files("*.otf")
        styleFiles += self.styleDir.files("*.woff")
        self.styleDir.copylist(styleFiles, outputDir)

        # copy the package's resource files
        package.resourceDir.copyfiles(outputDir)
            
        # Export the package content
        self.pages = [ IMSPage("index", 1, package.root) ]

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

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

        # Create the manifest file
        manifest = Manifest(self.config, outputDir, package, self.pages)
        manifest.save()
        
        # Copy the scripts
        self.scriptsDir.copylist(('libot_drag.js',
                                  'common.js'), outputDir)
        
        self.schemasDir.copylist(('imscp_v1p1.xsd',
                                  'imsmd_v1p2p2.xsd',
                                  'ims_xml.xsd'), outputDir)

        # copy players for media idevices.                
        hasFlowplayer     = False
        hasMagnifier      = False
        hasXspfplayer     = False
        hasGallery        = False
        isBreak           = False
        
        for page in self.pages:
            if isBreak:
                break
            for idevice in page.node.idevices:
                if (hasFlowplayer and hasMagnifier and hasXspfplayer and hasGallery):
                    isBreak = True
                    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 not hasGallery:
                    if 'GalleryIdevice' == idevice.klass:
                        hasGallery = True
                        
        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/'magnifier.swf')
            videofile.copyfile(outputDir/'magnifier.swf')
        if hasXspfplayer:
            videofile = (self.templatesDir/'xspf_player.swf')
            videofile.copyfile(outputDir/'xspf_player.swf')
        if hasGallery:
            imageGalleryCSS = (self.cssDir/'exe_lightbox.css')
            imageGalleryCSS.copyfile(outputDir/'exe_lightbox.css') 
            imageGalleryJS = (self.scriptsDir/'exe_lightbox.js')
            imageGalleryJS.copyfile(outputDir/'exe_lightbox.js') 
            self.imagesDir.copylist(('exeGallery_actions.png', 'exeGallery_loading.gif', 'stock-insert-image.png'), outputDir)

        if package.license == "GNU Free Documentation License":
            # 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()