You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@community.apache.org by rg...@apache.org on 2015/06/07 12:32:59 UTC

svn commit: r1684019 - in /comdev/tools: ./ comdev_tools/ events_list/ events_list/templates/ events_list/templates/events/ scripts/

Author: rgardler
Date: Sun Jun  7 10:32:59 2015
New Revision: 1684019

URL: http://svn.apache.org/r1684019
Log:
beginings of a Django app - does the import but no pretty stuff yet

Added:
    comdev/tools/.svnignore
    comdev/tools/Dockerfile
    comdev/tools/comdev_tools/
    comdev/tools/comdev_tools/__init__.py
    comdev/tools/comdev_tools/settings.py
    comdev/tools/comdev_tools/urls.py
    comdev/tools/comdev_tools/wsgi.py
    comdev/tools/events_list/.svnignore
    comdev/tools/events_list/__init__.py
    comdev/tools/events_list/admin.py
    comdev/tools/events_list/models.py
    comdev/tools/events_list/templates/
    comdev/tools/events_list/templates/events/
    comdev/tools/events_list/templates/events/importMeetups.html
    comdev/tools/events_list/templates/events/index.html
    comdev/tools/events_list/tests.py
    comdev/tools/events_list/urls.py
    comdev/tools/events_list/views.py
    comdev/tools/manage.py
    comdev/tools/readme.md
    comdev/tools/requirements.txt
    comdev/tools/scripts/   (with props)
    comdev/tools/scripts/.svnignore
    comdev/tools/scripts/config.tmpl
    comdev/tools/scripts/configHyper-v.sh
Modified:
    comdev/tools/   (props changed)
    comdev/tools/events_list/   (props changed)
    comdev/tools/events_list/meetups.py

Propchange: comdev/tools/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1,8 @@
+scripts/config.sh
+
+# Generated files
+groups.json
+meetups.json
+meetups.mdtext
+meetups.mlist
+meetups.tweets

Added: comdev/tools/.svnignore
URL: http://svn.apache.org/viewvc/comdev/tools/.svnignore?rev=1684019&view=auto
==============================================================================
--- comdev/tools/.svnignore (added)
+++ comdev/tools/.svnignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1,8 @@
+scripts/config.sh
+
+# Generated files
+groups.json
+meetups.json
+meetups.mdtext
+meetups.mlist
+meetups.tweets
\ No newline at end of file

Added: comdev/tools/Dockerfile
URL: http://svn.apache.org/viewvc/comdev/tools/Dockerfile?rev=1684019&view=auto
==============================================================================
--- comdev/tools/Dockerfile (added)
+++ comdev/tools/Dockerfile Sun Jun  7 10:32:59 2015
@@ -0,0 +1,14 @@
+FROM python:2.7
+ENV PYTHONUNBUFFERED 1
+
+RUN mkdir /project
+WORKDIR /project
+
+ADD requirements.txt /project/
+RUN pip install -r requirements.txt
+
+EXPOSE 8000
+
+ADD . /project/
+
+

Added: comdev/tools/comdev_tools/__init__.py
URL: http://svn.apache.org/viewvc/comdev/tools/comdev_tools/__init__.py?rev=1684019&view=auto
==============================================================================
    (empty)

Added: comdev/tools/comdev_tools/settings.py
URL: http://svn.apache.org/viewvc/comdev/tools/comdev_tools/settings.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/comdev_tools/settings.py (added)
+++ comdev/tools/comdev_tools/settings.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,106 @@
+""" 
+Django settings for comdev_tools project.
+
+Generated by 'django-admin startproject' using Django 1.8.2.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.8/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.8/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'f%7+@@op1xt_d7&hs!38u_2-_ij+ehrh=@0ke%%0#pt&b*&gb3'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = (
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'events_list'
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+)
+
+ROOT_URLCONF = 'comdev_tools.urls'
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'comdev_tools.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql_psycopg2',
+        'NAME': 'postgres',
+        'USER': 'postgres',
+        'HOST': 'db',
+        'PORT': 5432
+    }
+}
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.8/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.8/howto/static-files/
+
+STATIC_URL = '/static/'

Added: comdev/tools/comdev_tools/urls.py
URL: http://svn.apache.org/viewvc/comdev/tools/comdev_tools/urls.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/comdev_tools/urls.py (added)
+++ comdev/tools/comdev_tools/urls.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,22 @@
+"""comdev_tools URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/1.8/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
+Including another URLconf
+    1. Add an import:  from blog import urls as blog_urls
+    2. Add a URL to urlpatterns:  url(r'^blog/', include(blog_urls))
+"""
+from django.conf.urls import include, url
+from django.contrib import admin
+
+urlpatterns = [
+    url(r'^events/', include('events_list.urls')),
+    url(r'^admin/', include(admin.site.urls)),
+]

Added: comdev/tools/comdev_tools/wsgi.py
URL: http://svn.apache.org/viewvc/comdev/tools/comdev_tools/wsgi.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/comdev_tools/wsgi.py (added)
+++ comdev/tools/comdev_tools/wsgi.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,16 @@
+"""
+WSGI config for comdev_tools project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "comdev_tools.settings")
+
+application = get_wsgi_application()

Propchange: comdev/tools/events_list/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1,7 @@
+# Generated files
+groups.json
+meetups.json
+meetups.mdtext
+meetups.mlist
+meetups.tweets
+migrations

Added: comdev/tools/events_list/.svnignore
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/.svnignore?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/.svnignore (added)
+++ comdev/tools/events_list/.svnignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1,7 @@
+# Generated files
+groups.json
+meetups.json
+meetups.mdtext
+meetups.mlist
+meetups.tweets
+migrations
\ No newline at end of file

Added: comdev/tools/events_list/__init__.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/__init__.py?rev=1684019&view=auto
==============================================================================
    (empty)

Added: comdev/tools/events_list/admin.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/admin.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/admin.py (added)
+++ comdev/tools/events_list/admin.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,7 @@
+from django.contrib import admin
+from .models import Event, Group
+
+admin.site.register(Event)
+admin.site.register(Group)
+
+

Modified: comdev/tools/events_list/meetups.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/meetups.py?rev=1684019&r1=1684018&r2=1684019&view=diff
==============================================================================
--- comdev/tools/events_list/meetups.py (original)
+++ comdev/tools/events_list/meetups.py Sun Jun  7 10:32:59 2015
@@ -4,6 +4,7 @@ import urllib2
 import json
 import time
 import re
+import io
 
 ###########################
 #
@@ -26,7 +27,6 @@ import re
 # Magic
 import sys    # sys.setdefaultencoding is cancelled by site.py
 reload(sys)    # to re-enable sys.setdefaultencoding()
-sys.setdefaultencoding('utf-8')
 
 def importMeetups():
 
@@ -56,7 +56,7 @@ def importMeetups():
 
     for meetup in meetups:
         groups[ str( meetup['group']['id'] ) ] = meetup['group']['name']
-
+    
     keys = groups.keys()
     keyarg = ",".join( keys )
     
@@ -70,13 +70,13 @@ def importMeetups():
 
     print "Writing raw JSON data to 'meetups.json' and 'groups.json'"
 
-    raw = open('meetups.json', 'w')
-    raw.write(json.dumps(meetups, indent=4))
-    raw.close()
-
-    raw = open('groups.json', 'w')
-    raw.write(json.dumps(grps, indent=4))
-    raw.close();
+    with io.open('meetups.json', 'w', encoding='utf-8') as raw:
+        raw.write(json.dumps(meetups, indent=4, ensure_ascii=False))
+        raw.close()
+
+    with io.open('groups.json', 'w', encoding='utf-8') as raw:
+        raw.write(json.dumps(grps, indent=4, ensure_ascii=False))
+        raw.close();
 
 def createFiles():
     print "Loading meetups database..."
@@ -105,12 +105,12 @@ def createFiles():
     weeklater = (nowts * 1000 ) + ( week * 86400 * 1000 )
     twoweeklater = (nowts * 1000 ) + ( twoweek * 86400 * 1000 )
 
-    tweets = open('meetups.tweets', 'w')
-    mlist = open('meetups.mlist', 'w')
-    website = open('meetups.mdtext', 'w')
-
+    tweets = io. open('meetups.tweets', 'w', encoding='utf-8')
+    mlist = io.open('meetups.mlist', 'w', encoding='utf-8')
+    website = io.open('meetups.mdtext', 'w', encoding='utf-8')
+    
     # Standard intro to mailing list post
-    mlist.write( '''The following are the meetups I'm aware of in the coming week where
+    mlist.write( unicode('''The following are the meetups I'm aware of in the coming week where
     Apache enthusiasts are likely to be present. If you know
     of others, please let me know, and/or add them to
     http://apache.org/events
@@ -121,8 +121,8 @@ def createFiles():
 
     --Rich
 
-    ''')
-
+    '''))
+    
     for meetup in meetups:
         eventts = int( meetup['time'] + meetup['utc_offset'] )
 
@@ -144,8 +144,8 @@ def createFiles():
         if 'state' in grp.keys():
             eventout = eventout + grp['state'] + ', '
         eventout = eventout + grp['country'] + "\n"
-        website.write( str(eventout) )
-
+        website.write( unicode(eventout) )
+        
         # For everything else, a week is enough
         if eventts > weeklater:
             continue
@@ -155,15 +155,15 @@ def createFiles():
         if 'state' in grp.keys():
             eventout = eventout + grp['state'] + ', '
         eventout = eventout + grp['country'] + ': ' + meetup['name'] + ' - ' + meetup['event_url'] + " #Apache #Meetup\n"
-        tweets.write( str( eventout ))
+        tweets.write( unicode( eventout ))
 
         # For mailing list
         eventout = '* ' + t + ' in ' + grp['city'] + ', '
         if 'state' in grp.keys():
             eventout = eventout + grp['state'] + ', '
         eventout = eventout + grp['country'] + ': ' + meetup['name'] + ' - ' + meetup['event_url'] + "\n\n"
-        mlist.write( str( eventout ))
-
+        mlist.write( unicode( eventout ))
+        
     # Barn door
     tweets.close()
     mlist.close()

Added: comdev/tools/events_list/models.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/models.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/models.py (added)
+++ comdev/tools/events_list/models.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,21 @@
+from django.db import models
+
+class Group(models.Model):
+    name = models.CharField(max_length=200)
+    city = models.CharField(max_length=50)
+    state = models.CharField(max_length=25)
+    country = models.CharField(max_length=30)
+    meetupID = models.BigIntegerField(verbose_name = "Meetups.com ID", unique=True)
+
+    def __str__(self):
+        return self.name
+
+    
+class Event(models.Model):
+    name = models.CharField(max_length=200)
+    event_url = models.URLField()
+    group = models.ForeignKey(Group)
+    meetupID = models.CharField(verbose_name = "Meetups.com ID", max_length=50, unique=True)
+
+    def __str__(self):
+        return self.name

Added: comdev/tools/events_list/templates/events/importMeetups.html
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/templates/events/importMeetups.html?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/templates/events/importMeetups.html (added)
+++ comdev/tools/events_list/templates/events/importMeetups.html Sun Jun  7 10:32:59 2015
@@ -0,0 +1,3 @@
+<h1>Meetups Imported</h1>
+<p>You can view them in the <a href="/admin">Admin</a> interface.</p>
+<p>Better yet you will add code to make a pretty view on the <a href="/events">Events Index</a> page.</p>

Added: comdev/tools/events_list/templates/events/index.html
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/templates/events/index.html?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/templates/events/index.html (added)
+++ comdev/tools/events_list/templates/events/index.html Sun Jun  7 10:32:59 2015
@@ -0,0 +1,2 @@
+<h1>Events</h1>
+<a href="/events/importMeetups">Import Meetups</a>

Added: comdev/tools/events_list/tests.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/tests.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/tests.py (added)
+++ comdev/tools/events_list/tests.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

Added: comdev/tools/events_list/urls.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/urls.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/urls.py (added)
+++ comdev/tools/events_list/urls.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,8 @@
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    url(r'^$', views.index, name='index'),
+    url(r'^importMeetups/$', views.importMeetups, name='importMeetups'),
+]

Added: comdev/tools/events_list/views.py
URL: http://svn.apache.org/viewvc/comdev/tools/events_list/views.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/events_list/views.py (added)
+++ comdev/tools/events_list/views.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,102 @@
+from django.shortcuts import get_object_or_404, render
+from django.http import HttpResponse
+from django.template import RequestContext, loader
+from events_list.models import Event, Group
+import json
+import logging
+import urllib2
+import sys
+
+logger = logging.getLogger(__name__)
+
+def index(request):
+    template = loader.get_template('events/index.html')
+    context = RequestContext(request)
+    return HttpResponse(template.render(context))
+
+def importMeetups(request):
+    print "Rounding up the ponies ..."
+
+    # Note that this API key is *my* API key (rbowen) and if we start using
+    # it more than a few dozen times an hour it's likely to get revoked.
+    # Please play nice.
+    key = "3a7711454d145e404e531c2ee6f391d"
+
+    # Radius is defined around Lexington, KY, but it's infinite radius, so
+    # should work everywhere.
+    url = "https://api.meetup.com/2/open_events?&sign=true&photo-host=public&state=ky&city=lexington&country=usa&text=apache&radius=10000&sign=true&key=" + key
+
+    # Radius is defined around Lexington, KY, but it's infinite radius, so
+    # should work everywhere.
+    url = "https://api.meetup.com/2/open_events?&sign=true&photo-host=public&state=ky&city=lexington&country=usa&text=apache&radius=10000&sign=true&key=" + key
+
+    print "Fetching meetups ..."
+
+    response = urllib2.urlopen(url)
+    m = response.read()
+
+    print "Parsing results ..."
+    r = json.loads(m)
+    meetups = r['results']
+
+    groups = {}
+
+    print "Fetching group details ..."
+
+    for meetup in meetups:
+        groups[ str( meetup['group']['id'] ) ] = meetup['group']['name']
+    
+    keys = groups.keys()
+    keyarg = ",".join( keys )
+    
+    group_url = "https://api.meetup.com/2/groups?&sign=true&photo-host=public&group_id=" + keyarg + "&key=" + key
+
+    response = urllib2.urlopen( group_url )
+    m = response.read()
+    r = json.loads(m)
+
+    grps = r['results']
+
+    grp_deets = {}
+    for g in grps:
+        grp_deets[ g['id'] ] = g
+    
+    for meetup in meetups:
+        # Group information ...
+        grp = grp_deets[ meetup['group']['id'] ]
+
+        try:
+            group = Group.objects.get(meetupID = grp['id'])
+        except Group.DoesNotExist:
+            group = Group()            
+        
+        try:
+            group.meetupID = grp['id']
+            group.name = grp['name']
+            group.city = grp['city']
+            if 'state' in grp.keys():
+                group.state = grp['state']
+            group.country = grp['country']
+            group.save()
+        except:
+            print('Unable to save Group object: '), sys.exc_info()[0]
+
+        try:
+            event = Event.objects.get(meetupID = meetup['id'])
+        except Event.DoesNotExist:
+            event = Event()
+
+        try:
+            event.name = meetup['name']
+            event.event_url = meetup['event_url']
+            event.meetupID = meetup['id']
+            event.group = group
+            event.save()
+        except:
+            print('Unable to save Event object: '), sys.exc_info()[0]
+
+    template = loader.get_template('events/importMeetups.html')
+    context = RequestContext(request)
+    return HttpResponse(template.render(context))
+    
+

Added: comdev/tools/manage.py
URL: http://svn.apache.org/viewvc/comdev/tools/manage.py?rev=1684019&view=auto
==============================================================================
--- comdev/tools/manage.py (added)
+++ comdev/tools/manage.py Sun Jun  7 10:32:59 2015
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "comdev_tools.settings")
+
+    from django.core.management import execute_from_command_line
+
+    execute_from_command_line(sys.argv)

Added: comdev/tools/readme.md
URL: http://svn.apache.org/viewvc/comdev/tools/readme.md?rev=1684019&view=auto
==============================================================================
--- comdev/tools/readme.md (added)
+++ comdev/tools/readme.md Sun Jun  7 10:32:59 2015
@@ -0,0 +1,123 @@
+This is a Django based web application to assist with community
+development.
+
+# Features #
+
+  * Build and manage lists of events of community interest
+
+# Development #
+
+## Docker Prerequisites ##
+
+If you are using Windows as your client machine then it is a good idea
+to install Git for Windows from http://msysgit.github.io/. This will
+provide both Git and a Bash shell. We will use the Bash shell as a
+convenience since the scripts we have built are Bash scripts.
+
+The application is composed of a number of Docker containers.
+Therefore you will need to install Docker. Docker Macine is also
+useful for creating your Docker Host on whic you will run your version
+of the application.
+
+On Windows open a Bash shell (search for "Unix Bash" after installing Git
+for Windows):
+
+$ curl -L https://get.docker.com/builds/Windows/x86_64/docker-latest.exe > /bin/docker
+$ curl -L https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_windows-amd64.exe > /bin/docker-machine
+
+See the Docker website for instructions on installing Docker and Docker 
+Machine on other platforms see: http://docs.docker.com/machine/
+
+### Docker Hosts ###
+
+As a minimum you will need a Docker host for development. You'll most likely
+want this to be on your local machine. So run the following command (as an 
+administrator):
+
+	$ docker-machine create -d hyper-v comdev
+
+Note the "-d hyper-v" is for Windows machines, you may want to use a
+different provider if you are developing on a different platform.
+
+You'll also need to ensure that your docker client is using this
+machine. Run the following command:
+
+	$ eval "$(docker-machine env comdev)"
+
+#### Share your project code with the Docker Host ####
+
+You need to ensure your project directory is available on the Docker
+Host. On Windows you will need to share it explicitly. We've provided
+a helper script to do this. First, create a confiduration file:
+
+	$ cp scripts/config.tmpl scripts/config.sh
+
+Edit the 'config.sh' file, paying close attention to the section on
+Windows share configuration.
+
+No run:
+
+    $ scripts/configHyper-v.sh
+
+The script will ask you for your Windows password and then configure
+the Docker Host to share the directory you specify in .config.sh'
+
+Once done you will not need to run this script again unless you
+recreate the host.
+
+## Build and Start Your Development Containers ##
+
+As a Docker based application you will work directly with Docker
+containers during development. Your local client development directory
+will be mapped into /project on the container, thus local edits will
+be available in your development container immediately.
+
+The first time you run the container you will need to configure the
+database. Subsequent runs will just require standard Django commands
+to be run.
+
+### First Run ###
+
+As with all Docker containers the first time you build and run them
+the images and corresponding layers need to be downloaded. This can
+take a few minutes. After the first run everything is very quick.
+
+Ensure you are in the project root and then start the postgres
+database container:
+
+	$ docker run -d -v //home/docker/project:/project -p 5432:5432 --name comdev_db postgres
+
+Build the application container:
+
+	$ docker build -t comdev .
+
+Configure the application and the database:
+
+	$ docker run --rm -v //home/docker/project:/project --link comdev_db:db comdev python manage.py makemigrations events_list
+	$ docker run --rm -v //home/docker/project:/project --link comdev_db:db comdev python manage.py migrate
+
+Now, run the application:
+
+	$ docker run --rm -v //home/docker/project:/project --link comdev_db:db -p 80:8000 --name comdev_app comdev python manage.py runserver 0.0.0.0:8000
+
+Now you can visit the app at http://docker.host
+
+### Running Django Commands ###
+
+From this point development is just like any other Django application,
+but to run Django commands in the app container you will need to open
+a terminal on that machine. To do this run:
+
+	$ docker exec -it comdev_app bash
+
+### Using the Admin Interface ###
+
+To access the admin interface of the application you need an admin
+user account. Assuming you are starting from a clean development
+container (i.e. with no data in the database) you will need to create
+an admin user. To do this run the following command in your Django
+terminal.
+
+	$ python manage.py createsuperuser
+
+Now you can log into the admin app at http://docker.host/admin

Added: comdev/tools/requirements.txt
URL: http://svn.apache.org/viewvc/comdev/tools/requirements.txt?rev=1684019&view=auto
==============================================================================
--- comdev/tools/requirements.txt (added)
+++ comdev/tools/requirements.txt Sun Jun  7 10:32:59 2015
@@ -0,0 +1,2 @@
+Django
+psycopg2

Propchange: comdev/tools/scripts/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1 @@
+config.sh

Added: comdev/tools/scripts/.svnignore
URL: http://svn.apache.org/viewvc/comdev/tools/scripts/.svnignore?rev=1684019&view=auto
==============================================================================
--- comdev/tools/scripts/.svnignore (added)
+++ comdev/tools/scripts/.svnignore Sun Jun  7 10:32:59 2015
@@ -0,0 +1 @@
+config.sh
\ No newline at end of file

Added: comdev/tools/scripts/config.tmpl
URL: http://svn.apache.org/viewvc/comdev/tools/scripts/config.tmpl?rev=1684019&view=auto
==============================================================================
--- comdev/tools/scripts/config.tmpl (added)
+++ comdev/tools/scripts/config.tmpl Sun Jun  7 10:32:59 2015
@@ -0,0 +1,10 @@
+# Docker Host names
+DEV_MACHINE_NAME=tutorialDev
+STAGE_MACHINE_NAME=tutorialStage
+PROD_MACHINE_NAME=tutorialProd
+
+# Variables needed to workaround bug in folder sharing
+# on Windows, see configureDevHyper-v.sh
+USER_NAME=< WINDOWS CLIENT USERNAME >
+CLIENT_IP=<WINDOWS CLIENT IP >
+CLIENT_PATH_TO_PROJECT=< WINDOWS CLIENT PATH TO PROJECT FILES, EXCLUDING DRIVE LETTER, E.G. Users/username/path/to/folder >

Added: comdev/tools/scripts/configHyper-v.sh
URL: http://svn.apache.org/viewvc/comdev/tools/scripts/configHyper-v.sh?rev=1684019&view=auto
==============================================================================
--- comdev/tools/scripts/configHyper-v.sh (added)
+++ comdev/tools/scripts/configHyper-v.sh Sun Jun  7 10:32:59 2015
@@ -0,0 +1,17 @@
+# There is currently (5/31/2015) a bug in docker-machine/boot2docker that
+# means shared folders do not work as expected. To work around this
+# bug run the following script (after editing the last line) each time you 
+# provsiion a hyper-v docker-machine.
+
+source scripts/config.sh
+
+read -s -p "What is the password for the user account '$USER_NAME'?" USER_PASSWORD
+
+echo
+echo "Configuring $DEV_MACHINE_NAME"
+
+docker-machine ssh $DEV_MACHINE_NAME wget http://distro.ibiblio.org/tinycorelinux/5.x/x86/tcz/cifs-utils.tcz
+docker-machine ssh $DEV_MACHINE_NAME -- tce-load -i cifs-utils.tcz
+docker-machine ssh $DEV_MACHINE_NAME mkdir project
+echo "Mounting //$CLIENT_IP/$CLIENT_PATH_TO_PROJECT as /home/docker/project"
+docker-machine ssh $DEV_MACHINE_NAME -- "sudo mount -t cifs //$CLIENT_IP/$CLIENT_PATH_TO_PROJECT /home/docker/project -o user=$USER_NAME,password=$USER_PASSWORD"