diff --git a/ox/django/__init__.py b/ox/django/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/ox/django/api/__init__.py b/ox/django/api/__init__.py
deleted file mode 100644
index cf410f8..0000000
--- a/ox/django/api/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from actions import actions
diff --git a/ox/django/api/actions.py b/ox/django/api/actions.py
deleted file mode 100644
index 8579080..0000000
--- a/ox/django/api/actions.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from __future__ import division, with_statement
-import inspect
-import sys
-
-from django.conf import settings
-
-from ..shortcuts import render_to_json_response, json_response
-from ...utils import json
-
-def autodiscover():
- # Register api actions from all installed apps
- from importlib import import_module
- from django.utils.module_loading import module_has_submodule
- for app in settings.INSTALLED_APPS:
- if app != 'api':
- mod = import_module(app)
- try:
- import_module('%s.views'%app)
- except:
- if module_has_submodule(mod, 'views'):
- raise
-
-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)
-
-
-class ApiActions(dict):
- properties = {}
- versions = {}
- def __init__(self):
-
- def api(request, data):
- '''
- Returns a list of all api actions
- takes {
- code: boolean, // if true, return source code (optional)
- docs: boolean // if true, return doc strings (optional)
- }
- returns {
- actions: {
- name: {
- cache: boolean, // if false, don't cache results
- code: string, // source code
- doc: string // doc strings
- },
- ... // more actions
- }
- }
- '''
- docs = data.get('docs', False)
- code = data.get('code', False)
- version = getattr(request, 'version', None)
- if version:
- _actions = self.versions.get(version, {}).keys()
- _actions = list(set(_actions + self.keys()))
- else:
- _actions = self.keys()
- _actions.sort()
- actions = {}
- for a in _actions:
- actions[a] = self.properties[a]
- if docs:
- actions[a]['doc'] = self.doc(a, version)
- if code:
- actions[a]['code'] = self.code(a, version)
- response = json_response({'actions': actions})
- return render_to_json_response(response)
- self.register(api)
-
- def doc(self, name, version=None):
- if version:
- f = self.versions[version].get(name, self.get(name))
- else:
- f = self[name]
- return trim(f.__doc__)
-
- def code(self, name, version=None):
- if version:
- f = self.versions[version].get(name, self.get(name))
- else:
- f = self[name]
- if name != 'api' and hasattr(f, 'func_closure') and f.func_closure:
- fc = filter(lambda c: hasattr(c.cell_contents, '__call__'), f.func_closure)
- f = fc[len(fc)-1].cell_contents
- info = f.func_code.co_filename[len(settings.PROJECT_ROOT)+1:]
- info = u'%s:%s' % (info, f.func_code.co_firstlineno)
- return info, trim(inspect.getsource(f))
-
- def register(self, method, action=None, cache=True, version=None):
- if not action:
- action = method.func_name
- if version:
- if not version in self.versions:
- self.versions[version] = {}
- self.versions[version][action] = method
- else:
- self[action] = method
- self.properties[action] = {'cache': cache}
-
- def unregister(self, action):
- if action in self:
- del self[action]
-
-actions = ApiActions()
-
-def error(request, data):
- '''
- This action is used to test API error codes. It should return a 503 error.
- '''
- success = error_is_success
- return render_to_json_response({})
-actions.register(error)
diff --git a/ox/django/api/urls.py b/ox/django/api/urls.py
deleted file mode 100644
index 5346a98..0000000
--- a/ox/django/api/urls.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-
-from django.conf.urls import url
-
-import views
-
-import actions
-actions.autodiscover()
-
-urlpatterns = [
- url(r'^$', views.api),
-]
diff --git a/ox/django/api/views.py b/ox/django/api/views.py
deleted file mode 100644
index 43591ed..0000000
--- a/ox/django/api/views.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from __future__ import division, with_statement
-
-import json
-
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-from django.conf import settings
-
-from ..shortcuts import render_to_json_response, json_response
-
-from actions import actions
-
-def api(request):
- if request.META['REQUEST_METHOD'] == "OPTIONS":
- response = render_to_json_response({'status': {'code': 200,
- 'text': 'use POST'}})
- response['Access-Control-Allow-Origin'] = '*'
- return response
- if request.META['REQUEST_METHOD'] != "POST" or (
- not 'action' in request.POST and request.META.get('CONTENT_TYPE') != 'application/json'
- ):
- methods = actions.keys()
- api = []
- for f in sorted(methods):
- api.append({'name': f,
- 'doc': actions.doc(f).replace('\n', '
\n')})
- context = RequestContext(request, {
- 'api': api,
- 'settings': settings,
- 'sitename': settings.SITENAME
- })
- return render_to_response('api.html', context)
- if request.META.get('CONTENT_TYPE') == 'application/json':
- r = json.loads(request.body)
- action = r['action']
- data = r.get('data', {})
- else:
- action = request.POST['action']
- data = json.loads(request.POST.get('data', '{}'))
- version = getattr(request, 'version', None)
- if version:
- f = actions.versions.get(version, {}).get(action, actions.get(action))
- else:
- f = actions.get(action)
- if f:
- response = f(request, data)
- else:
- response = render_to_json_response(json_response(status=400,
- text='Unknown action %s' % action))
- response['Access-Control-Allow-Origin'] = '*'
- return response
-
diff --git a/ox/django/decorators.py b/ox/django/decorators.py
deleted file mode 100644
index 98aa9dd..0000000
--- a/ox/django/decorators.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-
-try:
- from django.contrib.auth.decorators import wraps
-except:
- from django.utils.functional import wraps
-from shortcuts import render_to_json_response
-
-def login_required_json(function=None):
- """
- Decorator for views that checks that the user is logged in
- return json error if not logged in.
- """
-
- def _wrapped_view(request, *args, **kwargs):
- if request.user.is_authenticated():
- return function(request, *args, **kwargs)
- return render_to_json_response({'status': {'code': 401, 'text': 'login required'}})
- return wraps(function)(_wrapped_view)
-
-def admin_required_json(function=None):
- """
- Decorator for views that checks that the user is logged in
- return json error if not logged in.
- """
-
- def _wrapped_view(request, *args, **kwargs):
- if request.user.is_authenticated() and request.user.profile.get_level() == 'admin':
- return function(request, *args, **kwargs)
- return render_to_json_response({'status': {'code': 403, 'text': 'permission denied'}})
- return wraps(function)(_wrapped_view)
diff --git a/ox/django/fields.py b/ox/django/fields.py
deleted file mode 100644
index 9270468..0000000
--- a/ox/django/fields.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-import time
-import datetime
-import copy
-
-from django.db import models
-from django.utils import datetime_safe
-from six import string_types
-
-from ox.utils import json
-
-
-def to_json(python_object):
- if isinstance(python_object, datetime.datetime):
- if python_object.year < 1900:
- tt = python_object.timetuple()
- value = '%d-%02d-%02dT%02d:%02d%02dZ' % tuple(list(tt)[:6])
- else:
- value = python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
- return {'__class__': 'datetime.datetime',
- '__value__': value}
- if isinstance(python_object, datetime_safe.datetime):
- return {'__class__': 'datetime.datetime',
- '__value__': python_object.strftime('%Y-%m-%dT%H:%M:%SZ')}
- if isinstance(python_object, time.struct_time):
- return {'__class__': 'time.asctime',
- '__value__': time.asctime(python_object)}
- try:
- if isinstance(python_object, bytes):
- return {'__class__': 'bytes',
- '__value__': list(python_object)}
- except:
- pass
- raise TypeError(repr(python_object) + ' is not JSON serializable')
-
-def from_json(json_object):
- if '__class__' in json_object:
- if json_object['__class__'] == 'bytes':
- return bytes(json_object['__value__'])
- if json_object['__class__'] == 'datetime_safe.datetime' \
- or json_object['__class__'] == 'datetime.datetime':
- return datetime_safe.datetime.strptime(json_object['__value__'], '%Y-%m-%dT%H:%M:%SZ')
- if json_object['__class__'] == 'time.asctime':
- return time.strptime(json_object['__value__'])
- return json_object
-
-class DictField(models.TextField):
- _type = dict
-
- def loads(self, value):
- return json.loads(value, object_hook=from_json)
-
- def dumps(self, obj):
- return json.dumps(obj, default=to_json, ensure_ascii=False)
-
- def from_db_value(self, value, expression, connection, context):
- if value is None:
- return value
- if isinstance(value, self._type):
- return value
- try:
- value = self.loads(value)
- except:
- raise Exception('failed to parse value: %s' % value)
- if value is not None:
- assert isinstance(value, self._type)
- return value
-
- def get_prep_value(self, value):
- if isinstance(value, self._type):
- value = self.dumps(value)
- if value is not None:
- assert isinstance(value, string_types)
- value = models.TextField.get_prep_value(self, value)
- return value
-
- def get_default(self):
- if self.has_default():
- if callable(self.default):
- return self.default()
- return copy.deepcopy(self.default)
- return super(DictField, self).get_default()
-
-class TupleField(DictField):
- _type = (tuple, list)
-
- def loads(self, value):
- value = DictField.loads(self, value)
- if isinstance(value, list):
- value = tuple(value)
- return value
-
-try:
- from south.modelsinspector import add_introspection_rules
- add_introspection_rules([], ["^ox.django\.fields\.DictField"])
- add_introspection_rules([], ["^ox.django\.fields\.TupleField"])
-except:
- pass
diff --git a/ox/django/http.py b/ox/django/http.py
deleted file mode 100644
index c07c36f..0000000
--- a/ox/django/http.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-import os
-import mimetypes
-from datetime import datetime, timedelta
-from six.moves.urllib.parse import quote
-
-from django.http import HttpResponse, Http404
-from django.conf import settings
-
-
-def HttpFileResponse(path, content_type=None, filename=None):
- if not os.path.exists(path):
- raise Http404
- if not content_type:
- content_type = mimetypes.guess_type(path)[0]
- if not content_type:
- content_type = 'application/octet-stream'
-
- if getattr(settings, 'XACCELREDIRECT', False):
- response = HttpResponse()
- response['Content-Length'] = os.stat(path).st_size
-
- for PREFIX in ('STATIC', 'MEDIA'):
- root = getattr(settings, PREFIX+'_ROOT', '')
- url = getattr(settings, PREFIX+'_URL', '')
- if root and path.startswith(root):
- path = url + path[len(root)+1:]
- if not isinstance(path, bytes):
- path = path.encode('utf-8')
- response['X-Accel-Redirect'] = path
- if content_type:
- response['Content-Type'] = content_type
- elif getattr(settings, 'XSENDFILE', False):
- response = HttpResponse()
- if not isinstance(path, bytes):
- path = path.encode('utf-8')
- response['X-Sendfile'] = path
- if content_type:
- response['Content-Type'] = content_type
- response['Content-Length'] = os.stat(path).st_size
- else:
- response = HttpResponse(open(path), content_type=content_type)
- if filename:
- if not isinstance(filename, bytes):
- filename = filename.encode('utf-8')
- response['Content-Disposition'] = "attachment; filename*=UTF=8''%s" % quote(filename)
-
- response['Expires'] = datetime.strftime(datetime.utcnow() + timedelta(days=1), "%a, %d-%b-%Y %H:%M:%S GMT")
-
- def allow_access():
- for key in ('X-Accel-Redirect', 'X-Sendfile'):
- if key in response:
- del response[key]
- response['Access-Control-Allow-Origin'] = '*'
- response.allow_access = allow_access
- return response
-
diff --git a/ox/django/middleware.py b/ox/django/middleware.py
deleted file mode 100644
index 751c24a..0000000
--- a/ox/django/middleware.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-
-from .shortcuts import HttpErrorJson, render_to_json_response
-
-class ExceptionMiddleware(object):
- def process_exception(self, request, exception):
- if isinstance(exception, HttpErrorJson):
- return render_to_json_response(exception.response)
- return None
-
-class ChromeFrameMiddleware(object):
- def process_response(self, request, response):
- response['X-UA-Compatible'] = 'chrome=1'
- return response
diff --git a/ox/django/monitor.py b/ox/django/monitor.py
deleted file mode 100644
index f87e839..0000000
--- a/ox/django/monitor.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from __future__ import print_function
-
-import os
-import sys
-import signal
-import threading
-import atexit
-from six.moves.queue import Queue
-
-_interval = 1.0
-_times = {}
-_files = []
-
-_running = False
-_queue = Queue()
-_lock = threading.Lock()
-
-def _restart(path):
- _queue.put(True)
- prefix = 'monitor (pid=%d):' % os.getpid()
- print('%s Change detected to \'%s\'.' % (prefix, path), file=sys.stderr)
- print('%s Triggering process restart.' % prefix, file=sys.stderr)
- os.kill(os.getpid(), signal.SIGINT)
-
-def _modified(path):
- try:
- # If path doesn't denote a file and were previously
- # tracking it, then it has been removed or the file type
- # has changed so force a restart. If not previously
- # tracking the file then we can ignore it as probably
- # pseudo reference such as when file extracted from a
- # collection of modules contained in a zip file.
-
- if not os.path.isfile(path):
- return path in _times
-
- # Check for when file last modified.
-
- mtime = os.stat(path).st_mtime
- if path not in _times:
- _times[path] = mtime
-
- # Force restart when modification time has changed, even
- # if time now older, as that could indicate older file
- # has been restored.
-
- if mtime != _times[path]:
- return True
- except:
- # If any exception occured, likely that file has been
- # been removed just before stat(), so force a restart.
-
- return True
-
- return False
-
-def _monitor():
- while 1:
- # Check modification times on all files in sys.modules.
-
- for module in list(sys.modules.values()):
- if not hasattr(module, '__file__'):
- continue
- path = getattr(module, '__file__')
- if not path:
- continue
- if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
- path = path[:-1]
- if _modified(path):
- return _restart(path)
-
- # Check modification times on files which have
- # specifically been registered for monitoring.
-
- for path in _files:
- if _modified(path):
- return _restart(path)
-
- # Go to sleep for specified interval.
-
- try:
- return _queue.get(timeout=_interval)
- except:
- pass
-
-_thread = threading.Thread(target=_monitor)
-_thread.setDaemon(True)
-
-def _exiting():
- try:
- _queue.put(True)
- except:
- pass
- _thread.join()
-
-atexit.register(_exiting)
-
-def track(path):
- if not path in _files:
- _files.append(path)
-
-def start(interval=1.0):
- global _interval
- if interval < _interval:
- _interval = interval
-
- global _running
- _lock.acquire()
- if not _running:
- _running = True
- _thread.start()
- _lock.release()
diff --git a/ox/django/query.py b/ox/django/query.py
deleted file mode 100644
index 38ab9a6..0000000
--- a/ox/django/query.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-
-from django.db.models.sql import Query
-from django.db.models.sql.compiler import SQLCompiler
-from django.db import connections
-import django.db.models.query
-
-'''
-models.py:
------------------------------------
-from ox.django.query import QuerySet
-
-class Manager(models.Manager):
- def get_query_set(self):
- return QuerySet(self.model)
-
-class Model(models.Model):
- ...
- objects = Manager()
-'''
-
-class NullLastSQLCompiler(SQLCompiler):
-
- def get_order_by(self):
- result = super(NullLastSQLCompiler, self).get_order_by()
- if self.query.nulls_last and result \
- and self.connection.vendor == 'postgresql':
- return [(expr, (sql + ' NULLS LAST', params, is_ref))
- for (expr, (sql, params, is_ref)) in result]
- return result
-
-class NullsLastQuery(Query):
- nulls_last = False
-
- def clone(self, *args, **kwargs):
- obj = super(NullsLastQuery, self).clone(*args, **kwargs)
- obj.nulls_last = self.nulls_last
- return obj
-
- def get_compiler(self, using=None, connection=None):
- if using is None and connection is None:
- raise ValueError("Need either using or connection")
- if using:
- connection = connections[using]
- return NullLastSQLCompiler(self, connection, using)
-
-class QuerySet(django.db.models.query.QuerySet):
-
- def __init__(self, model=None, query=None, using=None, **kwargs):
- super(QuerySet, self).__init__(model=model, query=query, using=None, **kwargs)
- self.query = query or NullsLastQuery(self.model)
-
- def order_by(self, *args, **kwargs):
- nulls_last = kwargs.pop('nulls_last', False)
- obj = super(QuerySet, self).order_by(*args, **kwargs)
- obj.query.nulls_last = nulls_last
- return obj
diff --git a/ox/django/shortcuts.py b/ox/django/shortcuts.py
deleted file mode 100644
index 2e6a4fb..0000000
--- a/ox/django/shortcuts.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from __future__ import print_function
-import datetime
-from django.utils import datetime_safe
-from django.http import HttpResponse, Http404
-try:
- import simplejson as json
-except ImportError:
- from django.utils import simplejson as json
-from django.conf import settings
-
-class HttpErrorJson(Http404):
- def __init__(self, response):
- self.response = response
-
-def json_response(data=None, status=200, text='ok'):
- if not data:
- data = {}
- return {'status': {'code': status, 'text': text}, 'data': data}
-
-def _to_json(python_object):
- if isinstance(python_object, datetime.datetime):
- if python_object.year < 1900:
- tt = python_object.timetuple()
- return '%d-%02d-%02dT%02d:%02d%02dZ' % tuple(list(tt)[:6])
- return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
- if isinstance(python_object, datetime_safe.datetime):
- return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
- raise TypeError(u'%s %s is not JSON serializable' % (repr(python_object), type(python_object)))
-
-def render_to_json_response(dictionary, content_type="text/json", status=200):
- indent=None
- if settings.DEBUG:
- content_type = "text/javascript"
- indent = 2
- if getattr(settings, 'JSON_DEBUG', False):
- print(json.dumps(dictionary, indent=2, default=_to_json, ensure_ascii=False).encode('utf-8'))
-
- return HttpResponse(json.dumps(dictionary, indent=indent, default=_to_json,
- ensure_ascii=False).encode('utf-8'), content_type=content_type, status=status)
-
-def get_object_or_404_json(klass, *args, **kwargs):
- from django.shortcuts import _get_queryset
- queryset = _get_queryset(klass)
- try:
- return queryset.get(*args, **kwargs)
- except queryset.model.DoesNotExist:
- response = {'status': {'code': 404,
- 'text': '%s not found' % queryset.model._meta.object_name}}
- raise HttpErrorJson(response)
-
diff --git a/ox/django/utils.py b/ox/django/utils.py
deleted file mode 100644
index cbc0067..0000000
--- a/ox/django/utils.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from django.utils.datetime_safe import datetime
-from django.http import HttpResponse,Http404
-from django.core.servers.basehttp import FileWrapper
-from django.conf import settings
-
-import mimetypes
-import os
-
-def basic_sendfile(fname,download_name=None):
- if not os.path.exists(fname):
- raise Http404
-
- wrapper = FileWrapper(open(fname,"r"))
-
- content_type = mimetypes.guess_type(fname)[0]
- response = HttpResponse(wrapper, content_type=content_type)
- response['Content-Length'] = os.path.getsize(fname)
-
- if download_name:
- response['Content-Disposition'] = "attachment; filename=%s"%download_name
-
- return response
-
-def x_sendfile(fname,download_name=None):
- if not os.path.exists(fname):
- raise Http404
-
- content_type = mimetypes.guess_type(fname)[0]
- response = HttpResponse('', content_type=content_type)
- response['Content-Length'] = os.path.getsize(fname)
- response['X-Sendfile'] = fname
-
- if download_name:
- response['Content-Disposition'] = "attachment; filename=%s"%download_name
-
- return response
-
-try:
- __sendfile = getattr(settings,'SENDFILE',False) == 'x_sendfile'
-except:
- __sendfile = False
-if __sendfile == 'x_sendfile':
- sendfile = x_sendfile
-else:
- sendfile = basic_sendfile
-
diff --git a/ox/django/views.py b/ox/django/views.py
deleted file mode 100644
index 24a20d6..0000000
--- a/ox/django/views.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-# vi:si:et:sw=4:sts=4:ts=4
-from six import StringIO, PY2
-from six.moves import urllib
-from six.moves import http_cookiejar as cookielib
-
-from celery.utils import get_full_cls_name
-from celery.backends import default_backend
-
-from django.http import HttpResponse
-from django.conf import settings
-
-from shortcuts import json_response
-import ox
-
-
-def task_status(request, task_id):
- response = json_response(status=200, text='ok')
- status = default_backend.get_status(task_id)
- res = default_backend.get_result(task_id)
- response['data'] = {
- 'id': task_id,
- 'status': status,
- 'result': res
- }
- if status in default_backend.EXCEPTION_STATES:
- traceback = default_backend.get_traceback(task_id)
- response['data'].update({'result': str(res.args[0]),
- 'exc': get_full_cls_name(res.__class__),
- 'traceback': traceback})
- return response
-
-class SessionCookieJar(cookielib.LWPCookieJar):
- def save(self):
- return "#LWP-Cookies-2.0\n" + self.as_lwp_str()
-
- def load(self, data, ignore_discard=True, ignore_expires=True):
- f = StringIO(data)
- self._really_load(f, 'memory', ignore_discard, ignore_expires)
-
-def api_proxy(request):
- '''
- settings.OXAPI_URL =...
- from ox.django.views import api_proxy
- urlpatterns = patterns('',
- url(r'^api/$', api_proxy)
- '''
- url = settings.OXAPI_URL
- cj = SessionCookieJar()
- if 'cj' in request.session:
- cj.load(request.session['cj'])
- opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
- opener.addheaders = [
- ('User-Agent', request.META.get('HTTP_USER_AGENT'))
- ]
- form = ox.MultiPartForm()
- for key in request.POST:
- form.add_field(key, request.POST[key])
- r = urllib.request.Request(url)
- body = form.body()
- r.add_header('Content-type', form.get_content_type())
- r.add_header('Content-length', len(body))
- r.add_data(body)
- f = opener.open(r)
- response = HttpResponse(f.read())
- request.session['cj'] = cj.save()
- return response
diff --git a/ox/django/widgets.py b/ox/django/widgets.py
deleted file mode 100644
index b22e57e..0000000
--- a/ox/django/widgets.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import django.newforms as forms
-from string import Template
-from django.utils.safestring import mark_safe
-
-class FirefoggWidget(forms.FileInput):
- def render(self, name, value, attrs=None):
- tpl = Template(u"""