def gen_linear_archive(self): config = self._request.get_configuration() data = self._request.get_data() root = config["datadir"] archives = {} archive_list = tools.get_entries(config, root) fulldict = {} fulldict.update(config) fulldict.update(data) template = config.get('archive_template', '<a href="%(base_url)s/%(Y)s/%(b)s">%(Y)s-%(b)s</a><br />') for mem in archive_list: timetuple = tools.filestat(self._request, mem) timedict = {} for x in ["B", "b", "m", "Y", "y"]: timedict[x] = time.strftime("%" + x, timetuple) fulldict.update(timedict) if not (timedict['Y'] + timedict['m']) in archives: archives[timedict['Y'] + timedict['m']] = (template % fulldict) result = [] for key in sorted(archives.keys(), reverse=True): result.append(archives[key]) self._archives = '\n'.join(result)
def __init__(self, request, filename, root, datadir=""): """ :param request: the Request object :param filename: the complete filename for the file in question including path :param root: i have no clue what this is :param datadir: the datadir """ base.EntryBase.__init__(self, request) self._config = request.get_configuration() self._filename = filename.replace(os.sep, '/') self._root = root.replace(os.sep, '/') self._datadir = datadir or self._config["datadir"] if self._datadir.endswith(os.sep): self._datadir = self._datadir[:-1] self._timetuple = tools.filestat(self._request, self._filename) self._mtime = time.mktime(self._timetuple) self._fulltime = time.strftime("%Y%m%d%H%M%S", self._timetuple) self._populated_data = 0
def gen_linear_archive(self): config = self._request.get_configuration() data = self._request.get_data() root = config["datadir"] baseurl = config.get("base_url", "") archives = {} archive_list = tools.walk(self._request, root) items = [] fulldict = {} fulldict.update(config) fulldict.update(data) theme = data.get( "theme", config.get("default_theme", "html")) template = config.get( 'archive_template', '<a href="%(base_url)s/%(Y)s/index.%(f)s">%(Y)s</a><br />') for mem in archive_list: timetuple = tools.filestat(self._request, mem) timedict = {} for x in ["m", "Y", "y", "d"]: timedict[x] = time.strftime("%" + x, timetuple) fulldict.update(timedict) fulldict["f"] = theme year = fulldict["Y"] if not year in archives: archives[year] = template % fulldict items.append( ["%(Y)s-%(m)s" % fulldict, "%(Y)s-%(m)s-%(d)s" % fulldict, time.mktime(timetuple), mem]) arc_keys = archives.keys() arc_keys.sort() arc_keys.reverse() result = [] for key in arc_keys: result.append(archives[key]) self._archives = '\n'.join(result) self._items = items
def cmd_persistdate(command, argv): from douglas.cmdline import import_config config = import_config() datadir = config.py.get('datadir') if not datadir: raise ValueError('config.py has no datadir property.') from douglas import tools from douglas.app import Douglas p = Douglas(config.py, {}) p.initialize() req = p.get_request() tools.run_callback('start', {'request': req}) filelist = tools.get_entries(config, datadir) print '%d files' % len(filelist) for fn in filelist: lines = open(fn, 'r').readlines() try: metadata = get_metadata(lines) except IndexError as exc: print '%s errored out: %s' % (fn, exc) continue if 'published' in metadata: print '%s already has metadata...' % fn continue print 'working on %s...' % fn timetuple = tools.filestat(req, fn) published = time.strftime('%Y-%m-%d %H:%M:%S', timetuple) lines.insert(1, '#published %s\n' % published) fp = open(fn, 'w') fp.write(''.join(lines)) fp.close()
def run_static_renderer(self, incremental=False): """This will go through all possible things in the blog and statically render everything to the ``static_dir`` specified in the config file. This figures out all the possible ``path_info`` settings and calls ``self.run()`` a bazillion times saving each file. :param incremental: Whether (True) or not (False) to incrementally render the pages. If we're incrementally rendering pages, then we render only the ones that have changed. """ self.initialize() config = self._request.get_configuration() data = self._request.get_data() print "Performing static rendering." if incremental: print "Incremental is set." staticdir = config.get("static_dir", "") datadir = config["datadir"] if not staticdir: print "Error: You must set static_dir in your config file." return 0 themes = config.get("static_themes", ["html"]) index_themes = config.get("static_index_themes", ["html"]) renderme = [] monthnames = config.get("static_monthnames", True) monthnumbers = config.get("static_monthnumbers", False) yearindexes = config.get("static_yearindexes", True) dates = {} categories = {} # first we handle entries and categories listing = tools.walk(self._request, datadir) for mem in listing: # skip the ones that have bad extensions ext = mem[mem.rfind(".")+1:] if not ext in data["extensions"].keys(): continue # grab the mtime of the entry file mtime = time.mktime(tools.filestat(self._request, mem)) # remove the datadir from the front and the bit at the end mem = mem[len(datadir):mem.rfind(".")] # this is the static filename fn = os.path.normpath(staticdir + mem) # grab the mtime of one of the statically rendered file try: smtime = os.stat(fn + "." + themes[0])[8] except: smtime = 0 # if the entry is more recent than the static, we want to # re-render if smtime < mtime or not incremental: # grab the categories temp = os.path.dirname(mem).split(os.sep) for i in range(len(temp)+1): p = os.sep.join(temp[0:i]) categories[p] = 0 # grab the date mtime = time.localtime(mtime) year = time.strftime("%Y", mtime) month = time.strftime("%m", mtime) day = time.strftime("%d", mtime) if yearindexes: dates[year] = 1 if monthnumbers: dates[year + "/" + month] = 1 dates[year + "/" + month + "/" + day] = 1 if monthnames: monthname = tools.num2month[month] dates[year + "/" + monthname] = 1 dates[year + "/" + monthname + "/" + day] = 1 # toss in the render queue for f in themes: renderme.append((mem + "." + f, "")) print "rendering %d entries." % len(renderme) # handle categories categories = categories.keys() categories.sort() # if they have stuff in their root category, it'll add a "/" # to the category list and we want to remove that because it's # a duplicate of "". if "/" in categories: categories.remove("/") print "rendering %d category indexes." % len(categories) for mem in categories: mem = os.path.normpath(mem + "/index.") for f in index_themes: renderme.append((mem + f, "")) # now we handle dates dates = dates.keys() dates.sort() dates = ["/" + d for d in dates] print "rendering %d date indexes." % len(dates) for mem in dates: mem = os.path.normpath(mem + "/index.") for f in index_themes: renderme.append((mem + f, "")) # now we handle arbitrary urls additional_stuff = config.get("static_urls", []) print "rendering %d arbitrary urls." % len(additional_stuff) for mem in additional_stuff: if mem.find("?") != -1: url = mem[:mem.find("?")] query = mem[mem.find("?")+1:] else: url = mem query = "" renderme.append((url, query)) # now we pass the complete render list to all the plugins via # cb_staticrender_filelist and they can add to the filelist # any (url, query) tuples they want rendered. print "(before) building %s files." % len(renderme) tools.run_callback("staticrender_filelist", {'request': self._request, 'filelist': renderme, 'themes': themes, 'incremental': incremental}) renderme = sorted(set(renderme)) print "building %s files." % len(renderme) for url, q in renderme: url = url.replace(os.sep, "/") print "rendering '%s' ..." % url tools.render_url_statically(dict(config), url, q) # we're done, clean up self.cleanup()
def check_mtime(cfg, now, path): mtime = time.mktime(filestat(cfg, path)) return mtime < now
def run_compile(self, incremental=False): """Compiles the blog into an HTML site. This will go through all possible things in the blog and compile the blog to the ``compiledir`` specified in the config file. This figures out all the possible ``path_info`` settings and calls ``self.run()`` a bazillion times saving each file. :param incremental: Whether (True) or not (False) to compile incrementally. If we're incrementally compiling, then only the urls that are likely to have changed get re-compiled. """ self.initialize() cfg = self._request.get_configuration() compiledir = cfg['compiledir'] datadir = cfg['datadir'] if not compiledir: print 'Error: You must set compiledir in your config file.' return 0 print 'Compiling to "{0}".'.format(compiledir) if incremental: print 'Incremental is set.' print '' themes = cfg['compile_themes'] index_themes = cfg['compile_index_themes'] dayindexes = cfg['day_indexes'] monthindexes = cfg['month_indexes'] yearindexes = cfg['year_indexes'] renderme = [] dates = {} categories = {} # first we handle entries and categories listing = tools.get_entries(cfg, datadir) for mem in listing: # Skip files that have extensions we don't know what to do # with. ext = os.path.splitext(mem)[1].lstrip('.') if not ext in cfg['extensions'].keys(): continue # Get the mtime of the entry. mtime = time.mktime(tools.filestat(self._request, mem)) # remove the datadir from the front and the bit at the end mem = mem[len(datadir):mem.rfind('.')] # This is the compiled file filename. fn = os.path.normpath(compiledir + mem) if incremental: # If we're incrementally rendering, we check the mtime # for the compiled file for one of the themes. If the entry # is more recent than the compiled version, we recompile. # Otherwise we skip it. try: smtime = os.stat(fn + '.' + themes[0])[8] if smtime < mtime or not incremental: continue except (IOError, OSError): pass # Figure out category indexes to re-render. temp = os.path.dirname(mem).split(os.sep) for i in range(len(temp)+1): p = os.sep.join(temp[0:i]) categories[p] = 0 # Figure out year/month/day indexes to re-render. mtime = time.localtime(mtime) year = time.strftime('%Y', mtime) month = time.strftime('%m', mtime) day = time.strftime('%d', mtime) if yearindexes: dates[year] = 1 if monthindexes: dates[year + '/' + month] = 1 if dayindexes: dates[year + '/' + month + '/' + day] = 1 # Toss each theme for this entry in the render queue. for f in themes: renderme.append((mem + '.' + f, '')) print '- Found {0} entry(es) ...'.format(len(renderme)) if categories: categories = sorted(categories.keys()) # if they have stuff in their root category, it'll add a "/" # to the category list and we want to remove that because it's # a duplicate of "". if '/' in categories: categories.remove('/') print '- Found {0} category index(es) ...'.format(len(categories)) for mem in categories: mem = os.path.normpath(mem + '/index.') for f in index_themes: renderme.append((mem + f, '')) if dates: dates = ['/' + d for d in sorted(dates.keys())] print '- Found {0} date index(es) ...'.format(len(dates)) for mem in dates: mem = os.path.normpath(mem + '/index.') for f in index_themes: renderme.append((mem + f, '')) additional_stuff = cfg['compile_urls'] if additional_stuff: print '- Found {0} arbitrary url(s) ...'.format( len(additional_stuff)) for mem in additional_stuff: if mem.find('?') != -1: url = mem[:mem.find('?')] query = mem[mem.find('?')+1:] else: url = mem query = '' renderme.append((url, query)) # Pass the complete render list to all the plugins via # cb_compile_filelist and they can add to the filelist any # (url, query) tuples they want rendered. total = len(renderme) tools.run_callback('compile_filelist', {'request': self._request, 'filelist': renderme, 'themes': themes, 'incremental': incremental}) renderme = sorted(set(renderme)) print '- Found {0} url(s) specified by plugins ...'.format( len(renderme) - total) print '' print 'Compiling {0} url(s) total.'.format(len(renderme)) print '' print 'Rendering files ...' for url, q in renderme: url = url.replace(os.sep, '/') print ' Rendering {0} ...'.format(url) tools.render_url_statically(dict(cfg), url, q) # We're done, clean up self.cleanup()