def read(self, request): Emitter.register('xml', OpProfessionXMLEmitter, 'text/xml; charset=utf-8') if 'type' in request.GET and request.GET['type'] == 'basic': return OpProfession.objects.db_manager('op').getBasic().values('id', 'description', 'odescription') else: return OpProfession.objects.using('op').all()
def render_data(self, request): filecode = request.REQUEST.get('filecode', 'gb18030') Emitter.register('txt', TXTEmitter, 'text/plain; charset=%s' % filecode) lines = [txt_format(a) for a in self.cells] lines.insert(0, txt_format(self.head)) return u"\r\n".join(lines).encode(filecode)
def render_data(self, request): filecode = 'gb18030' #request.REQUEST.get('filecode','gb18030') Emitter.register('csv', CSVEmitter, 'applicatioin/download; charset=%s' % filecode) lines = [csv_format(a) for a in self.cells] lines.insert(0, csv_format(self.head)) return u"\r\n".join(lines).encode(filecode)
def read(self, request, id_type, city_id): Emitter.register('xml', OpXMLEmitter, 'text/xml; charset=utf-8') request_s = request.GET.urlencode().replace('&', '+') reps = cache.get('op_api_' + request_s) # if reps is None: if True: reps = self.get_cityreps(id_type, city_id) cache.set('op_api_'+request_s, reps, 3600) return reps
def read(self, request): Emitter.register('xml', OpXMLEmitter, 'text/xml; charset=utf-8') request_s = request.GET.urlencode().replace('&', '+') statistics = cache.get('op_api_' + request_s) if statistics is None: statistics = OpInstitutionCharge.objects.db_manager('op').get_statistics(request) cache.set('op_api_'+request_s, statistics, 3600) return { 'statistics': statistics }
def read(self, request): ''' documentazione per la api education_levels ''' Emitter.register('xml', OpEducationLevelXMLEmitter, 'text/xml; charset=utf-8') if 'type' in request.GET and request.GET['type'] == 'basic': return OpEducationLevel.objects.db_manager('op').getBasic().values('id', 'description') else: return OpProfession.objects.using('op').all()
def read(self, request, id_type, location_id, year=None): Emitter.register('xml', OpLocationXMLEmitter, 'text/xml; charset=utf-8') try: if 'city_mayors' in request.path: return self.get_city_mayors_data(id_type, location_id) elif 'city_mayor' in request.path: return self.get_city_mayor_data(id_type, location_id, year) else: return self.get_location_government_data(id_type, location_id, year) except Exception, e: return { 'error': e }
def read(self, request, pol_id=None): Emitter.register('xml', OpXMLEmitter, 'text/xml; charset=utf-8') self.request_s = request.get_full_path().replace('&', '+') try: members = None if 'first_name' not in request.GET or 'last_name' not in request.GET: return {'error': 'must specify first_name, last_name and, optionally, birth_date'} if 'first_name' in request.GET and 'last_name' in request.GET: members = self.base.select_related().filter( Q(first_name=request.GET['first_name'], last_name=request.GET['last_name']), ) if 'first_name' in request.GET and 'last_name' in request.GET and 'birth_date' in request.GET: members = self.base.select_related().filter( Q(first_name=request.GET['first_name'], last_name=request.GET['last_name']) | Q(first_name=request.GET['first_name'], birth_date=request.GET['birth_date']) | Q(last_name=request.GET['last_name'], birth_date=request.GET['birth_date']) ) if members: if 'count' in request.GET and request.GET['count'] == 'true': return len(members) if 'limit' in request.GET: members = members[:request.GET['limit']] pols = [] for member in members: api_url = reverse('api_op_politician_detail', args=[member.content_id]) member_charges = [c['textual_rep'] for c in member.getInstitutionCharges()] member= { 'op_id': member.content_id, 'first_name': member.first_name, 'last_name': member.last_name, 'birth_date': member.birth_date, 'birth_location': member.birth_location, 'charges': member_charges, 'op_link': 'http://www.openpolis.it/politico/%s' % member.content_id, 'api_link': '%s%s' % (settings.SITE_URL, api_url) } pols.append(member) return pols else: if 'count' in request.GET: return 0 else: return [] except self.model.DoesNotExist: return None
def __call__(self, request, result, handler): if isinstance(result, ErrorDict): result = dictFromErrorDict(result) resource = handler.resource em_format = resource.determine_emitter(request) emitter, ct = Emitter.get(em_format) srl = emitter(result, typemapper, handler, handler.fields, anonymous=True) try: if resource.stream: stream = srl.stream_render(request) else: stream = srl.render(request) self.__init__(stream, mimetype=ct) self.streaming = resource.stream except HttpStatusCode, e: return e.response
def error_resp(message, error_type=None, resp=rc.BAD_REQUEST, status_code=None): logging.warn("Status Code " + str(resp.status_code) + ", error_type: " + repr(error_type) + ", message: " + repr(message)) error_json = {} if message and error_type: (error_type_resp, error_type) = error_type resp = error_type_resp error = {} error['type'] = error_type error['message'] = message error_json['error'] = error elif message: error = {} error['type'] = '' error['message'] = message error_json['error'] = error if message or error_type: emitter, ct = Emitter.get('json') #TODO: Make this work for other emitter formats srl = emitter(error_json, None, None, None, None) rendered_resp = srl.render(HttpRequest()) final_resp = HttpResponse(rendered_resp, mimetype=ct) if status_code: final_resp.status_code = status_code else: final_resp.status_code = resp.status_code return final_resp else: return resp
def apply_json_emitter(value_to_emit, handler=None): emitter, ct = Emitter.get('json') #TODO: Make this work for other emitter formats handler_fields = None if handler: handler_fields = handler.fields srl = emitter(value_to_emit, typemapper, handler, handler_fields, None) json = srl.construct() return json
def render_created(self, request, new_obj, new_url): """Quick hack to return a 201 Created along with a JSON rendering of what was created""" resp = rc.CREATED emitter, ct = Emitter.get('json') resp['Content-Type'] = ct resp['Location'] = new_url srl = emitter(new_obj, typemapper, self, self.fields, False) resp.content = srl.render(request) return resp
def read(self, request, id=None): Emitter.register('xml', OpLocationXMLEmitter, 'text/xml; charset=utf-8') # store request as a string, as cache key self.request_s = request.get_full_path().replace('&', '+') msg = "%s, %s %s, %s, %s" % \ (time.strftime("%d/%b/%Y %H:%M:%S",time.localtime(time.time())), request.method, self.request_s, request.user.username, request.META['REMOTE_ADDR']) try: if id: return self.base.get(pk=id) else: locs = cache.get('op_api_' + self.request_s) if locs is None: locs = self.base.all() if 'namestartswith' in request.GET: locs = locs.filter((Q(name__istartswith=request.GET['namestartswith']) | Q(alternative_name__istartswith=request.GET['namestartswith']))).order_by('location_type__id', '-inhabitants') if 'name' in request.GET: locs = locs.filter((Q(name=request.GET['name']) | Q(alternative_name=request.GET['name']))).order_by('location_type__id') if 'location_type' in request.GET: location_type = request.GET['location_type'] # self.fields.remove(('location_type', ('name', ))) if location_type in ('comune', 'provincia', 'regione'): locs = locs.filter(location_type__name__iexact=location_type) else: return None if location_type in ('comune', 'provincia') and 'regional_id' in request.GET: locs = locs.filter(regional_id=request.GET['regional_id']) if location_type == 'comune' and 'provincial_id' in request.GET: locs = locs.filter(provincial_id=request.GET['provincial_id']) if 'limit' in request.GET: locs = locs[:request.GET['limit']] cache.set('op_api_'+self.request_s, locs, 3600) return locs except self.model.DoesNotExist: return None
def build_error_response(e, request): # logger.error(str(e.status_code) + ' API error: ' + e.type) content = {"error": True, "type": e.type, "status_code": e.status_code, "explanation": ""} content.update(e.extra) response = rc.BAD_REQUEST format = request.GET.get("format", "json") em_info = Emitter.get(format) RequestEmitter = em_info[0] emitter = RequestEmitter(content, typemapper, "", "", False) response.content = emitter.render(request) response["Content-Type"] = em_info[1] return response
def form_validation_response(self, e, request,em_format): print 'in form_validation_response 1' try: emitter, ct = Emitter.get(em_format) fields = self.handler.fields except ValueError: result = piston.utils.rc.BAD_REQUEST result.content = "Invalid output format specified '%s'." % em_format return result serialized_errors = dict((key, [unicode(v) for v in values]) for key,values in e.form.errors.items()) srl = emitter(serialized_errors, piston.handler.typemapper, self.handler, fields, False) stream = srl.render(request) resp = HttpResponse(stream, mimetype=ct, status=400) return resp
def form_validation_response(self, e, request, em_format): print 'in form_validation_response 1' try: emitter, ct = Emitter.get(em_format) fields = self.handler.fields except ValueError: result = piston.utils.rc.BAD_REQUEST result.content = "Invalid output format specified '%s'." % em_format return result serialized_errors = dict((key, [unicode(v) for v in values]) for key, values in e.form.errors.items()) srl = emitter(serialized_errors, piston.handler.typemapper, self.handler, fields, False) stream = srl.render(request) resp = HttpResponse(stream, mimetype=ct, status=400) return resp
def render(self, request, *args, **kwargs): f = StringIO.StringIO() out = csv.writer(f,dialect='excel') c = self.construct() if not bool(request.REQUEST.get('headerless', False)): out.writerow(self.fields) def mapper(row): return [row[key] for key in self.fields] out.writerows(map(mapper, c)) # In this case we'll hanlde the HttpResponse wrapping. _, ct = Emitter.get('csv') response = HttpResponse(f.getvalue(), ct) response['Content-Disposition'] = 'attachment; filename=irack.csv' return response
def build_error_response(e, request): #logger.error(str(e.status_code) + ' API error: ' + e.type) content = { "error": True, "type": e.type, "status_code": e.status_code, "explanation": "" } content.update(e.extra) response = rc.BAD_REQUEST format = request.GET.get("format", "json") em_info = Emitter.get(format) RequestEmitter = em_info[0] emitter = RequestEmitter(content, typemapper, "", "", False) response.content = emitter.render(request) response['Content-Type'] = em_info[1] return response
import logging from piston.handler import BaseHandler, AnonymousBaseHandler from piston.emitters import Emitter, JSONEmitter from brc.models import * from api.emitters import GeoJSONEmitter from swingtime.models import Event, Occurrence import time JSONEmitter.unregister('json') Emitter.register('json', GeoJSONEmitter, content_type='text/javascript; charset=utf-8') art_fields = ('id', 'name', ('year', ('id', 'year')), 'slug', 'artist', 'description', 'url', 'contact_email', 'location_point', 'location_poly', 'circular_street', 'time_address') event_fields = ('id', 'title', 'description', 'print_description', ('year', ('id', 'year')), 'slug', 'event_type', ('hosted_by_camp', ('id', 'name')), ('located_at_art', ('id', 'name')), 'other_location', 'check_location', 'url', 'location_point', 'location_track', 'all_day', ('occurrence_set', ('start_time', 'end_time'))) camp_fields = ('id', ('year', ('id', 'year')), 'name', 'description', 'type', 'start_date_time', 'end_date_time', 'duration', 'repeats', 'hosted_by_camp', 'located_at_art', 'url', 'location_point', 'location_poly', 'contact_email') cstreet_fields = ('id', ('year', ('id', 'year')), 'name', 'order', 'width', 'distance_from_center', 'street_line') tstreet_fields = ('id', ('year', ('id', 'year')), 'hour', 'minute', 'name', 'width', 'street_line') infrastructure_fields = ('id', ('year', ('id', 'year')), 'name',
import sys from piston.handler import BaseHandler, AnonymousBaseHandler from piston.emitters import Emitter, JSONEmitter from piston_api.emitters import GeoJSONEmitter from mednet.sahana.models import * from mednet.messaging.models import * from piston.utils import rc from datetime import * import hashlib, random import urllib JSONEmitter.unregister('json') Emitter.register('json', GeoJSONEmitter, 'application/javascript; charset=utf-8') outgoing_fields = ('date_queued', 'receipt', 'date_sent', 'message', 'recipient', 'guid') #Incoming SMS class AnonymousIncomingSmsHandler(BaseHandler): allowed_methods=('GET','POST',) model = IncomingSmsMessage def read(self, request, message_id=None): if(message_id): return IncomingSmsMessage.objects.get(guid=message_id) else: return IncomingSmsMessage.objects.all() def create(self, request): if not self.has_model(): return rc.NOT_IMPLEMENTED
resp = super(Resource, self).__call__(request, *args, **kwargs) try: db.logs.insert({'key': request.apikey['_id'], 'method': self.handler.__class__.__name__, 'query_string': request.META['QUERY_STRING'], 'timestamp': datetime.datetime.utcnow()}) except AttributeError: pass return resp else: authorizer = None Resource = piston.resource.Resource Emitter.register('json', BillyJSONEmitter, 'application/json; charset=utf-8') Emitter.register('ics', ICalendarEmitter, 'text/calendar') Emitter.unregister('yaml') Emitter.unregister('xml') Emitter.unregister('django') Emitter.unregister('pickle') all_metadata_handler = Resource(handlers.AllMetadataHandler, authentication=authorizer) metadata_handler = Resource(handlers.MetadataHandler, authentication=authorizer) bill_handler = Resource(handlers.BillHandler, authentication=authorizer) bill_search_handler = Resource(handlers.BillSearchHandler,
from django.conf.urls.defaults import url, patterns, include from dcapi.common.emitters import StreamingCSVEmitter, StreamingJSONEmitter, ExcelEmitter from piston.emitters import Emitter Emitter.register('json', StreamingJSONEmitter, 'application/json; charset=utf-8') Emitter.register('csv', StreamingCSVEmitter, 'text/csv; charset=utf-8') Emitter.register('xls', ExcelEmitter, 'application/vnd.ms-excel; charset=utf-8') Emitter.unregister('django') Emitter.unregister('pickle') Emitter.unregister('xml') Emitter.unregister('yaml') urlpatterns = patterns( '', # each data set has its own area of the API and has its own # namespace. 'entities' is a core/common element to all APIs, and # aggregates has also been de-coupled from the contributions API. url(r'^entities', include('dcapi.aggregates.entities.urls')), url(r'^contracts', include('dcapi.contracts.urls')), #url(r'^contributions/bundled/', include('dcapi.contributions.bundling.urls')), url(r'^contributions', include('dcapi.contributions.urls')), url(r'^grants', include('dcapi.grants.urls')), url(r'^lobbying', include('dcapi.lobbying.urls')), url(r'^earmarks', include('dcapi.earmarks.urls')), url(r'^misconduct', include('dcapi.contractor_misconduct.urls')), url(r'^epa', include('dcapi.epa.urls')), url(r'^faca', include('dcapi.faca.urls')), url(r'^fara', include('dcapi.fara.urls')), url(r'^aggregates/', include('dcapi.aggregates.urls')),
try: db.logs.insert({ 'key': request.apikey['_id'], 'method': self.handler.__class__.__name__, 'query_string': request.META['QUERY_STRING'], 'timestamp': datetime.datetime.utcnow() }) except AttributeError: pass return resp else: authorizer = None Resource = piston.resource.Resource Emitter.register('json', OpenStateJSONEmitter, 'application/json; charset=utf-8') Emitter.register('xml', OpenStateXMLEmitter, 'application/xml; charset=utf-8') Emitter.register('rss', FeedEmitter, 'application/rss+xml') Emitter.register('ics', ICalendarEmitter, 'text/calendar') Emitter.unregister('yaml') Emitter.unregister('django') Emitter.unregister('pickle') metadata_handler = Resource(handlers.MetadataHandler, authentication=authorizer) bill_handler = Resource(handlers.BillHandler, authentication=authorizer) bill_search_handler = Resource(handlers.BillSearchHandler, authentication=authorizer) legislator_handler = Resource(handlers.LegislatorHandler,
class SsiEmitterMixin(object): def construct(self): ssify_api = getattr(settings, 'SSIFY_API', True) if ssify_api and isinstance(self.data, QuerySet) and self.data.model in (Book, Fragment, Tag): return SsiQS(self.data) else: return super(SsiEmitterMixin, self).construct() class SsiJsonEmitter(SsiEmitterMixin, JSONEmitter): def render(self, request): try: return super(SsiJsonEmitter, self).render(request) except TypeError: return '[%s]' % ",".join(self.construct().get_ssis('json')) Emitter.register('json', SsiJsonEmitter, 'application/json; charset=utf-8') class SsiXmlEmitter(SsiEmitterMixin, XMLEmitter): def render(self, request): try: return super(SsiXmlEmitter, self).render(request) except TypeError: return '<?xml version="1.0" encoding="utf-8"?>\n' \ '<response><resource>%s</resource></response>' % \ '</resource><resource>'.join(self.construct().get_ssis('xml')) Emitter.register('xml', SsiXmlEmitter, 'text/xml; charset=utf-8')
class CSVEmitter(Emitter): """Emitter that returns CSV file""" def render(self, request): result = StringIO.StringIO() field_names = tuple(get_flattened_field_names(self.fields)) dict_writer = unicodecsv.UnicodeDictWriter(result, field_names, dialect=csv.excel_tab) dict_writer.writerow(dict(zip(field_names, field_names))) dict_writer.writerows(get_flattened_data(self.construct())) return result.getvalue() Emitter.register('csv', CSVEmitter, 'application/csv') def detect_style(val): if isinstance(val, str): for typ in [int, float]: try: val = typ(val) return val, typ except ValueError: pass class ExcelEmitter(Emitter): """Emitter that returns Excel file""" def render(self, request): result = StringIO.StringIO()
def register(): if not _registered: global _registered Emitter.register('comic-protobuf', ComicProtobufEmitter, 'application/x-protobuf') _registered = True
import PyRSS2Gen import datetime class RSSEmitter(Emitter): def render(self, request): data = self.construct() rss_items = [] for item in data: rss_items.append( PyRSS2Gen.RSSItem( title=item['title'], description=item['synopsis'], link=item['url'], pubDate=item['date_created'], )) rss = PyRSS2Gen.RSS2(title="RSS for Something", link="http://news.something.com", description="Test", lastBuildDate=datetime.datetime.utcnow(), items=rss_items) return rss.to_xml(encoding="utf-8") #return data # Register Emitter Emitter.register('rss', RSSEmitter, 'charset=utf-8')
import logging from piston.handler import BaseHandler, AnonymousBaseHandler from piston.emitters import Emitter, JSONEmitter from brc.models import * from api.emitters import GeoJSONEmitter from swingtime.models import Event, Occurrence import time JSONEmitter.unregister('json') Emitter.register('json', GeoJSONEmitter, content_type='text/javascript; charset=utf-8') art_fields = ('id', 'name', ('year', ('id','year')), 'slug', 'artist', 'description', 'url', 'contact_email', 'location_point', 'location_poly', 'circular_street', 'time_address') event_fields = ('id', 'title','description', 'print_description', ('year', ('id','year')), 'slug', 'event_type', ('hosted_by_camp', ('id','name')), ('located_at_art', ('id','name')), 'other_location', 'check_location', 'url', 'location_point', 'location_track', 'all_day', ('occurrence_set', ('start_time', 'end_time'))) camp_fields = ('id', ('year', ('id','year')), 'name', 'description', 'type', 'start_date_time', 'end_date_time', 'duration', 'repeats', 'hosted_by_camp', 'located_at_art', 'url', 'location_point', 'location_poly', 'contact_email') cstreet_fields = ('id', ('year', ('id','year')), 'name', 'order', 'width', 'distance_from_center', 'street_line') tstreet_fields = ('id', ('year', ('id','year')), 'hour', 'minute', 'name', 'width', 'street_line') infrastructure_fields = ('id', ('year', ('id','year')), 'name', 'location_point', 'location_line', 'location_poly', 'location_multigeom', 'tags') year_fields = ('id', 'location', 'location_point', 'participants', 'theme') user_fields = ('id', 'username', 'first_name', 'last_name', 'active') class AnonymousArtInstallationHandler(BaseHandler): allow_methods = ('GET',) model = ArtInstallation fields = art_fields def read(self, request, year_year=None, art_id=None): base = ArtInstallation.objects.filter() if(year_year): year = Year.objects.get(year=year_year) if(art_id):
from piston.emitters import Emitter from piston.utils import rc from django.http import HttpResponse class HTMLEmitter(Emitter): def render(self, request): data = self.construct() resp = rc.ALL_OK resp.write(data) return resp Emitter.register('html', HTMLEmitter, 'text/html')
from billy.web.api import handlers from billy.web.api.emitters import BillyJSONEmitter class CORSResource(piston.resource.Resource): def __call__(self, *args, **kwargs): r = super(CORSResource, self).__call__(*args, **kwargs) r['Access-Control-Allow-Origin'] = '*' return r authorizer = None Resource = CORSResource Emitter.register('json', BillyJSONEmitter, 'application/json; charset=utf-8') Emitter.unregister('yaml') Emitter.unregister('xml') Emitter.unregister('django') Emitter.unregister('pickle') all_metadata_handler = Resource(handlers.AllMetadataHandler, authentication=authorizer) metadata_handler = Resource(handlers.MetadataHandler, authentication=authorizer) bill_handler = Resource(handlers.BillHandler, authentication=authorizer) bill_search_handler = Resource(handlers.BillSearchHandler, authentication=authorizer) legislator_handler = Resource(handlers.LegislatorHandler, authentication=authorizer)
class Resource(object): """ Resource. Create one for your URL mappings, just like you would with Django. Takes one argument, the handler. The second argument is optional, and is an authentication handler. If not specified, `NoAuthentication` will be used by default. """ callmap = { 'GET': 'read', 'POST': 'create', 'PUT': 'update', 'DELETE': 'delete' } def __init__(self, handler, authentication=None): if not callable(handler): raise AttributeError, "Handler not callable." self.handler = handler() self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True) if not authentication: self.authentication = (NoAuthentication(),) elif isinstance(authentication, (list, tuple)): self.authentication = authentication else: self.authentication = (authentication,) # Erroring self.email_errors = getattr(settings, 'PISTON_EMAIL_ERRORS', True) self.display_errors = getattr(settings, 'PISTON_DISPLAY_ERRORS', True) self.stream = getattr(settings, 'PISTON_STREAM_OUTPUT', False) def determine_emitter(self, request, *args, **kwargs): """ Function for determining which emitter to use for output. It lives here so you can easily subclass `Resource` in order to change how emission is detected. You could also check for the `Accept` HTTP header here, since that pretty much makes sense. Refer to `Mimer` for that as well. """ em = kwargs.pop('emitter_format', None) if not em: em = request.GET.get('format', 'json') return em def form_validation_response(self, e): """ Method to return form validation error information. You will probably want to override this in your own `Resource` subclass. """ resp = rc.BAD_REQUEST resp.write(' '+str(e.form.errors)) return resp @property def anonymous(self): """ Gets the anonymous handler. Also tries to grab a class if the `anonymous` value is a string, so that we can define anonymous handlers that aren't defined yet (like, when you're subclassing your basehandler into an anonymous one.) """ if hasattr(self.handler, 'anonymous'): anon = self.handler.anonymous if callable(anon): return anon for klass in typemapper.keys(): if anon == klass.__name__: return klass return None def authenticate(self, request, rm): actor, anonymous = False, True for authenticator in self.authentication: if not authenticator.is_authenticated(request): if self.anonymous and \ rm in self.anonymous.allowed_methods: actor, anonymous = self.anonymous(), True else: actor, anonymous = authenticator.challenge, CHALLENGE else: return self.handler, self.handler.is_anonymous return actor, anonymous @vary_on_headers('Authorization') def __call__(self, request, *args, **kwargs): """ NB: Sends a `Vary` header so we don't cache requests that are different (OAuth stuff in `Authorization` header.) """ rm = request.method.upper() # Django's internal mechanism doesn't pick up # PUT request, so we trick it a little here. if rm == "PUT": coerce_put_post(request) actor, anonymous = self.authenticate(request, rm) if anonymous is CHALLENGE: return actor() else: handler = actor # Translate nested datastructs into `request.data` here. if rm in ('POST', 'PUT'): try: translate_mime(request) except MimerDataException: return rc.BAD_REQUEST if not hasattr(request, 'data'): if rm == 'POST': request.data = request.POST else: request.data = request.PUT if not rm in handler.allowed_methods: return HttpResponseNotAllowed(handler.allowed_methods) meth = getattr(handler, self.callmap.get(rm, ''), None) if not meth: raise Http404 # Support emitter both through (?P<emitter_format>) and ?format=emitter. em_format = self.determine_emitter(request, *args, **kwargs) kwargs.pop('emitter_format', None) # Clean up the request object a bit, since we might # very well have `oauth_`-headers in there, and we # don't want to pass these along to the handler. request = self.cleanup_request(request) try: result = meth(request, *args, **kwargs) except Exception, e: result = self.error_handler(e, request, meth, em_format) try: emitter, ct = Emitter.get(em_format) fields = handler.fields if hasattr(handler, 'list_fields') and isinstance(result, (list, tuple, QuerySet)): fields = handler.list_fields except ValueError: result = rc.BAD_REQUEST result.content = "Invalid output format specified '%s'." % em_format return result status_code = 200 # If we're looking at a response object which contains non-string # content, then assume we should use the emitter to format that # content if isinstance(result, HttpResponse) and not result._is_string: status_code = result.status_code # Note: We can't use result.content here because that method attempts # to convert the content into a string which we don't want. # when _is_string is False _container is the raw data result = result._container srl = emitter(result, typemapper, handler, fields, anonymous) try: """ Decide whether or not we want a generator here, or we just want to buffer up the entire result before sending it to the client. Won't matter for smaller datasets, but larger will have an impact. """ if self.stream: stream = srl.stream_render(request) else: stream = srl.render(request) if not isinstance(stream, HttpResponse): resp = HttpResponse(stream, mimetype=ct, status=status_code) else: resp = stream resp.streaming = self.stream return resp except HttpStatusCode, e: return e.response
from django.conf.urls.defaults import url, patterns, include from dcapi.common.emitters import StreamingCSVEmitter, StreamingJSONEmitter, ExcelEmitter from piston.emitters import Emitter Emitter.register("json", StreamingJSONEmitter, "application/json; charset=utf-8") Emitter.register("csv", StreamingCSVEmitter, "text/csv; charset=utf-8") Emitter.register("xls", ExcelEmitter, "application/vnd.ms-excel; charset=utf-8") Emitter.unregister("django") Emitter.unregister("pickle") Emitter.unregister("xml") Emitter.unregister("yaml") urlpatterns = patterns( "", # each data set has its own area of the API and has its own # namespace. 'entities' is a core/common element to all APIs, and # aggregates has also been de-coupled from the contributions API. url(r"^entities", include("dcapi.aggregates.entities.urls")), url(r"^contracts", include("dcapi.contracts.urls")), # url(r'^contributions/bundled/', include('dcapi.contributions.bundling.urls')), url(r"^contributions", include("dcapi.contributions.urls")), url(r"^grants", include("dcapi.grants.urls")), url(r"^lobbying", include("dcapi.lobbying.urls")), url(r"^earmarks", include("dcapi.earmarks.urls")), url(r"^misconduct", include("dcapi.contractor_misconduct.urls")), url(r"^epa", include("dcapi.epa.urls")), url(r"^faca", include("dcapi.faca.urls")), url(r"^fara", include("dcapi.fara.urls")), url(r"^aggregates/", include("dcapi.aggregates.urls")), url(r"^refine/", include("dcapi.reconcile.urls")), url(r"^", include("dcapi.rapportive.urls")),
from django.core.cache import cache from django.core.serializers.json import DateTimeAwareJSONEncoder from django.utils import simplejson from piston.emitters import Emitter from core import Core class JSONCachedEmitter(Emitter): """ JSON emitter that caches the response for a given request """ def render(self, request): cache_key = str(Core.current_user().id ) + request.path + request.META['QUERY_STRING'] old = cache.get(cache_key) if old: return old seria = simplejson.dumps(self.construct(), cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=4) cache.set(cache_key, seria) return seria Emitter.register('json-cached', JSONCachedEmitter, 'application/json; charset=utf-8')
if len(construct) > 0: for key, value in construct[0].items(): header_row.append(key) for row in construct: this_row = [] for header in header_row: this_row.append(row[header]) data.append(this_row) return { 'header_row':header_row, 'data':data } class HTMLEmitter(Emitter): def render(self, request): page_info = _get_page_info(request) data = _construct_to_list(self.construct()) return render_to_string("api/data_html_view.html", { 'page_info':page_info, 'data':data }) class CSVEmitter(Emitter): def render(self, request): response = HttpResponse(mimetype='text/csv') writer = csv.writer(response) data = _construct_to_list(self.construct()) writer.writerow(data['header_row']) for row in data['data']: writer.writerow(row) return(response) Emitter.register('html', HTMLEmitter, 'text/html') Emitter.register('csv', CSVEmitter, 'text/csv')
class SsiEmitterMixin(object): def construct(self): if isinstance(self.data, QuerySet) and self.data.model in (Book, Fragment, Tag): return SsiQS(self.data) else: return super(SsiEmitterMixin, self).construct() class SsiJsonEmitter(SsiEmitterMixin, JSONEmitter): def render(self, request): try: return super(SsiJsonEmitter, self).render(request) except TypeError: return '[%s]' % ",".join(self.construct().get_ssis('json')) Emitter.register('json', SsiJsonEmitter, 'application/json; charset=utf-8') class SsiXmlEmitter(SsiEmitterMixin, XMLEmitter): def render(self, request): try: return super(SsiXmlEmitter, self).render(request) except TypeError: return '<?xml version="1.0" encoding="utf-8"?>\n' \ '<response><resource>%s</resource></response>' % \ '</resource><resource>'.join(self.construct().get_ssis('xml')) Emitter.register('xml', SsiXmlEmitter, 'text/xml; charset=utf-8')
xml.endElement(key.split()[0]) else: xml.characters(smart_unicode(data)) def render(self, request): stream = StringIO.StringIO() xml = SimplerXMLGenerator(stream, "utf-8") xml.startDocument() xml.startElement("Response", {}) self._to_xml(xml, self.construct()) xml.endElement("Response") xml.endDocument() return stream.getvalue() Emitter.register('custom_xml', CustomXmlEmitter, 'text/xml; charset=utf-8') Mimer.register(lambda *a: None, ('text/xml', )) class IpAuthentication(object): """IP Authentication handler """ def __init__(self, auth_func=authenticate, realm='API'): self.auth_func = auth_func self.realm = realm def is_authenticated(self, request): try: settings.API_ALLOWED_IP.index(request.META['REMOTE_ADDR']) return True except:
else: response = render_to_response( template_name=template_name, dictionary={ 'data': data, 'is_collection': is_collection }, context_instance=c, ) logger.info("...ending HTMLEmitter.render()") return (response) Emitter.register('html', HTMLEmitter, 'text/html; charset=utf-8') class SubOcgDataEmitter(IdentityEmitter): __converter__ = None __file_ext__ = '' def _render_(self, request): logger.info("starting {0}.render()...".format( self.__converter__.__name__)) payload = self.construct() self.request = request ## if it is a usergeometrymetdata object, run a different "flavor" of ## the converter. if isinstance(payload, HttpResponse): return (payload)
from piston.handler import AnonymousBaseHandler from piston.utils import rc from django.core.exceptions import ObjectDoesNotExist from django.forms.models import model_to_dict from djeuscan.models import Version, Package, Herd, Maintainer, EuscanResult, \ VersionLog from djeuscan.helpers import catch_and_return # replace default XMLEmitter with ours from piston.emitters import Emitter from .emitters import EuscanXMLEmitter Emitter.register('xml', EuscanXMLEmitter, 'text/xml; charset=utf-8') # /api/1.0/ class RootHandler(AnonymousBaseHandler): allowed_methods = ('GET',) def read(self, request): return {'api-version': '1.0'} # /api/1.0/statistics class StatisticsHandler(AnonymousBaseHandler): allowed_methods = ('GET',) def read(self, request): data = {} data['n_packaged'] = Package.objects.n_packaged()
from piston.handler import AnonymousBaseHandler from piston.utils import rc from django.core.exceptions import ObjectDoesNotExist from django.forms.models import model_to_dict from djeuscan.models import Version, Package, Herd, Maintainer, EuscanResult, \ VersionLog from djeuscan.helpers import catch_and_return # replace default XMLEmitter with ours from piston.emitters import Emitter from .emitters import EuscanXMLEmitter Emitter.register('xml', EuscanXMLEmitter, 'text/xml; charset=utf-8') # /api/1.0/ class RootHandler(AnonymousBaseHandler): allowed_methods = ('GET', ) def read(self, request): return {'api-version': '1.0'} # /api/1.0/statistics class StatisticsHandler(AnonymousBaseHandler): allowed_methods = ('GET', ) def read(self, request): data = {} data['n_packaged'] = Package.objects.n_packaged()
def render(self, request): cb = request.GET.get("callback", None) try: per_page = int(request.GET.get("per_page", 10)) except ValueError: per_page = 10 try: page_number = int(request.GET.get("page_number", 1)) except ValueError: page_number = 1 pages = Paginator(self.construct(), per_page) try: page = pages.page(page_number) except EmptyPage: page = pages.page(1) data = {"num_pages": pages.num_pages, "page_number": page_number, "data": page.object_list} serial = json.dumps(data, cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=4) # Callback if cb and is_valid_jsonp_callback_value(cb): return "%s(%s)" % (cb, serial) return serial Emitter.register("page_json", PageJSONEmitter, "application/json; charset=utf-8")
# create csv writer stream = StringIO() csvwriter = csv.DictWriter(stream, fieldnames, extrasaction='ignore', delimiter=self.delimiter, doublequote=self.doublequote, escapechar=self.escapechar, lineterminator=self.lineterminator) # conditionally output header if self.header: csvwriter.writeheader() for row in data: self._write_delimited(csvwriter, row) # recode in unicode upon output return unicode(stream.getvalue(), 'utf8') class CSVEmitter(DelimitedEmitter): delimiter = ',' class TSVEmitter(DelimitedEmitter): delimiter = '\t' Emitter.register('atom', AtomEmitter, 'application/atom+xml; charset=utf-8') Emitter.register('rss', RSSEmitter, 'application/rss+xml; charset=utf-8') Emitter.register('csv', CSVEmitter, 'text/csv; charset=utf-8') Emitter.register('tsv', TSVEmitter, 'text/tab-separated-values; charset=utf-8')
RegulationsDocketSubmitterHandler from dcapi.aggregates.fec.handlers import CandidateSummaryHandler, CommitteeSummaryHandler, CandidateStateHandler, \ CandidateTimelineHandler, CandidateItemizedDownloadHandler, CommitteeItemizedDownloadHandler, \ CommitteeTopContribsHandler from dcapi.aggregates.independentexpenditures.handlers import CandidateIndExpHandler, CommitteeIndExpHandler, \ CandidateIndExpDownloadHandler, CommitteeIndExpDownloadHandler from django.conf.urls.defaults import patterns, url from locksmith.auth.authentication import PistonKeyAuthentication from piston.emitters import Emitter from piston.resource import Resource from dcapi.aggregates.faca.handlers import FACAAgenciesHandler,\ FACACommitteeMembersHandler # We are using the default JSONEmitter so no need to explicitly # register it. However, unregister those we don't need. Emitter.unregister('django') Emitter.unregister('pickle') Emitter.unregister('xml') Emitter.unregister('yaml') ad = { 'authentication': PistonKeyAuthentication() } urlpatterns = patterns('', # amount contributed by one entity to another url(r'^recipient/(?P<recipient_entity>[a-f0-9]{32})/contributor/(?P<contributor_entity>[a-f0-9]{32})/amount.(?P<emitter_format>.+)$', Resource(ContributionAmountHandler, **ad)), # contributors to a single politician url(r'^pol/(?P<entity_id>[a-f0-9]{32})/contributors\.(?P<emitter_format>.+)$',
def __call__(self, request, *args, **kwargs): rm = request.method.upper() if rm == "PUT": coerce_put_post(request) actor, anonymous = self.authenticate(request, rm) if anonymous is CHALLENGE: return actor() else: handler = actor if rm in ('POST', 'PUT'): try: translate_mime(request) except MimerDataException: return rc.BAD_REQUEST if not hasattr(request, 'data'): if rm == 'POST': request.data = request.POST else: request.data = request.PUT if not rm in handler.allowed_methods: return HttpResponseNotAllowed(handler.allowed_methods) meth = getattr(handler, self.callmap.get(rm, ''), None) if not meth: raise Http404 em_format = self.determine_emitter(request, *args, **kwargs) kwargs.pop('emitter_format', None) request = self.cleanup_request(request) try: result = meth(request, *args, **kwargs) except ValueError: result = rc.BAD_REQUEST result.content = 'Invalid arguments' try: emitter, ct = Emitter.get(em_format) fields = handler.fields if hasattr(handler, 'list_fields') and isinstance( result, (list, tuple, QuerySet)): fields = handler.list_fields except ValueError: result = rc.BAD_REQUEST result.content = "Invalid output format specified '%s'." % em_format return result status_code = 200 if isinstance(result, HttpResponse) and not result._is_string: status_code = result.status_code result = result._container srl = emitter(result, typemapper, handler, fields, anonymous) try: if self.stream: stream = srl.stream_render(request) else: stream = srl.render(request) if not isinstance(stream, HttpResponse): resp = HttpResponse(stream, mimetype=ct, status=status_code) else: resp = stream resp.streaming = self.stream return resp except HttpStatusCode, e: return e.response
from django.conf import settings from django.conf.urls.defaults import * from piston.resource import Resource from piston.emitters import Emitter from fiftystates.site.api.handlers import * from fiftystates.site.api.emitters import LoggingJSONEmitter, LoggingXMLEmitter from fiftystates.site.api.views import document if getattr(settings, 'USE_LOCKSMITH', False): from locksmith.auth.authentication import PistonKeyAuthentication authorizer = PistonKeyAuthentication() Emitter.register('json', LoggingJSONEmitter, 'application/json; charset=utf-8') # disable XML output Emitter.unregister('xml') else: authorizer = None metadata_handler = Resource(MetadataHandler, authentication=authorizer) bill_handler = Resource(BillHandler, authentication=authorizer) bill_search_handler = Resource(BillSearchHandler, authentication=authorizer) legislator_handler = Resource(LegislatorHandler, authentication=authorizer) legsearch_handler = Resource(LegislatorSearchHandler, authentication=authorizer) legislator_geo_handler = Resource(LegislatorGeoHandler, authentication=authorizer) committee_handler = Resource(CommitteeHandler, authentication=authorizer) committee_search_handler = Resource(CommitteeSearchHandler, authentication=authorizer)
from django.conf.urls.defaults import url, patterns, include from dcapi.common.emitters import StreamingCSVEmitter, StreamingJSONEmitter, ExcelEmitter from piston.emitters import Emitter Emitter.register('json', StreamingJSONEmitter, 'application/json; charset=utf-8') Emitter.register('csv', StreamingCSVEmitter, 'text/csv; charset=utf-8') Emitter.register('xls', ExcelEmitter, 'application/vnd.ms-excel; charset=utf-8') Emitter.unregister('django') Emitter.unregister('pickle') Emitter.unregister('xml') Emitter.unregister('yaml') urlpatterns = patterns('', # each data set has its own area of the API and has its own # namespace. 'entities' is a core/common element to all APIs, and # aggregates has also been de-coupled from the contributions API. url(r'^entities', include('dcapi.aggregates.entities.urls')), url(r'^contracts', include('dcapi.contracts.urls')), #url(r'^contributions/bundled/', include('dcapi.contributions.bundling.urls')), url(r'^contributions', include('dcapi.contributions.urls')), url(r'^grants', include('dcapi.grants.urls')), url(r'^lobbying', include('dcapi.lobbying.urls')), url(r'^earmarks', include('dcapi.earmarks.urls')), url(r'^misconduct', include('dcapi.contractor_misconduct.urls')), url(r'^epa', include('dcapi.epa.urls')), url(r'^faca', include('dcapi.faca.urls')), url(r'^aggregates/', include('dcapi.aggregates.urls')), url(r'^', include('dcapi.rapportive.urls')), )
try: db.logs.insert({ 'key': request.apikey['_id'], 'method': self.handler.__class__.__name__, 'query_string': request.META['QUERY_STRING'], 'timestamp': datetime.datetime.utcnow() }) except AttributeError: pass return resp else: authorizer = None Resource = piston.resource.Resource Emitter.register('json', BillyJSONEmitter, 'application/json; charset=utf-8') Emitter.register('ics', ICalendarEmitter, 'text/calendar') Emitter.unregister('yaml') Emitter.unregister('xml') Emitter.unregister('django') Emitter.unregister('pickle') all_metadata_handler = Resource(handlers.AllMetadataHandler, authentication=authorizer) metadata_handler = Resource(handlers.MetadataHandler, authentication=authorizer) bill_handler = Resource(handlers.BillHandler, authentication=authorizer) bill_search_handler = Resource(handlers.BillSearchHandler, authentication=authorizer)
return u", ".join(l) class CSVEmitter(ColumnEmitter): """ CSV emitter, understands timestamps. """ def render_data(self, request): filecode = 'gb18030' #request.REQUEST.get('filecode','gb18030') Emitter.register('.csv', CSVEmitter, 'applicatioin/download; charset=%s' % filecode) lines = [csv_format(a) for a in self.cells] return u"\r\n".join(lines).encode(filecode) Emitter.register('.csv', CSVEmitter) def txt_format(a): l = [] for item in a: t = type(item) if t == type({}): l.append(item['verbose']) else: if t == datetime.datetime: p = "%s" % (item.strftime("%Y-%m-%dT%H:%M:%S")) elif item is not None: p = u"%s" % item p = p.replace("\t", "\\t").replace("\r", "\\r").replace("\n", "\\n")
self._to_xml(xml, value) xml.endElement(key.split()[0]) else: xml.characters(smart_unicode(data)) def render(self, request): stream = StringIO.StringIO() xml = SimplerXMLGenerator(stream, "utf-8") xml.startDocument() xml.startElement("Response", {}) self._to_xml(xml, self.construct()) xml.endElement("Response") xml.endDocument() return stream.getvalue() Emitter.register('custom_xml', CustomXmlEmitter, 'text/xml; charset=utf-8') Mimer.register(lambda *a: None, ('text/xml',)) class IpAuthentication(object): """IP Authentication handler """ def __init__(self, auth_func=authenticate, realm='API'): self.auth_func = auth_func self.realm = realm def is_authenticated(self, request): try: settings.API_ALLOWED_IP.index(request.META['REMOTE_ADDR']) return True except:
def register_emitters(): """ Registers the DojoDataEmitter with the name 'dojodata'. """ Emitter.register('dojodata', DojoDataEmitter, 'application/json; charset=utf-8')
class UncachedEmitter(JSONEmitter): """ In websites running under varnish or another cache caching the api can mess the results and return the wrong data this emmitter injects No-Cache headers in response""" def render(self, request): content = super(UncachedEmitter, self).render(request) response = HttpResponse(content) response['Cache-Control'] = 'no-cache, no-store, must-revalidate' response['Content-Type'] = 'application/json; charset=utf-8' response['Pragma'] = 'no-cache' response['Expires'] = 0 return response Emitter.register('json', UncachedEmitter, 'application/json; charset=utf-8') class BaseHandler(Handler): limit = 20 limit_arg = 'paginate_limit' meta = {} def include_meta(self, d): obj = {'meta': self.meta, 'objects': d} return obj def paginate_queryset(self, queryset, request): limit = request.GET.get(self.limit_arg, self.meta.get(self.limit_arg)) paginator = Paginator(queryset, limit or self.limit)
CommitteeItemizedDownloadHandler, CommitteeTopContribsHandler, \ ElectionSummaryHandler from dcapi.aggregates.independentexpenditures.handlers import \ CandidateIndExpHandler, CommitteeIndExpHandler, \ CandidateIndExpDownloadHandler, CommitteeIndExpDownloadHandler, \ TopPACsByIndExpsHandler, TopCandidatesAffectedByIndExpHandler from django.conf.urls.defaults import patterns, url from locksmith.auth.authentication import PistonKeyAuthentication from piston.emitters import Emitter from piston.resource import Resource from dcapi.aggregates.faca.handlers import FACAAgenciesHandler,\ FACACommitteeMembersHandler # We are using the default JSONEmitter so no need to explicitly # register it. However, unregister those we don't need. Emitter.unregister('django') Emitter.unregister('pickle') Emitter.unregister('xml') Emitter.unregister('yaml') ad = {'authentication': PistonKeyAuthentication()} urlpatterns = patterns( '', # amount contributed by one entity to another url( r'^recipient/(?P<recipient_entity>[a-f0-9]{32})/contributor/(?P<contributor_entity>[a-f0-9]{32})/amount.(?P<emitter_format>.+)$', Resource(ContributionAmountHandler, **ad)), # contributors to a single politician
from django.utils import simplejson from django.core.serializers.json import DateTimeAwareJSONEncoder from piston.emitters import Emitter class ExtJSONEmitter(Emitter): """ JSON emitter, understands timestamps, wraps result set in object literal for Ext JS compatibility """ def render(self, request): cb = request.GET.get('callback') ext_dict = {'success': True, 'data': self.construct(), 'message': 'Something good happened on the server!'} seria = simplejson.dumps(ext_dict, cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=4) # Callback if cb: return '%s(%s)' % (cb, seria) return seria Emitter.register('ext-json', ExtJSONEmitter, 'application/json; charset=utf-8')
'id': row['id'], 'cell': [row[field] for field in fields] } for row in row_data] # todo: Is there a better way to determine this? if fields[1] == 'image': total = int(math.ceil(len(Image.objects.all()) / 50.0)) else: total = int(math.ceil(len(File.objects.all()) / 50.0)) jqgrid_dict = { 'page': int(request.GET['page']), 'total': total, 'records': len(rows), 'rows': rows } json = simplejson.dumps(jqgrid_dict, cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=4) # callback if callback: return '%s(%s)' % (callback, json) return json Emitter.register('jqgrid-json', jqGridJSONEmitter, 'application/json; charset=utf-8')
# Universal Subtitles, universalsubtitles.org # # Copyright (C) 2010 Participatory Culture Foundation # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see # http://www.gnu.org/licenses/agpl-3.0.html. from piston.emitters import Emitter from piston.utils import Mimer class PlainEmitter(Emitter): def render(self, request): return self.construct() Emitter.register('plain', PlainEmitter, 'text/plain; charset=utf-8') Mimer.register(lambda *a: None, ('text/plain',))
except: indent = None seria = simplejson.dumps(self.construct(), cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=indent) # Callback if cb and is_valid_jsonp_callback_value(cb): return '%s(%s)' % (cb, seria) return seria Emitter.register('json', JSONEmitter, 'application/json; charset=utf-8') from django.utils.html import strip_tags from film20.utils.html import unescape def strip_html(text): request = get_request() if request and 'striphtml' in request.GET: return unescape(strip_tags(text or '')) return text from django.conf import settings from film20.core.models import Person from film20.config import urls