Source

pist / pist / core.py

import os

from tornado import web

from models import User, Repo
from utils import get_remote_ip, format_file

class BaseHandler(web.RequestHandler):

    def __init__(self, *args, **kwargs):
        super(BaseHandler, self).__init__(*args, **kwargs)
        self.context = {
            'format': format_file,
        }

    def get_current_user(self):
        """Returns the current user or None if the user is not logged in"""

        user_id = self.get_secure_cookie('user_id')
        return User.by_id(user_id)

    def render(self, template, **kwargs):
        """Renders the specified template using our context variables"""

        self.context.update(kwargs)
        return super(BaseHandler, self).render(template, **self.context)

    def get_error_html(self, status_code, **kwargs):
        """Returns the HTML from a template whose name matches the status code"""

        self.context['errors'] = []
        self.context['status_code'] = status_code
        self.context.update(kwargs)

        self._finished = False
        return self.render_string('%s.html' % status_code, **self.context)

class HomeHandler(BaseHandler):

    def get(self):
        return self.render('home.html')

class ShowRepoHandler(BaseHandler):

    def get(self, hash, revision=None):
        repo = Repo.by_id(hash)
        repo.revision = revision
        return self.render('show_repo.html', repo=repo)

class EditHandler(BaseHandler):

    @web.authenticated
    def get(self, hash=None):
        if hash:
            repo = Repo.by_id(hash)
            action = self.reverse_url('edit-repo', repo.hash)
        else:
            repo = None
            action = self.reverse_url('new-repo')

        return self.render('edit_repo.html', repo=repo, action=action)

    @web.authenticated
    def post(self, hash=None):
        if hash is None:
            repo = Repo.create(self.current_user.id)
        else:
            repo = Repo.by_id(hash)

        # create/update the files in the request
        files = self.get_arguments('name[]')
        snippets = zip(files, self.get_arguments('snippet[]'))
        for filename, snippet in snippets:
            path = os.path.join(repo.path, filename)

            # try to make any necessary directories first
            try:
                os.makedirs(os.path.dirname(path))
            except OSError:
                pass

            f = open(path, 'w')
            f.write(snippet)
            f.close()

        # remove any files that are in the repo that aren't in the request
        for file in repo.list():
            if file not in files:
                os.remove(os.path.join(repo.path, file))

        repo.commit("Edited from %s" % get_remote_ip(self.request))

        return self.redirect(self.reverse_url('show-repo', repo.hash))