A => .hgignore +12 -0
@@ 0,0 1,12 @@
+syntax:glob
+.coverage
+.tox
+settings_local.py
+.*.swp
+**.pyc
+MANIFEST
+
+
+syntax:regexp
+^htmlcov$
+^env$
A => README.rst +0 -0
A => awesomebox/__init__.py +3 -0
@@ 0,0 1,3 @@
+__version__ = '0.1'
+
+
A => awesomebox/base.py +57 -0
@@ 0,0 1,57 @@
+from collections import namedtuple
+from django.conf import settings
+from django.utils.importlib import import_module
+from django.core.urlresolvers import reverse_lazy
+
+
+Result = namedtuple('Result', ['success', 'message'])
+
+
+class BaseAwesomebox(object):
+ init_str = '!'
+ cmd_sep = ' '
+ success_url = reverse_lazy('awesomebox_main')
+ template_name = 'awesomebox/awesomebox.html'
+
+ def __init__(self, cmd):
+ self.cmd = cmd
+
+ def run_command(self):
+ cmd = self.cmd
+ if self.init_str is not None and not cmd.startswith(self.init_str):
+ return Result(False, 'Invalid command initialization.')
+
+ real_cmd, _, data = cmd[len(self.init_str):].partition(self.cmd_sep)
+ func = getattr(self, 'cmd_{}'.format(real_cmd, None)
+ if func is None or not callable(func):
+ return Result(False, 'Invalid command.')
+
+ result = func(data)
+ if not isinstance(result, Result):
+ return Result(
+ False,
+ ('Invalid result type given. Expected '
+ 'awesomebox.base.Result instance.'),
+ )
+ return result
+
+ def cmd_echo(self, data):
+ ''' Example function. Returns back the data passed in.
+ '''
+ return Result(True, data)
+
+
+def get_awesomebox_class():
+ ''' Return the class to use for Awesomebox dispatching.
+ '''
+ class NullAwesomeBox(BaseAwesomebox):
+ pass
+
+ cls_path = getattr(settings, 'AWESOMEBOX_CLASS', None)
+ cls = NullAwesomeBox if cls_path is None else import_module(cls_path)
+ if not issubclass(cls, BaseAwesomebox):
+ raise TypeError(
+ 'Invalid Awesomebox Class. Must subclass '
+ 'awesomebox.base.BaseAwesomebox'
+ )
+ return cls
A => awesomebox/forms.py +5 -0
@@ 0,0 1,5 @@
+from django import forms
+
+
+class AwesomeboxForm(forms.Form):
+ cmd = forms.CharField(widget=forms.Textarea())
A => awesomebox/models.py +3 -0
@@ 0,0 1,3 @@
+from django.db import models
+
+# Create your models here.
A => awesomebox/tests.py +16 -0
@@ 0,0 1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.assertEqual(1 + 1, 2)
A => awesomebox/urls.py +9 -0
@@ 0,0 1,9 @@
+from django.conf.urls import patterns, url
+from .views import AwesomeboxView
+
+
+urlpatterns = patterns('awesomebox.views',
+ url(r'^/?$',
+ AwesomeboxView.as_view(),
+ name='awesomebox_main'),
+)
A => awesomebox/views.py +39 -0
@@ 0,0 1,39 @@
+import json
+from django.conf import settings
+from django.views.base import View
+from django.http import HttpResponse
+from django.shortcuts import render, redirect
+from .forms import AwesomeboxForm
+from .base import get_awesomebox_class
+
+AwesomeboxCls = get_awesomebox_class()
+
+
+class AwesomeboxView(View):
+ template_name = AwesomeboxCls.template_name
+ form_class = AwesomeboxForm
+ success_url = AwesomeboxCls.success_url
+
+ def get(self, request, *args, **kwargs):
+ form = self.form_class()
+ return render(request, self.template_name, {'form': form})
+
+ def post(self, request, *args, **kwargs):
+ form = self.form_class(request.POST)
+ if form.is_valid():
+ cmd = form.cleaned_data.get('cmd')
+ abox = AwesomeboxCls(cmd)
+ result = abox.run_command()
+ if request.is_ajax():
+ result = {
+ 'success': result.success,
+ 'message': result.message,
+ }
+ return HttpResponse(
+ json.dumps(result),
+ mimetype='application/json',
+ )
+ # TODO Add message here for user session
+ return redirect(self.success_url)
+
+ return render(request, self.template_name, {'form': form})
A => setup.py +51 -0
@@ 0,0 1,51 @@
+import os
+from distutils.core import setup
+
+project_name = 'awesomebox'
+long_description = open('README.rst').read()
+
+# Idea from django-registration setup.py
+packages, data_files = [], []
+root_dir = os.path.dirname(__file__)
+if root_dir:
+ os.chdir(root_dir)
+
+for dirpath, dirnames, filenames in os.walk(project_name):
+ # Ignore dirnames that start with '.'
+ for i, dirname in enumerate(dirnames):
+ if dirname.startswith('.'):
+ del dirnames[i]
+ if '__init__.py' in filenames:
+ pkg = dirpath.replace(os.path.sep, '.')
+ if os.path.altsep:
+ pkg = pkg.replace(os.path.altsep, '.')
+ packages.append(pkg)
+ elif filenames:
+ prefix = dirpath[(len(project_name) + 1):]
+ for f in filenames:
+ data_files.append(os.path.join(prefix, f))
+
+setup(
+ name='django-awesomebox',
+ version=__import__(project_name).__version__,
+ package_dir={project_name: project_name},
+ packages=packages,
+ package_data={project_name: data_files},
+ description=('Django "awesomebox" to easily dispatch '
+ 'commands from an admin dashboard.'),
+ author='Peter Sanchez',
+ author_email='petersanchez@gmail.com',
+ license='BSD License',
+ url='http://bitbucket.org/petersanchez/django-awesomebox/',
+ long_description=long_description,
+ platforms=['any'],
+ classifiers=[
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Environment :: Web Environment',
+ ],
+)
A => tox.ini +26 -0
@@ 0,0 1,26 @@
+[tox]
+downloadcache = {toxworkdir}/cache/
+envlist = py3.3-django1.5,py2.7-django1.5,py2.6-django1.5,py2.7-django1.4,py2.6-django1.4
+
+[testenv]
+commands = {envpython} runtests.py
+
+[testenv:py3.3-django1.5]
+basepython = python3.3
+deps = django==1.5.1
+
+[testenv:py2.7-django1.5]
+basepython = python2.7
+deps = django==1.5.1
+
+[testenv:py2.7-django1.4]
+basepython = python2.7
+deps = django==1.4.5
+
+[testenv:py2.6-django1.5]
+basepython = python2.6
+deps = django==1.5.1
+
+[testenv:py2.6-django1.4]
+basepython = python2.6
+deps = django==1.4.5