import os import subprocess contentDirectory = "content" renderedDirectory = "renderedContent" # Pairs of extension, pandoc read type # HTML->HTML is essentially a copy, with some pandoc sugar added (see pandoc docs) convertableContentTypes = [(".org", "org"), (".html", "html")] contentExtensions = [] for contentType in convertableContentTypes: contentExtensions.append(contentType[0]) contentExtensions = tuple(contentExtensions) renderedContentTypes = [(".html", "html")] defaultRenderedTypeIndex = 0 renderedContentExtensions = [] for contentType in renderedContentTypes: renderedContentExtensions.append(contentType[0]) renderedContentExtensions = tuple(renderedContentExtensions) def getContentReadType(contentFilename): contentExtension = contentFilename[contentFilename.rfind("."):] for contentType in convertableContentTypes: if contentExtension == contentType[0]: return contentType[1] # Strip the content directory def getContentLocalName(contentFilename): return contentFilename[len(contentDirectory):] # Strip the rendered directory def getRenderedLocalName(filename): return filename[len(renderedDirectory):] def stripExtension(filename): return filename[:filename.rfind(".")] def contentFilenameToRenderedFilename(contentFilename): return "{}{}{}".format(renderedDirectory, stripExtension(getContentLocalName(contentFilename)), renderedContentTypes[defaultRenderedTypeIndex][0]) def renderContent(contentFilename): # Content modified recently; render it print("\tRendering {}".format(contentFilename)) outputFilename = contentFilenameToRenderedFilename(contentFilename) # Make subdirectory if necessary if not os.path.exists(os.path.dirname(outputFilename)): os.makedirs(os.path.dirname(outputFilename)) # TODO: Support multiple output formats? subprocess.run(["pandoc", "-r", getContentReadType(contentFilename), "-w", renderedContentTypes[defaultRenderedTypeIndex][1], "-o", outputFilename, contentFilename]) # List of all content files contentCache = [] renderedCache = [] renderedDictionary = {} def updateRenderedCache(): global renderedCache global renderedDictionary renderedCache = [] # Get all rendered files for root, dirs, files in os.walk(renderedDirectory): for file in files: if file.endswith(renderedContentExtensions): renderedFile = os.path.join(root, file) renderedCache.append(renderedFile) # The path actually used to look up the content (strip '/' from front) contentPath = getRenderedLocalName(stripExtension(renderedFile))[1:] print("\t'{}' = '{}'".format(contentPath, renderedFile)) # No use for the value yet, we just want fast key lookups renderedDictionary[contentPath] = renderedFile """ Interface """ def getAllPostsList(): allPosts = [] for key, value in renderedDictionary.items(): allPosts.append(key) return allPosts def getRenderedBody(contentPath): body = None if contentPath in renderedDictionary: renderedFilename = renderedDictionary[contentPath] renderedFile = open(renderedFilename) body = renderedFile.readlines() body = "".join(body) renderedFile.close() return body def checkForContentChange(): global contentCache print("Checking for content updates...") # Get all content files contentCache = [] for root, dirs, files in os.walk(contentDirectory): for file in files: if file.endswith(contentExtensions): contentCache.append(os.path.join(root, file)) updateRenderedCache() numRenderedFiles = 0 # Compare timestamps to determine which files need regeneration for contentFilename in contentCache: contentModified = os.path.getmtime(contentFilename) contentLocalName = getContentLocalName(contentFilename) renderedFileFound = False for renderedFile in renderedCache: if stripExtension(renderedFile[len(renderedDirectory):]) != stripExtension(contentLocalName): continue renderedFileFound = True renderedModified = os.path.getmtime(renderedFile) # Modified content if contentModified > renderedModified: renderContent(contentFilename) numRenderedFiles += 1 # New content file if not renderedFileFound: renderContent(contentFilename) numRenderedFiles += 1 # We generated new content; make sure the cache is up-to-date if numRenderedFiles: updateRenderedCache() print("Checking for content updates done. Rendered {} files".format(numRenderedFiles))