From the desk of Brent Huisman

Plugins

Deze website heb ik gebouwd op basis van de static site generator Obraz. Het is een enkel .py script van ~500LOC, en dat sprak me aan omdat er zo nog enige kans is dat ik er iets van begrijp en er aanvullingen voor kan schrijven. Dat laatste is gelukt. Hieronder vind je de plugins die ik heb geschreven en gebruik.

codeview.py

import obraz,os,random,cgi
try:
from urllib.request import pathname2url, url2pathname
except ImportError:
from urllib import pathname2url, url2pathname

def process_codeview(basedir, destdir, site):
  """Retrieving source and generating code view."""
  
  def get_code(infile):
    try:
      desc = open(infile, 'r').read()
    except IOError:
      desc = ''
    return cgi.escape(desc, True).replace('\n','<br>').replace('\t','&nbsp&nbsp')
  
  for page in site.get('pages', []):
    sourcedir = '/_' + page['url'][1:]
    #if not os.path.isdir(url2pathname(os.getcwd() + sourcedir)):
    #doesn't work for some reason
    sourcefiles = []
    for root, dirnames, filenames in os.walk(url2pathname(os.getcwd() + sourcedir)):
      for filename in filenames:
        sourcefiles.append(os.path.join(root, filename))
    codeview = ''
    
    for file in sourcefiles:
      filename = pathname2url(file).replace(pathname2url(os.getcwd())+sourcedir,'')
      codeview += '<a class="exp" href="#' + filename + '" name="' + filename + '"><h2>' + filename + '</h2></a><div><pre>' + get_code(file) + '</pre></div>'
    
    page['content'] = page['content'].replace('[codeview]',codeview)

obraz.processors.insert(0, process_codeview)

gallery.py

import obraz,os,glob,Image,ImageOps,random
try:
from urllib.request import pathname2url, url2pathname
except ImportError:
from urllib import pathname2url, url2pathname

def process_gallery(basedir, destdir, site):
  """Adding gallery metadata and generating thumbnails."""
  thumb_ext = '.thumb.jpg'
  #should use url2pathname when opening files!
  
  def get_desc(infile):
    try:
      desc = open(infile+'.txt', 'r').read()
    except IOError:
      desc = ''
    return desc
  
  for page in site.get('pages', []):
    gallery = glob.glob(os.getcwd() + page['url'] + '*.png') + glob.glob(os.getcwd() + page['url'] + '*.jpg') + glob.glob(os.getcwd() + page['url'] + '*.PNG') + glob.glob(os.getcwd() + page['url'] + '*.JPG')
    gallery = [ ( filename[len(os.getcwd()):] , filename[len(os.getcwd()):] + thumb_ext, get_desc(filename) ) for filename in gallery if (filename[-len(thumb_ext):] != thumb_ext)]
    random.shuffle(gallery)
    
    gallery_str = '<p>'
    
    for image,thumb,desc in gallery:
      im = Image.open(os.getcwd() + image)
      w,h = im.size            #Get image width and height
      if min(w,h)>2048:          #Check if either dimension is smaller then 2048
        im.thumbnail((2048,2048), Image.ANTIALIAS)  #Re-size Image
        w,h = im.size          #update image size
        im.save(os.getcwd() + image, "JPEG")
      
      imthumb = ImageOps.fit(im, (180, 180), Image.ANTIALIAS)
      #try:
      #  os.mkdir(os.getcwd() + "/_site" + page['url'])
      #except OSError:
      #  pass
      imthumb.save(os.getcwd() + thumb, "JPEG")
      gallery_str += '<a class="colorbox" href="' + pathname2url(image) + '" title="' + desc + '"><img class="thumbnail" src="' + pathname2url(thumb) + '"></a>'
      
    gallery_str += '</p>'
    page['content'] = page['content'].replace('[gallery]',gallery_str)

obraz.processors.insert(0, process_gallery)

pages_layout.py

import obraz

def process_pages_layout(basedir, destdir, site):
"""Set default pages layout."""
layout = site.get('pages_layout', 'page')
for page in site.get('pages', []):
if page['url'] != '/feed.atom':
      page.setdefault('layout', layout)

obraz.processors.insert(0, process_pages_layout)

posts_layout.py

import obraz

def process_posts_layout(basedir, destdir, site):
"""Set default posts layout."""
layout = site.get('posts_layout', 'post')
for post in site.get('posts', []):
post.setdefault('layout', layout)

obraz.processors.insert(0, process_posts_layout)

relativize.py

import obraz,re

def process_relativize(basedir, destdir, site):
  """Relativize URLs"""

  for page in site.get('pages', []):
    relpath = ''
    distance = page['url'].count('/') - 1
    for step in range(distance):
      relpath += '../'
    page['relpath'] = relpath

obraz.processors.insert(0, process_relativize)

def regex_replace(s, arg):
  """A non-optimal implementation of a regex filter"""
  if arg == "":
    arg="./"
  find = "(href|src)=[\"']/(?!/)([^\"']*)[\"']"
  replace = '\\1="'+arg+'\\2"'
  return re.sub(find, replace, s)

obraz.template_filters['regex'] = regex_replace

resizejpg.py

import obraz,os,glob,Image
try:
from urllib.request import pathname2url, url2pathname
except ImportError:
from urllib import pathname2url, url2pathname

def resize_jpg(basedir, destdir, site):
  """Resizing large .jpgs in /attach dir."""
  #should use url2pathname when opening files!
  
  attach_dir = glob.glob(os.getcwd() + '/attach/' + '*.jpg') + glob.glob(os.getcwd() + '/attach/' + '*.JPG')
  
  for image in attach_dir:
    im = Image.open(image)
    w,h = im.size            #Get image width and height
    if min(w,h)>2048:          #Check if either dimension is smaller than 2048
      im.thumbnail((2048,2048), Image.ANTIALIAS)  #Re-size Image
      w,h = im.size          #update image size
      im.save(image, "JPEG")

obraz.processors.insert(0, resize_jpg)

sortmeister.py

import obraz,datetime

def process_sortmeister(basedir, destdir, site):
"""Add yearmonth sorting to posts."""
for post in site.get('posts', []):
post['yearmonth'] = datetime.datetime( int( post['date'].strftime('%Y') ) , int( post['date'].strftime('%m') ), 1 )

obraz.processors.insert(0, process_sortmeister)

koppen/index.php

--- 
title: Koppensneller
layout: common
class: koppen
---
<?php //Start caching!
$cacheFile = 'cache.html';
if ( (file_exists($cacheFile)) && ((time() - filemtime($cacheFile)) < 1800) ){
echo file_get_contents($cacheFile);
} else {
ob_start();
?>
<?php //Function to generate feedstuffs.
function printfeed($url,$max){
$rss = @simplexml_load_file($url);
if($rss){
echo '<ul><li>'.$rss->channel->title.'</li>';
$items = $rss->channel->item;
$iter = 1;
foreach($items as $item){
if ($iter++ > $max) break;
echo '<li><a href="http://viewtext.org/article?url='.$item->link.'" title="'.$item->title.': '.strip_tags($item->description).'">'.$item->title.'</a></li>';
}
echo '</ul>';
}
}
function printfeedimage($url){
$rss = @simplexml_load_file($url);
if($rss){
$items = $rss->channel->item;
foreach($items as $item){
preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $item->description, $matches);
$first_img = $matches [1] [0];
echo '<article><h2>'.$rss->channel->title.'</h2><h3> </h3><a href="'.$item->link.'" title="'.strip_tags($item->description).'"><img src="'.$matches[1][0].'"></a></article>';
break;
}
}
}
?>
<div id="columns">

<ul>
<li>Linksch</li>
<li><a href="https://gmail.com/">Gmail</a></li>
<li><a href="http://gathering.tweakers.net/forum/list_bookmarks/////forum">GoT Bookmarks</a></li>
<li><a href="http://quartertothree.com/game-talk/forumdisplay.php?f=6">Quarter to Three</a></li>
<li><a href="http://hydrogenaudio.org/">HydrogenAudio</a></li>
<li><a href="http://www.reddit.com/r/askscience+asmr+CampingandHiking+dailyprogrammer+dataisbeautiful+DepthHub+EarthPorn+LifeProTips+linux+MapPorn+programming+ProjectReddit+Python+science+technology+vexillology+YouShouldKnow">Reddit</a></li>
<li><a href="http://ihackernews.com/">Hackernews</a></li>
<li><a href="http://alterslash.org/">Slashdot</a></li>
</ul>
<? //Place feeds
printfeed('http://feeds.feedburner.com/englishrussia/GrPQ',5);
printfeed('http://www.spiegel.de/international/index.rss',3);
printfeed('http://nrc.nl/rss.php',7);
printfeed('http://www.aljazeera.com/Services/Rss/?PostingId=2007731105943979989',6);
printfeed('http://feeds.nos.nl/nosjournaal',6);
printfeed('http://feeds.feedburner.com/NotRocketScience',3);
printfeed('http://feeds.newscientist.com/science-news',6);
printfeed('http://feeds.bbci.co.uk/news/science_and_environment/rss.xml',5);
printfeed('http://feeds.wired.com/wired/index',6);
printfeed('http://feeds.arstechnica.com/arstechnica/index',6);
printfeed('http://tweakers.net/feeds/nieuws.xml',7);
printfeed('http://feeds.feedburner.com/RockPaperShotgun',6);
printfeed('http://lxer.com/module/newswire/headlines.rdf',6);
echo "</div>";
printfeedimage('http://xkcd.com/rss.xml');
printfeedimage('http://www.acme.com/jef/apod/rss.xml');
printfeedimage('http://www.boston.com/bigpicture/index.xml');
?>
<?php //End caching.
file_put_contents($cacheFile,ob_get_contents());
ob_end_flush();
}
?>