123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- # coding: utf8
- from __future__ import unicode_literals
- import livereload
- import fabric.colors as colors
- import fabric.contrib.project as project
- import fabric.contrib.files as files
- import fabric.api as fabric
- import jinja2
- import path
- import pelican.utils as utils
- import collections
- import datetime
- import logging
- import logging.handlers
- import mimetypes
- import sys
- # Local path configuration (can be absolute or relative to fabfile)
- fabric.env.deploy_path = path.path('output')
- fabric.env.content_path = path.path('content')
- fabric.env.theme_path = path.path('../theme')
- fabric.env.jinja = jinja2.Environment(
- loader=jinja2.PackageLoader('fabfile', 'templates')
- )
- MESSAGE_FORMAT = '%(levelname)s %(message)s'
- LEVELS = {
- 'WARNING': colors.yellow('WARN', bold=True),
- 'INFO': colors.blue('INFO', bold=True),
- 'DEBUG': colors.green('DEBUG', bold=True),
- 'CRITICAL': colors.magenta('CRIT', bold=True),
- 'ERROR': colors.red('ERROR', bold=True),
- }
- class FabricFormatter(logging.Formatter):
- def format(self, record):
- record.levelname = LEVELS.get(record.levelname) + ':'
- return super(FabricFormatter, self).format(record)
- class Server(livereload.Server):
- def _setup_logging(self):
- super(Server, self)._setup_logging()
- server_handler = logging.getLogger('livereload').handlers[0]
- server_handler.setFormatter(FabricFormatter(MESSAGE_FORMAT))
- def application(env, start_response):
- chunk_size = 64 * 1024
- def not_found(sr):
- sr('404 NOT FOUND', [('Content-Type', 'text/plain')])
- return ['Not Found']
- def serve_file(f, sr):
- mime = mimetypes.guess_type(f)
- sr('200 OK', [('Content-Type', mime[0])])
- return f.chunks(chunk_size, 'rb')
- def list_dir(d, sr):
- sr('200 OK', [('Content-Type', 'text/html')])
- context = {
- 'directory': d.relpath(fabric.env.deploy_path),
- 'links': [ f.relpath(d) for f in d.listdir() ]
- }
- return (fabric.env.jinja.get_template('list_dir.tplt')
- .stream(**context))
- path = fabric.env.deploy_path + env.get('PATH_INFO')
- path_index = path + 'index.html'
- if not path.exists():
- return not_found(start_response)
- if path.isfile():
- return serve_file(path, start_response)
- if path_index.exists():
- return serve_file(path_index, start_response)
- return list_dir(path, start_response)
- @fabric.task
- def clean():
- if fabric.env.deploy_path.isdir():
- fabric.local('rm -rf {deploy_path}'.format(**fabric.env))
- fabric.local('mkdir {deploy_path}'.format(**fabric.env))
- @fabric.task
- def build():
- fabric.local('pelican -s pelicanconf.py')
- @fabric.task
- def rebuild():
- clean()
- build()
- @fabric.task
- def regenerate():
- fabric.local('pelican -r -s pelicanconf.py')
- @fabric.task
- def serve(*args):
- port = args[0] if len(args) > 0 else 8000
- if not isinstance(port, int) or port < 1024 or port > 65535:
- print(colors.red('Port must be an integer between 1024 and 65535...'))
- return
- build()
- server = Server(application)
- server.watch(fabric.env.content_path, build)
- server.watch(fabric.env.theme_path, build)
- server.serve(port=port, debug=True)
- @fabric.task
- def reserve():
- build()
- serve()
- @fabric.task
- def new_post(*args):
- title = args[0] if len(args) > 0 else fabric.prompt('New post title?')
- title = unicode(title, 'utf8')
- date = datetime.date.today().isoformat()
- filename = '.'.join([date, utils.slugify(title), 'md'])
- filename = fabric.env.content_path / filename
- print(' '.join([LEVELS['INFO'], 'Create new post:', filename]))
- (fabric.env.jinja.get_template('new_post.tplt')
- .stream(title=title)
- .dump(filename, 'utf8'))
- @fabric.task
- def publish():
- build()
- fabric.local('ghp-import {0}'.format(fabric.env.deploy_path))
- fabric.local('git push origin -f gh-pages:master')
|