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 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()
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)
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(),..]
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()
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()
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' ', u' ') # 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('>', '>') imageName = imageName.replace('<', '<') imageName = imageName.replace('"', '"') imageName = imageName.replace(' ', '') 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
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()
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 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()
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()
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()
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' ', u' ') # 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
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()
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
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()
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())