Source

Dragoman / dragoman / control / main.py

import os
import simplejson
import gettext
import urllib

from urlparse import urljoin

import cherrypy

from eggmonster import env

from dragoman.control import APIHandler, cache
from dragoman.lib.storage import Catalog, CatalogList, LanguageList

from pprint import pprint


class Service(APIHandler):
    '''Returns the API service URLs as JSON'''
    @cache
    def GET(self):
        result = self.json({
            'base': cherrypy.request.base,
            'self': cherrypy.request.base + '/api',
            'languages': '/api/language',
            'catalog' : '/api/catalog/{catalog}',
            'language': '/api/catalog/{catalog}/{language}',
            'phrases' : '/api/{catalog}/{language}',
            'phrase': '/api/{catalog}/{language}/{phrase}', 
        })
        return result


class Languages(APIHandler):

    def GET(self):
        langs = LanguageList()
        return self.json(dict([(k, v) for k, v in langs.items()]))
	
    def POST(self):
        langs = LanguageList()
        doc = simplejson.loads(cherrypy.request.body.read())
        if not doc.get('abbrev') or not doc.get('name'):
            raise cherrypy.HTTPError(400, 'Need a JSON doc with abbrev and name as keys')
        abbrev, name = doc['abbrev'], doc['name']
        langs.add(abbrev, name)
        cherrypy.response.status = 201
        return self.json({
            'status': 201, 'message': 'created',
        })

    def DELETE(self, abbrev=None):
        if not abbrev:
            raise cherrypy.HTTPError(404)
        langs = LanguageList()
        langs.delete(abbrev)
        return self.json({
            'status': 200, 'message': 'deleted',
        })
        
        

class Catalogs(APIHandler):

    def GET(self, catalog=None):
        cl = CatalogList()
        if not catalog:
            return self.json(cl.catalogs.keys())
        # list the languages in the catalog
        return self.json(cl.catalogs[catalog])


    def POST(self, catalog, lang=None, *args, **kw):
        '''Can add a catalog to the listing. If the catalog is empty
        it is just a place holder and a blank default catalog will be
        added. This is like the master .po. Otherwise, a document must
        be provided in the form of a JSON document containing the
        supported doc format.
        '''
        hdrs = cherrypy.request.headers

        # no json provided
        if not hdrs.get('Content-Length', None):
            if not lang:
                raise cherrypy.HTTPError(400, 'You must provide a request body')
            else:
                # stub the catalog with the defaults defined in the
                # env config
                c = Catalog(catalog, lang)
                c.initialize()
        else:
            if hdrs['Content-Type'] != 'application/json':
                # TODO: write the body as a po and try to import it                
                cherrypy.HTTPError(501) # NotImplemented
            else:
                # read the json and import that    
                doc = simplejson.loads(cherrypy.request.body.read())
                c = Catalog(catalog, lang)
                c.batch(doc)

        url = '/api/%s' % (catalog)             
        cherrypy.response.status = 201
        cherrypy.response.headers['Location'] = url
        return self.json({
            'status': 201, 'message': 'created',
            'url': url
        })


class Phrases(APIHandler):

    def list_phrases(self, catalog, lang):
        catalog = Catalog(catalog, lang)
        return self.json(list(catalog.phrases()))

    @cache
    def GET(self, catalog, lang, phrase=None, *args, **extra): 
        if not Catalog.is_valid_lang(lang):
            raise cherrypy.HTTPError(404)

        # no :phrase in the URL so give a listing in JSON
        if not phrase:
            return self.list_phrases(catalog, lang)

        catalog = Catalog(catalog, lang)
        translation = catalog.get(phrase, extra)

        # add the phrase for later
        if translation == False:
            catalog.add(phrase, '')
            raise cherrypy.HTTPError(404)

        # return the original english
        elif translation == None:
            return phrase
        
        return translation.encode('utf-8')

    def POST(self, catalog, lang, phrase=None, **extra):
        if not Catalog.is_valid_lang(lang):
            raise cherrypy.HTTPError(404)

        catalog = Catalog(catalog, lang)
        doc = simplejson.loads(cherrypy.request.body.read())
        if not doc.get('translation'):
            doc['translation'] = '' # allow empties

        catalog.add(phrase, doc['translation'], extra)
        
        cherrypy.response.status = 201
        return self.json({
            'status': 201, 'message': 'created',
            'url': '/api/%s/%s' % (catalog.lang, urllib.quote(phrase))
        })