# -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 from __future__ import division import os.path from os.path import join import re from datetime import datetime from urllib2 import unquote import mimetypes from django import forms from django.core.paginator import Paginator from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.db.models import Q, Avg, Count, Sum from django.http import HttpResponse, Http404 from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect from django.template import RequestContext from django.conf import settings from ox.utils import json from ox.django.decorators import login_required_json from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response from ox.django.http import HttpFileResponse import ox def api(request): if request.META['REQUEST_METHOD'] == "OPTIONS": response = HttpResponse('') response = render_to_json_response({'status': {'code': 200, 'text': 'use POST'}}) response['Access-Control-Allow-Origin'] = '*' return response if not 'action' in request.POST: return apidoc(request) function = request.POST['action'] #FIXME: possible to do this in f #data = json.loads(request.POST['data']) f = globals().get('api_'+function, None) if f: response = f(request) else: response = render_to_json_response(json_response(status=400, text='Unknown function %s' % function)) response['Access-Control-Allow-Origin'] = '*' return response def api_api(request): ''' returns list of all known api action return {'status': {'code': int, 'text': string}, 'data': {actions: ['api', 'hello', ...]}} ''' actions = globals().keys() actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions)) actions.sort() ret = {} #FIXME: set cache to False for login, logout, etc. for a in actions: ret[a] = { 'cache': True } return render_to_json_response(json_response({'actions': ret})) def api_apidoc(request): ''' returns array of actions with documentation ''' actions = globals().keys() actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions)) actions.sort() docs = {} for f in actions: docs[f] = get_api_doc(f) return render_to_json_response(json_response({'actions': docs})) #FIXME: REMOVE THIS FUNCTION WHEN THERE ARE REAL USERS!!!! def get_user_json(u): return {'name': 'Guest', 'group': 'guest', 'preferences': {}} def api_hello(request): ''' return {'status': {'code': int, 'text': string}, 'data': {user: object}} ''' #data = json.loads(request.POST['data']) response = json_response({}) if request.user.is_authenticated(): response['data']['user'] = get_user_json(request.user) else: response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'preferences': {}} return render_to_json_response(response) def api_error(request): ''' trows 503 error ''' success = error_is_success return render_to_json_response({}) def api_find(request): data = json.loads(request.POST['data']) # print json.dumps(data) model = getModel(data) response = json_response({}) l = model.get_list(data) if data.has_key('ids'): ids = data['ids'] else: ids = [] if data.has_key('range'): response['data']['items'] = l else: response['data']['items'] = len(l) response['data']['positions'] = _get_positions(ids, l) response['status'] = {'code': 200} return render_to_json_response(response) def _get_positions(ids, l): ret = {} i = 0 for id in ids: for obj in l: if obj['id'] == id: ret[id] = i break i += 1 return ret def api_preview(request): data = json.loads(request.POST['data']) if not data.has_key('id'): return render_to_json_response({'status': {'code': 404}}) id = int(data['id']) model = getModel(data) response = json_response({}) response['status'] = {'code': 200} obj = get_object_or_404(model, pk=id) response['data'] = obj.preview_dict() response['template'] = getTemplate(data, "preview") return render_to_json_response(response) #FIXME: Generalize based on these two functions being the same. def api_info(request): data = json.loads(request.POST['data']) id = int(data['id']) model = getModel(data) response = json_response({}) response['status'] = {'code': 200} obj = get_object_or_404(model, pk=id) response['data'] = obj.info_dict() response['template'] = getTemplate(data, "info") return render_to_json_response(response) def getTemplate(data, tmpl_name): path = join(settings.PROJECT_PATH, "templates", data['module'], data['model'], tmpl_name + ".html") return open(path).read().strip() def getModel(data): module = __import__(data['module']) return module.models.__getattribute__(data['model']) def get_api_doc(f): f = 'api_' + f import sys def trim(docstring): if not docstring: return '' # Convert tabs to spaces (following the normal Python rules) # and split into a list of lines: lines = docstring.expandtabs().splitlines() # Determine minimum indentation (first line doesn't count): indent = sys.maxint for line in lines[1:]: stripped = line.lstrip() if stripped: indent = min(indent, len(line) - len(stripped)) # Remove indentation (first line is special): trimmed = [lines[0].strip()] if indent < sys.maxint: for line in lines[1:]: trimmed.append(line[indent:].rstrip()) # Strip off trailing and leading blank lines: while trimmed and not trimmed[-1]: trimmed.pop() while trimmed and not trimmed[0]: trimmed.pop(0) # Return a single string: return '\n'.join(trimmed) return trim(globals()[f].__doc__) def apidoc(request): ''' this is used for online documentation at http://127.0.0.1:8000/api/ ''' functions = filter(lambda x: x.startswith('api_'), globals().keys()) api = [] for f in sorted(functions): api.append({ 'name': f[4:], 'doc': get_api_doc(f[4:]).replace('\n', '
\n') }) context = RequestContext(request, {'api': api, 'sitename': settings.SITENAME,}) return render_to_response('api.html', context) def jsdoc(request): ''' Used to document OxUI JS Widgets ''' context = RequestContext(request, {}) return render_to_response("jsdoc.html", context) ''' ajax html snapshots http://code.google.com/web/ajaxcrawling/docs/html-snapshot.html ''' def html_snapshot(request): fragment = unquote(request.GET['_escaped_fragment_']) url = request.build_absolute_uri('/ra') url = 'http://'+settings.URL response = HttpResponse('sorry, server side rendering for %s!#%s not yet implemented'%(url, fragment)) return response