Source

ryshcate / ryshcate / api.py

# -*- coding: utf-8 -*-
"""
ryshcate.api
============
This module contains the pastebin API, which is powered by XML-RPC.

:copyright: 2010 Matthew "LeafStorm" Frazier
:license:   MIT/X11, see LICENSE for details
"""
from flaskext.xmlrpc import XMLRPCHandler, Fault
from ryshcate.database import Paste, create_id
from ryshcate.utils import LEXER_LIST, LEXER_DICT, contains_profanities

def paste_to_struct(paste):
    return dict(id=paste.id, title=paste.title, code=paste.code,
                language=paste.language, tags=list(paste.tags),
                created=paste.created, private=paste.private)


handler = XMLRPCHandler('api')

ryshcate = handler.namespace('ryshcate')

@ryshcate.register
def get_paste(id):
    """
    Returns the paste with the given ID. Pastes are structs with the members
    id (string), title (string), code (string), language (string), tags (lis
    of strings), created (date/time), and private (boolean). It will raise
    a fault with the code ``not_found`` if the paste does not exist.
    """
    paste = Paste.load(id)
    if paste is None:
        raise Fault('not_found', 'The paste with ID %s does not exist.' % id)
    return paste_to_struct(paste)


@ryshcate.register
def all_languages():
    """
    This lists all of the available languages. It is returned as a list of
    structs with the members name and id.
    """
    return [dict(id=id, name=name) for (id, name) in LEXER_LIST]


@ryshcate.register
def public_pastes():
    """
    This returns a listing of all public pastes. It returns a list of structs
    that have the same members as the one for `get_paste`.
    """
    pastes = Paste.public()
    return [paste_to_struct(paste) for paste in pastes]


@ryshcate.register
def list_tags():
    """
    This lists all the tags that have public pastes. It returns a list of
    structs with the members name and count, count being the number of pastes
    therein.
    """
    tag_counts = Paste.tag_counts()
    return [dict(name=t.key, count=t.value) for t in tag_counts]


@ryshcate.register
def list_languages():
    """
    This lists all the languages that have public pastes. It returns a list of
    structs with the members id, name, and count.
    """
    language_counts = Paste.language_counts()
    return [dict(id=l.key, name=LEXER_DICT[l.key], count=l.value)
            for l in language_counts]


@ryshcate.register
def pastes_by_tag(tag):
    """
    This returns a list of pastes that have a given tag. The format of the
    return value is identical to the one for `public_pastes`.
    """
    pastes = Paste.tagged[tag]
    return [paste_to_struct(paste) for paste in pastes]


@ryshcate.register
def pastes_by_language(language):
    """
    This returns a list of pastes for the given language. The format of the
    return value is identical to the one for `public_pastes`.
    """
    pastes = Paste.by_language[language]
    return [paste_to_struct(paste) for paste in pastes]


@ryshcate.register
def new_paste(title, code, language, tags=None, private=False):
    """
    This creates a new paste.
    
    :param title: The title of the paste as a string.
    :param code: The paste's code as a string.
    :param language: The id of the language. (See `list_languages` for a
                     list.)
    :param tags: Tags to apply, as a list of strings. (Optional, defaults to
                 an empty list.)
    :param private: Whether the paste should be private or not. (Optional,
                    defaults to `False`.
    """
    # Validate title
    if contains_profanities(title):
        raise Fault('profane', 'Title may not contain profanities.')
    if len(title) > 64:
        raise Fault('length', 'Title is too long.')
    # Validate code
    if contains_profanities(code):
        raise Fault('profane', 'Code may not contain profanities.')
    # Validate language
    if language not in LEXER_DICT:
        raise Fault('unknown_language', 'That language cannot be pasted.')
    # Validate tags
    if tags is None:
        tags = []
    if any(contains_profanities(tag) for tag in tags):
        raise Fault('profane', 'Tags may not contain profanities.')
    
    paste = Paste(title=title, code=code, language=language, tags=tags,
                  private=private, id=create_id())
    paste.store()
    return paste_to_struct(paste)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.