├── .gitignore
├── LICENSE
├── README.md
├── cbv.sublime-project
├── cbv.sublime-workspace
├── deals.txt
├── src
    ├── .gitignore
    ├── cbv
    │   ├── __init__.py
    │   ├── settings
    │   │   ├── __init__.py
    │   │   ├── base.py
    │   │   ├── local.py
    │   │   └── production.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── dashboard
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── forms.py
    │   ├── migrations
    │   │   ├── 0001_initial.py
    │   │   ├── 0002_auto_20150815_0059.py
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── templates
    │   │   └── dashboard
    │   │   │   ├── book_confirm_delete.html
    │   │   │   ├── book_detail.html
    │   │   │   └── book_list.html
    │   ├── tests.py
    │   └── views.py
    ├── db.sqlite3
    ├── manage.py
    ├── newsletter
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── forms.py
    │   ├── migrations
    │   │   ├── 0001_initial.py
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── requirements.txt
    ├── static_in_pro
    │   └── our_static
    │   │   ├── css
    │   │       ├── bootstrap.min.css
    │   │       ├── custom.css
    │   │       └── navbar-static-top.css
    │   │   ├── img
    │   │       ├── example.txt
    │   │       ├── marketing1.jpg
    │   │       └── mvp_landing_logo.png
    │   │   ├── js
    │   │       ├── bootstrap.min.js
    │   │       └── ie10-viewport-bug-workaround.js
    │   │   └── psd
    │   │       └── mvp_landing_logo.psd
    └── templates
    │   ├── 400.html
    │   ├── 403.html
    │   ├── 404.html
    │   ├── 500.html
    │   ├── about.html
    │   ├── base.html
    │   ├── example_fluid.html
    │   ├── example_text.txt
    │   ├── forms.html
    │   ├── head_css.html
    │   ├── home.html
    │   ├── javascript.html
    │   ├── navbar.html
    │   ├── registration
    │       ├── activate.html
    │       ├── activation_complete.html
    │       ├── activation_email.txt
    │       ├── activation_email_subject.txt
    │       ├── login.html
    │       ├── logout.html
    │       ├── password_change_done.html
    │       ├── password_change_form.html
    │       ├── password_reset_complete.html
    │       ├── password_reset_confirm.html
    │       ├── password_reset_done.html
    │       ├── password_reset_email.html
    │       ├── password_reset_form.html
    │       ├── registration_closed.html
    │       ├── registration_complete.html
    │       └── registration_form.html
    │   └── single_form.html
├── static_in_env
    └── static_root
    │   ├── admin
    │       ├── css
    │       │   ├── base.css
    │       │   ├── changelists.css
    │       │   ├── dashboard.css
    │       │   ├── forms.css
    │       │   ├── ie.css
    │       │   ├── login.css
    │       │   ├── rtl.css
    │       │   └── widgets.css
    │       ├── img
    │       │   ├── changelist-bg.gif
    │       │   ├── changelist-bg_rtl.gif
    │       │   ├── default-bg-reverse.gif
    │       │   ├── default-bg.gif
    │       │   ├── deleted-overlay.gif
    │       │   ├── gis
    │       │   │   ├── move_vertex_off.png
    │       │   │   └── move_vertex_on.png
    │       │   ├── icon-no.gif
    │       │   ├── icon-unknown.gif
    │       │   ├── icon-yes.gif
    │       │   ├── icon_addlink.gif
    │       │   ├── icon_alert.gif
    │       │   ├── icon_calendar.gif
    │       │   ├── icon_changelink.gif
    │       │   ├── icon_clock.gif
    │       │   ├── icon_deletelink.gif
    │       │   ├── icon_error.gif
    │       │   ├── icon_searchbox.png
    │       │   ├── icon_success.gif
    │       │   ├── inline-delete-8bit.png
    │       │   ├── inline-delete.png
    │       │   ├── inline-restore-8bit.png
    │       │   ├── inline-restore.png
    │       │   ├── inline-splitter-bg.gif
    │       │   ├── nav-bg-grabber.gif
    │       │   ├── nav-bg-reverse.gif
    │       │   ├── nav-bg-selected.gif
    │       │   ├── nav-bg.gif
    │       │   ├── selector-icons.gif
    │       │   ├── selector-search.gif
    │       │   ├── sorting-icons.gif
    │       │   ├── tooltag-add.png
    │       │   └── tooltag-arrowright.png
    │       └── js
    │       │   ├── LICENSE-JQUERY.txt
    │       │   ├── SelectBox.js
    │       │   ├── SelectFilter2.js
    │       │   ├── actions.js
    │       │   ├── actions.min.js
    │       │   ├── admin
    │       │       ├── DateTimeShortcuts.js
    │       │       └── RelatedObjectLookups.js
    │       │   ├── calendar.js
    │       │   ├── collapse.js
    │       │   ├── collapse.min.js
    │       │   ├── core.js
    │       │   ├── inlines.js
    │       │   ├── inlines.min.js
    │       │   ├── jquery.init.js
    │       │   ├── jquery.js
    │       │   ├── jquery.min.js
    │       │   ├── prepopulate.js
    │       │   ├── prepopulate.min.js
    │       │   ├── related-widget-wrapper.js
    │       │   ├── timeparse.js
    │       │   └── urlify.js
    │   ├── css
    │       ├── bootstrap.min.css
    │       ├── custom.css
    │       └── navbar-static-top.css
    │   ├── img
    │       ├── example.txt
    │       ├── marketing1.jpg
    │       └── mvp_landing_logo.png
    │   ├── js
    │       ├── bootstrap.min.js
    │       └── ie10-viewport-bug-workaround.js
    │   └── psd
    │       └── mvp_landing_logo.psd
└── webfaction
    └── httpd.conf
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | include/
3 | lib/
4 | .DS_STORE
5 | .Python
6 | *.py[cod]
7 | pip-selfcheck.json
8 | 
9 | 
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2015 Coding For Entrepreneurs
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
23 | 
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | # Class Based Views - Django
 4 | 
 5 | Class Based Views (CBVs) are an important aspect of making Django work better for you. This tutorial series helps you understand how to use class based views in a pre-existing project. 
 6 | 
 7 | The project we use is [Try Django 1.8](https://github.com/codingforentrepreneurs/Try-Django-1.8). Created by Team CFE @ [http://joincfe.com](http://joincfe.com).
 8 | 
 9 | Interested in learning more?
10 | Sign up on our [YouTube channel](http://joincfe.com/youtube)
11 | Become a member on [Coding for Entrepreneurs](http://joincfe.com/enroll)
12 | 
13 | 
14 | The tutorial code below is the final code from the end of each tutorial video. Each link below is tied directly to the tutorial's title. Please note that some videos may not have code reference code.
15 | 
16 | ## Tutorial Code
17 | 
18 | [3 - Intro & TemplateView](../../tree/a3e8ce790930e802c26f1a38c13c57708db8d6f1)
19 | 
20 | [4 - Customize TemplateView](../../tree/5618ab2b0c529a7e5260733837df47de89abaf59)
21 | 
22 | [5 - Base View and Mixins](../../tree/6309dd039e4dec3d2dc169ab15dfc74e247773d3)
23 | 
24 | [6 - Login Required Decorator & Custom Mixin](../../tree/af25e788c51e7e3f0cc4ae253084f6ff111dd312)
25 | 
26 | [7 - DetailView](../../tree/e4f5e42f2a7e9760ccac28e326a0ee1f66593a5e)
27 | 
28 | [8 & 9 ListView & CreateView](../../tree/517f2c6c661f1bbd951f7e9887be36101627fc7d)
29 | 
30 | [10 - UpdateView](../../tree/9e219141a90ae7e4140fccf85061dd65b176b8a0)
31 | 
32 | [12 - DeleteView](../../tree/bbac8e5e62bff743f9d0542e94b3128e7e249bd0)
33 | 
34 | [13 - Django Messages in CBVs](../../tree/8f5c890cfd0e645ab5c70bc9f675ef8a3ad35a01)
35 | 
36 | [14 - Using a FormMixin in a CBV](../../tree/a64a8e925add592bb1b1611c435361b04555b159)
37 | 
--------------------------------------------------------------------------------
/cbv.sublime-project:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"folders":
 3 | 	[
 4 | 		{
 5 | 			"path": "src"
 6 | 		},
 7 | 		{
 8 | 			"path": "static_in_env"
 9 | 		}
10 | 	]
11 | }
12 | 
--------------------------------------------------------------------------------
/deals.txt:
--------------------------------------------------------------------------------
1 | Webfaction Sign-Up Deals (full disclosure: these are affiliate links):
2 | 
3 | 
4 | 2 months for the price of 1 (50% off): http://bit.ly/1hxMgmn
5 | 1 year for the price of 6 months (50% off): http://bit.ly/cfe12
6 | 3 years, 65% off: http://bit.ly/cfe36
--------------------------------------------------------------------------------
/src/.gitignore:
--------------------------------------------------------------------------------
1 | src/settings/db_password.py
2 | 
--------------------------------------------------------------------------------
/src/cbv/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/cbv/__init__.py
--------------------------------------------------------------------------------
/src/cbv/settings/__init__.py:
--------------------------------------------------------------------------------
 1 | from .base import *
 2 | 
 3 | 
 4 | try:
 5 | 	from .local import *
 6 | except:
 7 | 	pass
 8 | 
 9 | 	
10 | try:
11 | 	from .production import *
12 | except:
13 | 	pass
14 | 
15 | 
16 | 
17 | try:
18 | 	from .imac import *
19 | except:
20 | 	pass
21 | 
22 | try:
23 | 	from .macbookpro import *
24 | except:
25 | 	pass
--------------------------------------------------------------------------------
/src/cbv/settings/base.py:
--------------------------------------------------------------------------------
  1 | """
  2 | Django settings for cbv project.
  3 | 
  4 | Generated by 'django-admin startproject' using Django 1.8.
  5 | 
  6 | For more information on this file, see
  7 | https://docs.djangoproject.com/en/1.8/topics/settings/
  8 | 
  9 | For the full list of settings and their values, see
 10 | https://docs.djangoproject.com/en/1.8/ref/settings/
 11 | """
 12 | 
 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 14 | import os
 15 | 
 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 17 | #root of project
 18 | 
 19 | # Quick-start development settings - unsuitable for production
 20 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
 21 | 
 22 | # SECURITY WARNING: keep the secret key used in production secret!
 23 | SECRET_KEY = 'csqwlmc8s55o($rt6ozh7u+ui9zb-et00w$d90j8$^!nvj41_r'
 24 | 
 25 | # SECURITY WARNING: don't run with debug turned on in production!
 26 | DEBUG = False
 27 | 
 28 | ALLOWED_HOSTS = []
 29 | 
 30 | EMAIL_HOST = 'smtp.gmail.com'
 31 | EMAIL_HOST_USER = 'yourgmail@gmail.com'
 32 | EMAIL_HOST_PASSWORD = 'yourpassword'
 33 | EMAIL_PORT = 587
 34 | EMAIL_USE_TLS = True
 35 | 
 36 | ''' 
 37 | If using gmail, you will need to
 38 | unlock Captcha to enable Django 
 39 | to  send for you:
 40 | https://accounts.google.com/displayunlockcaptcha
 41 | '''
 42 | 
 43 | 
 44 | 
 45 | # Application definition
 46 | 
 47 | INSTALLED_APPS = (
 48 |     #django app
 49 |     'django.contrib.admin',
 50 |     'django.contrib.auth',
 51 |     'django.contrib.contenttypes',
 52 |     'django.contrib.sessions',
 53 |     'django.contrib.sites',
 54 |     'django.contrib.messages',
 55 |     'django.contrib.staticfiles',
 56 |     #third party apps
 57 |     'crispy_forms',
 58 |     'registration',
 59 |     #my apps
 60 |     'dashboard',
 61 |     'newsletter',
 62 | )
 63 | 
 64 | MIDDLEWARE_CLASSES = (
 65 |     'django.contrib.sessions.middleware.SessionMiddleware',
 66 |     'django.middleware.common.CommonMiddleware',
 67 |     'django.middleware.csrf.CsrfViewMiddleware',
 68 |     'django.contrib.auth.middleware.AuthenticationMiddleware',
 69 |     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 70 |     'django.contrib.messages.middleware.MessageMiddleware',
 71 |     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 72 |     'django.middleware.security.SecurityMiddleware',
 73 | )
 74 | 
 75 | ROOT_URLCONF = 'cbv.urls'
 76 | 
 77 | TEMPLATES = [
 78 |     {
 79 |         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 80 |         'DIRS': [os.path.join(BASE_DIR, "templates")],
 81 |         'APP_DIRS': True,
 82 |         'OPTIONS': {
 83 |             'context_processors': [
 84 |                 'django.template.context_processors.debug',
 85 |                 'django.template.context_processors.request',
 86 |                 'django.contrib.auth.context_processors.auth',
 87 |                 'django.contrib.messages.context_processors.messages',
 88 |             ],
 89 |         },
 90 |     },
 91 | ]
 92 | 
 93 | WSGI_APPLICATION = 'cbv.wsgi.application'
 94 | 
 95 | 
 96 | # Database
 97 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
 98 | 
 99 | DATABASES = {
100 |     'default': {
101 |         'ENGINE': 'django.db.backends.sqlite3',
102 |         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
103 |     }
104 | }
105 | 
106 | 
107 | # Internationalization
108 | # https://docs.djangoproject.com/en/1.8/topics/i18n/
109 | 
110 | LANGUAGE_CODE = 'en-us'
111 | 
112 | TIME_ZONE = 'UTC'
113 | 
114 | USE_I18N = True
115 | 
116 | USE_L10N = True
117 | 
118 | USE_TZ = True
119 | 
120 | 
121 | # Static files (CSS, JavaScript, Images)
122 | # https://docs.djangoproject.com/en/1.8/howto/static-files/
123 | 
124 | STATIC_URL = '/static/'
125 | 
126 | STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "static_root")
127 |     
128 | STATICFILES_DIRS = (
129 |     os.path.join(BASE_DIR, "static_in_pro", "our_static"),
130 |     #os.path.join(BASE_DIR, "static_in_env"),
131 |     #'/var/www/static/',
132 | )
133 | 
134 | MEDIA_URL = '/media/'
135 | MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")
136 | 
137 | 
138 | 
139 | #Crispy FORM TAGs SETTINGS
140 | CRISPY_TEMPLATE_PACK = 'bootstrap3'
141 | 
142 | 
143 | #DJANGO REGISTRATION REDUX SETTINGS
144 | ACCOUNT_ACTIVATION_DAYS = 7
145 | REGISTRATION_AUTO_LOGIN = True
146 | SITE_ID = 1
147 | LOGIN_REDIRECT_URL = '/'
148 | 
149 | 
150 | 
151 | 
--------------------------------------------------------------------------------
/src/cbv/settings/local.py:
--------------------------------------------------------------------------------
  1 | """
  2 | Django settings for cbv project.
  3 | 
  4 | Generated by 'django-admin startproject' using Django 1.8.
  5 | 
  6 | For more information on this file, see
  7 | https://docs.djangoproject.com/en/1.8/topics/settings/
  8 | 
  9 | For the full list of settings and their values, see
 10 | https://docs.djangoproject.com/en/1.8/ref/settings/
 11 | """
 12 | 
 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 14 | import os
 15 | 
 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 17 | #root of project
 18 | 
 19 | # Quick-start development settings - unsuitable for production
 20 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
 21 | 
 22 | # SECURITY WARNING: keep the secret key used in production secret!
 23 | SECRET_KEY = 'csqwlmc8s55o($rt6ozh7u+ui9zb-et00w$d90j8$^!nvj41_r'
 24 | 
 25 | # SECURITY WARNING: don't run with debug turned on in production!
 26 | DEBUG = True
 27 | 
 28 | ALLOWED_HOSTS = []
 29 | 
 30 | EMAIL_HOST = 'smtp.gmail.com'
 31 | EMAIL_HOST_USER = 'yourgmail@gmail.com'
 32 | EMAIL_HOST_PASSWORD = 'yourpassword'
 33 | EMAIL_PORT = 587
 34 | EMAIL_USE_TLS = True
 35 | 
 36 | ''' 
 37 | If using gmail, you will need to
 38 | unlock Captcha to enable Django 
 39 | to  send for you:
 40 | https://accounts.google.com/displayunlockcaptcha
 41 | '''
 42 | 
 43 | 
 44 | 
 45 | # Application definition
 46 | 
 47 | INSTALLED_APPS = (
 48 |     #django app
 49 |     'django.contrib.admin',
 50 |     'django.contrib.auth',
 51 |     'django.contrib.contenttypes',
 52 |     'django.contrib.sessions',
 53 |     'django.contrib.sites',
 54 |     'django.contrib.messages',
 55 |     'django.contrib.staticfiles',
 56 |     #third party apps
 57 |     'crispy_forms',
 58 |     'registration',
 59 |     #my apps
 60 |     'dashboard',
 61 |     'newsletter',
 62 | )
 63 | 
 64 | MIDDLEWARE_CLASSES = (
 65 |     'django.contrib.sessions.middleware.SessionMiddleware',
 66 |     'django.middleware.common.CommonMiddleware',
 67 |     'django.middleware.csrf.CsrfViewMiddleware',
 68 |     'django.contrib.auth.middleware.AuthenticationMiddleware',
 69 |     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 70 |     'django.contrib.messages.middleware.MessageMiddleware',
 71 |     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 72 |     'django.middleware.security.SecurityMiddleware',
 73 | )
 74 | 
 75 | ROOT_URLCONF = 'cbv.urls'
 76 | 
 77 | TEMPLATES = [
 78 |     {
 79 |         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 80 |         'DIRS': [os.path.join(BASE_DIR, "templates")],
 81 |         'APP_DIRS': True,
 82 |         'OPTIONS': {
 83 |             'context_processors': [
 84 |                 'django.template.context_processors.debug',
 85 |                 'django.template.context_processors.request',
 86 |                 'django.contrib.auth.context_processors.auth',
 87 |                 'django.contrib.messages.context_processors.messages',
 88 |             ],
 89 |         },
 90 |     },
 91 | ]
 92 | 
 93 | WSGI_APPLICATION = 'cbv.wsgi.application'
 94 | 
 95 | 
 96 | # Database
 97 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
 98 | 
 99 | DATABASES = {
100 |     'default': {
101 |         'ENGINE': 'django.db.backends.sqlite3',
102 |         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
103 |     }
104 | }
105 | 
106 | 
107 | # Internationalization
108 | # https://docs.djangoproject.com/en/1.8/topics/i18n/
109 | 
110 | LANGUAGE_CODE = 'en-us'
111 | 
112 | TIME_ZONE = 'UTC'
113 | 
114 | USE_I18N = True
115 | 
116 | USE_L10N = True
117 | 
118 | USE_TZ = True
119 | 
120 | 
121 | # Static files (CSS, JavaScript, Images)
122 | # https://docs.djangoproject.com/en/1.8/howto/static-files/
123 | 
124 | STATIC_URL = '/static/'
125 | 
126 | STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "static_root")
127 |     
128 | STATICFILES_DIRS = (
129 |     os.path.join(BASE_DIR, "static_in_pro", "our_static"),
130 |     #os.path.join(BASE_DIR, "static_in_env"),
131 |     #'/var/www/static/',
132 | )
133 | 
134 | MEDIA_URL = '/media/'
135 | MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")
136 | 
137 | 
138 | 
139 | #Crispy FORM TAGs SETTINGS
140 | CRISPY_TEMPLATE_PACK = 'bootstrap3'
141 | 
142 | 
143 | #DJANGO REGISTRATION REDUX SETTINGS
144 | ACCOUNT_ACTIVATION_DAYS = 7
145 | REGISTRATION_AUTO_LOGIN = True
146 | SITE_ID = 1
147 | LOGIN_REDIRECT_URL = '/'
148 | 
149 | 
150 | 
151 | 
--------------------------------------------------------------------------------
/src/cbv/settings/production.py:
--------------------------------------------------------------------------------
  1 | 
  2 | #static is here mvpland_static
  3 | #postgresql -- mvpland
  4 | #username -- cfedeploy
  5 | #password -- ##
  6 | 
  7 | 
  8 | """
  9 | Django settings for cbv project.
 10 | 
 11 | Generated by 'django-admin startproject' using Django 1.8.
 12 | 
 13 | For more information on this file, see
 14 | https://docs.djangoproject.com/en/1.8/topics/settings/
 15 | 
 16 | For the full list of settings and their values, see
 17 | https://docs.djangoproject.com/en/1.8/ref/settings/
 18 | """
 19 | 
 20 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 21 | 
 22 | from django.conf import settings
 23 | 
 24 | if not settings.DEBUG:
 25 | 	import os
 26 | 
 27 | 	BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 28 | 	#root of project
 29 | 
 30 | 	# Quick-start development settings - unsuitable for production
 31 | 	# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
 32 | 
 33 | 	# SECURITY WARNING: keep the secret key used in production secret!
 34 | 	SECRET_KEY = 'csqwlmc8s55o($rt6ozh7u+ui9zb-et00w$d90j8$^!nvj41_r'
 35 | 
 36 | 	# SECURITY WARNING: don't run with debug turned on in production!
 37 | 	DEBUG = False
 38 | 
 39 | 	ADMINS = (
 40 | 		("Justin", "codingforentrepreneurs@gmail.com"),
 41 | 
 42 | 		)
 43 | 
 44 | 	ALLOWED_HOSTS = ['cfedeploy.webfactional.com', 'trydjango.com', 'www.trydjango.com']
 45 | 	#purchasing domain name http://name.com
 46 | 
 47 | 	EMAIL_HOST = 'smtp.gmail.com'
 48 | 	EMAIL_HOST_USER = 'yourgmail@gmail.com'
 49 | 	EMAIL_HOST_PASSWORD = 'yourpassword'
 50 | 	EMAIL_PORT = 587
 51 | 	EMAIL_USE_TLS = True
 52 | 
 53 | 	''' 
 54 | 	If using gmail, you will need to
 55 | 	unlock Captcha to enable Django 
 56 | 	to  send for you:
 57 | 	https://accounts.google.com/displayunlockcaptcha
 58 | 	'''
 59 | 
 60 | 
 61 | 
 62 | 	# Application definition
 63 | 
 64 | 	INSTALLED_APPS = (
 65 | 	    #django app
 66 | 	    'django.contrib.admin',
 67 | 	    'django.contrib.auth',
 68 | 	    'django.contrib.contenttypes',
 69 | 	    'django.contrib.sessions',
 70 | 	    'django.contrib.sites',
 71 | 	    'django.contrib.messages',
 72 | 	    'django.contrib.staticfiles',
 73 | 	    #third party apps
 74 | 	    'crispy_forms',
 75 | 	    'registration',
 76 | 	    #my apps
 77 | 	    'newsletter',
 78 | 	)
 79 | 
 80 | 	MIDDLEWARE_CLASSES = (
 81 | 	    'django.contrib.sessions.middleware.SessionMiddleware',
 82 | 	    'django.middleware.common.CommonMiddleware',
 83 | 	    'django.middleware.csrf.CsrfViewMiddleware',
 84 | 	    'django.contrib.auth.middleware.AuthenticationMiddleware',
 85 | 	    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 86 | 	    'django.contrib.messages.middleware.MessageMiddleware',
 87 | 	    'django.middleware.clickjacking.XFrameOptionsMiddleware',
 88 | 	    'django.middleware.security.SecurityMiddleware',
 89 | 	)
 90 | 
 91 | 	ROOT_URLCONF = 'cbv.urls'
 92 | 
 93 | 	TEMPLATES = [
 94 | 	    {
 95 | 	        'BACKEND': 'django.template.backends.django.DjangoTemplates',
 96 | 	        'DIRS': [os.path.join(BASE_DIR, "templates")],
 97 | 	        'APP_DIRS': True,
 98 | 	        'OPTIONS': {
 99 | 	            'context_processors': [
100 | 	                'django.template.context_processors.debug',
101 | 	                'django.template.context_processors.request',
102 | 	                'django.contrib.auth.context_processors.auth',
103 | 	                'django.contrib.messages.context_processors.messages',
104 | 	            ],
105 | 	        },
106 | 	    },
107 | 	]
108 | 
109 | 	WSGI_APPLICATION = 'cbv.wsgi.application'
110 | 
111 | 
112 | 	# Database
113 | 	# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
114 | 
115 | 	from .db_password import DBPASS
116 | 
117 | 	DATABASES = {
118 | 	    'default': {
119 | 	        'ENGINE': 'django.db.backends.postgresql_psycopg2',
120 | 	        'NAME': "mvpland",
121 | 	        'USER': "cfedeploy",
122 | 	        'PASSWORD': DBPASS,
123 | 	    }
124 | 	}
125 | 
126 | 
127 | 	# Internationalization
128 | 	# https://docs.djangoproject.com/en/1.8/topics/i18n/
129 | 
130 | 	LANGUAGE_CODE = 'en-us'
131 | 
132 | 	TIME_ZONE = 'UTC'
133 | 
134 | 	USE_I18N = True
135 | 
136 | 	USE_L10N = True
137 | 
138 | 	USE_TZ = True
139 | 
140 | 
141 | 	# Static files (CSS, JavaScript, Images)
142 | 	# https://docs.djangoproject.com/en/1.8/howto/static-files/
143 | 
144 | 	STATIC_URL = '/static/'
145 | 
146 | 	STATIC_ROOT = '/home/cfedeploy/webapps/mvpland_static/'
147 | 	#os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "static_root")
148 | 	    
149 | 	STATICFILES_DIRS = (
150 | 	    os.path.join(BASE_DIR, "static_in_pro", "our_static"),
151 | 	    #os.path.join(BASE_DIR, "static_in_env"),
152 | 	    #'/var/www/static/',
153 | 	)
154 | 
155 | 	MEDIA_URL = '/media/'
156 | 	MEDIA_ROOT = '/home/cfedeploy/webapps/mvpland_media/'
157 | 	#os.path.join(os.path.dirname(BASE_DIR), "static_in_env", "media_root")
158 | 
159 | 
160 | 	#Crispy FORM TAGs SETTINGS
161 | 	CRISPY_TEMPLATE_PACK = 'bootstrap3'
162 | 
163 | 
164 | 	#DJANGO REGISTRATION REDUX SETTINGS
165 | 	ACCOUNT_ACTIVATION_DAYS = 7
166 | 	REGISTRATION_AUTO_LOGIN = True
167 | 	SITE_ID = 1
168 | 	LOGIN_REDIRECT_URL = '/'
169 | 
170 | 
171 | 
172 | 
173 | 
174 | 
--------------------------------------------------------------------------------
/src/cbv/urls.py:
--------------------------------------------------------------------------------
 1 | from django.conf import settings
 2 | from django.conf.urls import include, url
 3 | from django.conf.urls.static import static
 4 | from django.contrib import admin
 5 | 
 6 | from django.views.generic.base import TemplateView
 7 | 
 8 | from dashboard.views import DashboardTemplateView, MyView,\
 9 | 							 BookDetail, BookListView, BookCreateView,\
10 | 							 BookUpdateView, BookDeleteView
11 | 
12 | urlpatterns = [
13 |     # Examples:
14 |     url(r'^$', 'newsletter.views.home', name='home'),
15 |     url(r'^contact/$', 'newsletter.views.contact', name='contact'),
16 |     #url(r'^about/$', 'cbv.views.about', name='about'),
17 |     url(r'^book/create/$', BookCreateView.as_view(), name='book_create'),
18 |     url(r'^book/$', BookListView.as_view(), name='book_list'),
19 |     url(r'^book/(?P[-\w]+)/$', BookDetail.as_view(), name='book_detail'),
20 |     url(r'^book/(?P[-\w]+)/delete/$', BookDeleteView.as_view(), name='book_delete'),
21 |     url(r'^book/(?P[-\w]+)/update/$', BookUpdateView.as_view(), name='book_update'),
22 |     url(r'^someview/$', MyView.as_view(template_name='about.html'), name='someview'),
23 |     url(r'^about/$', DashboardTemplateView.as_view(), name='about'),
24 |     url(r'^team/$', DashboardTemplateView.as_view(template_name='team.html'), name='team'),
25 |     # url(r'^blog/', include('blog.urls')),
26 | 
27 |     url(r'^admin/', include(admin.site.urls)),
28 |     url(r'^accounts/', include('registration.backends.default.urls')),
29 | ]
30 | 
31 | if settings.DEBUG:
32 | 	urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
33 | 	urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
--------------------------------------------------------------------------------
/src/cbv/wsgi.py:
--------------------------------------------------------------------------------
 1 | """
 2 | WSGI config for cbv project.
 3 | 
 4 | It exposes the WSGI callable as a module-level variable named ``application``.
 5 | 
 6 | For more information on this file, see
 7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
 8 | """
 9 | 
10 | import os
11 | 
12 | from django.core.wsgi import get_wsgi_application
13 | 
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cbv.settings")
15 | 
16 | application = get_wsgi_application()
17 | 
--------------------------------------------------------------------------------
/src/dashboard/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/dashboard/__init__.py
--------------------------------------------------------------------------------
/src/dashboard/admin.py:
--------------------------------------------------------------------------------
 1 | from django.contrib import admin
 2 | 
 3 | # Register your models here.
 4 | from .forms import BookForm
 5 | from .models import Book
 6 | 
 7 | class BookAdmin(admin.ModelAdmin):
 8 | 	list_display = [
 9 | 				"__unicode__",
10 | 				"slug",	
11 | 				]
12 | 	readonly_fields = ['slug', 'updated', 'timestamp', 'added_by', "last_edited_by"]
13 | 	
14 | 	form = BookForm
15 | 
16 | admin.site.register(Book, BookAdmin)
--------------------------------------------------------------------------------
/src/dashboard/forms.py:
--------------------------------------------------------------------------------
 1 | from django import forms
 2 | from django.utils.text import slugify
 3 | 
 4 | from .models import Book
 5 | 
 6 | 
 7 | class BookForm(forms.ModelForm):
 8 | 	class Meta:
 9 | 		model = Book
10 | 		fields = [
11 | 			'title',
12 | 			'description',
13 | 		]
14 | 
15 | 	def clean_title(self):
16 | 		title = self.cleaned_data["title"]
17 | 		slug = slugify(title)
18 | 		try:
19 | 			book = Book.objects.get(slug=slug)
20 | 			raise forms.ValidationError("Title Already Exists. Please try a different one.")
21 | 		except Book.DoesNotExist:
22 | 			return title
23 | 		except:
24 | 			raise forms.ValidationError("Title Already Exists. Please try a different one.")
25 | 
--------------------------------------------------------------------------------
/src/dashboard/migrations/0001_initial.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | from __future__ import unicode_literals
 3 | 
 4 | from django.db import models, migrations
 5 | from django.conf import settings
 6 | 
 7 | 
 8 | class Migration(migrations.Migration):
 9 | 
10 |     dependencies = [
11 |         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.CreateModel(
16 |             name='Book',
17 |             fields=[
18 |                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
19 |                 ('title', models.CharField(max_length=120)),
20 |                 ('description', models.TextField(null=True, blank=True)),
21 |                 ('slug', models.SlugField()),
22 |                 ('updated', models.DateTimeField(auto_now=True)),
23 |                 ('timestamp', models.DateTimeField(auto_now_add=True)),
24 |                 ('added_by', models.ForeignKey(related_name='book_add', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
25 |                 ('last_edited_by', models.ForeignKey(related_name='book_edit', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
26 |             ],
27 |         ),
28 |     ]
29 | 
--------------------------------------------------------------------------------
/src/dashboard/migrations/0002_auto_20150815_0059.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | from __future__ import unicode_literals
 3 | 
 4 | from django.db import models, migrations
 5 | 
 6 | 
 7 | class Migration(migrations.Migration):
 8 | 
 9 |     dependencies = [
10 |         ('dashboard', '0001_initial'),
11 |     ]
12 | 
13 |     operations = [
14 |         migrations.AlterModelOptions(
15 |             name='book',
16 |             options={'ordering': ['-timestamp', '-updated']},
17 |         ),
18 |         migrations.AlterField(
19 |             model_name='book',
20 |             name='slug',
21 |             field=models.SlugField(unique=True),
22 |         ),
23 |     ]
24 | 
--------------------------------------------------------------------------------
/src/dashboard/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/dashboard/migrations/__init__.py
--------------------------------------------------------------------------------
/src/dashboard/models.py:
--------------------------------------------------------------------------------
 1 | from django.conf import settings
 2 | from django.core.urlresolvers import reverse
 3 | from django.db import models
 4 | 
 5 | from django.db.models.signals import pre_save, post_save
 6 | from django.utils.text import slugify
 7 | 
 8 | # Create your models here.
 9 | 
10 | 
11 | 
12 | class Book(models.Model):
13 | 	added_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='book_add')
14 | 	last_edited_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,  related_name='book_edit')
15 | 	title = models.CharField(max_length=120)
16 | 	description = models.TextField(null=True, blank=True)
17 | 	slug = models.SlugField(unique=True)
18 | 	updated = models.DateTimeField(auto_now_add=False, auto_now=True)
19 | 	timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
20 | 
21 | 	class Meta:
22 | 		ordering = ["-timestamp", "-updated"]
23 | 		#unique_together = ("title", "slug")
24 | 
25 | 	def __unicode__(self):
26 | 		return self.title
27 | 
28 | 	def get_absolute_url(self):
29 | 		#url(r'^book/(?P\d+)$', BookDetail.as_view(), name='book_detail'),
30 | 		#return reverse("book_detail", kwargs={"id": self.id})
31 | 		return reverse("book_detail", kwargs={"slug": self.slug})
32 | 
33 | 
34 | 
35 | def pre_save_book(sender, instance, *args, **kwargs):
36 | 	slug = slugify(instance.title)
37 | 	instance.slug = slug
38 | 
39 | 
40 | pre_save.connect(pre_save_book, sender=Book)
--------------------------------------------------------------------------------
/src/dashboard/templates/dashboard/book_confirm_delete.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | 
 3 | 
 4 | 
 5 | {% block content %}
 6 | 
 7 | 
 8 | 
13 | 
14 | 
15 | 
16 | {% endblock %}
--------------------------------------------------------------------------------
/src/dashboard/templates/dashboard/book_detail.html:
--------------------------------------------------------------------------------
 1 | {% extends 'base.html' %}
 2 | 
 3 | 
 4 | 
 5 | {% block content %}
 6 | 
 7 | 
 8 | {{ object.title }} 
 9 | {{ object.description }}
10 | 
11 | 
12 | {% include "single_form.html" with form=form btn_title=btn_title %}
13 | 
14 | {% endblock %}
--------------------------------------------------------------------------------
/src/dashboard/templates/dashboard/book_list.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | 
 3 | 
 4 | 
 5 | {% block content %}
 6 | 
 7 | 
 8 | {% for object in object_list %}
 9 | {{ object }} 
12 | 
13 | 
14 | {% endblock %}
--------------------------------------------------------------------------------
/src/dashboard/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | 
3 | # Create your tests here.
4 | 
--------------------------------------------------------------------------------
/src/dashboard/views.py:
--------------------------------------------------------------------------------
  1 | from django.contrib import messages
  2 | from django.contrib.messages.views import SuccessMessageMixin
  3 | from django.contrib.auth.decorators import login_required
  4 | from django.core.urlresolvers import reverse
  5 | from django.http import HttpResponse, Http404
  6 | from django.views.generic import View
  7 | from django.views.generic.base import TemplateView, TemplateResponseMixin, ContextMixin
  8 | from django.views.generic.detail import DetailView
  9 | from django.views.generic.list import ListView
 10 | from django.views.generic.edit import CreateView, UpdateView, DeleteView, ModelFormMixin
 11 | from django.shortcuts import render
 12 | from django.utils.decorators import method_decorator
 13 | 
 14 | 
 15 | from .forms import BookForm
 16 | from .models import Book
 17 | 
 18 | 
 19 | #CREATE
 20 | 
 21 | #RETREIVE
 22 | 
 23 | #UPDATE
 24 | 
 25 | #DELETE
 26 | 
 27 | 
 28 | 
 29 | 
 30 | 
 31 | # def book_detail(request, slug):
 32 | # 	book = Book.objects.get(slug=slug)
 33 | # 	return render()
 34 | 
 35 | 
 36 | class MultipleObjectMixin(object):
 37 | 	def get_object(self, queryset=None, *args, **kwargs):
 38 | 		slug = self.kwargs.get("slug")
 39 | 		if slug:
 40 | 			try:
 41 | 				obj = self.model.objects.get(slug=slug)
 42 | 			except self.model.MultipleObjectsReturned:
 43 | 				obj = self.get_queryset().first()
 44 | 			except:
 45 | 				raise Http404
 46 | 			return obj
 47 | 		raise Http404
 48 | 
 49 | 
 50 | class BookDeleteView(DeleteView):
 51 | 	model = Book
 52 | 
 53 | 	def get_success_url(self):
 54 | 		return reverse("book_list")
 55 | 
 56 | 
 57 | 
 58 | class BookCreateView(SuccessMessageMixin, CreateView):
 59 | 	template_name = "forms.html"
 60 | 	form_class = BookForm
 61 | 	success_message = "%(title)s has been created at %(created_at)s"
 62 | 	#success_url = "/"
 63 | 	def form_valid(self, form):
 64 | 		form.instance.added_by = self.request.user
 65 | 		#form.instance.last_edited_by = self.request.user
 66 | 		valid_form = super(BookCreateView, self).form_valid(form)
 67 | 		#messages.success(self.request, "Book created!")
 68 | 		# send signals
 69 | 		return valid_form
 70 | 
 71 | 	def get_success_url(self):
 72 | 		return reverse("book_list")
 73 | 
 74 | 	def get_success_message(self, cleaned_data):
 75 | 		return self.success_message % dict(
 76 | 			cleaned_data,
 77 | 			created_at=self.object.timestamp,
 78 | 		)
 79 | 
 80 | 
 81 | class BookUpdateView(MultipleObjectMixin, UpdateView):
 82 | 	model = Book
 83 | 	#fields = ["title", "description"]
 84 | 	form_class = BookForm
 85 | 	template_name = "forms.html"
 86 | 
 87 | 
 88 | class BookDetail(SuccessMessageMixin, ModelFormMixin, MultipleObjectMixin, DetailView):
 89 | 	model = Book
 90 | 	form_class = BookForm
 91 | 	success_message = "%(title)s has been updated."
 92 | 
 93 | 	def get_context_data(self, *args, **kwargs):
 94 | 		context = super(BookDetail, self).get_context_data(*args, **kwargs)
 95 | 		context["form"] = self.get_form()
 96 | 		context["btn_title"] = "Update Book"
 97 | 		return context
 98 | 
 99 | 	def post(self, request, *args, **kwargs):
100 | 		if request.user.is_authenticated():
101 | 			self.object = self.get_object()
102 | 			form = self.get_form()
103 | 			if form.is_valid():
104 | 				return self.form_valid(form)
105 | 			else:
106 | 				return self.form_invalid(form)
107 | 
108 | 	def get_success_url(self):
109 | 		return reverse("book_list")
110 | 
111 | 
112 | 	# def dispatch(self, request, *args, **kwargs):
113 | 	# 	messages.success(self.request, "Book viewed!")
114 | 	# 	return super(BookDetail, self).dispatch(request, *args, **kwargs)
115 | 
116 | 
117 | class BookListView(ListView):
118 | 	model = Book
119 | 	# def get_queryset(self, *args, **kwargs):
120 | 	# 	qs = super(BookListView, self).get_queryset(*args, **kwargs)
121 | 	# 	return qs
122 | 
123 | 
124 | 
125 | 
126 | class LoginRequiredMixin(object):
127 | 	# @classmethod
128 | 	# def as_view(cls, **kwargs):
129 | 	# 	view = super(LoginRequiredMixin, cls).as_view(**kwargs)
130 | 	# 	return login_required(view)
131 | 
132 | 	@method_decorator(login_required)
133 | 	def dispatch(self, request, *args, **kwargs):
134 | 		return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
135 | 
136 | 
137 | class DashboardTemplateView(TemplateView):
138 | 	template_name = "about.html"
139 | 
140 | 	def get_context_data(self, *args, **kwargs):
141 | 		context = super(DashboardTemplateView, self).get_context_data(*args, **kwargs)
142 | 		context["title"] = "This is about us"
143 | 		return context
144 | 
145 | 
146 | 
147 | class MyView(ContextMixin, TemplateResponseMixin, LoginRequiredMixin, View):
148 | 	def get(self, request, *args, **kwargs):
149 | 		context = self.get_context_data(**kwargs)
150 | 		context["title"] = "Some other title"
151 | 		return self.render_to_response(context)
152 | 
153 | 	# @method_decorator(login_required)
154 | 	# def dispatch(self, request, *args, **kwargs):
155 | 	# 	return super(MyView, self).dispatch(request, *args, **kwargs)
--------------------------------------------------------------------------------
/src/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/db.sqlite3
--------------------------------------------------------------------------------
/src/manage.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python
 2 | import os
 3 | import sys
 4 | 
 5 | if __name__ == "__main__":
 6 |     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cbv.settings")
 7 | 
 8 |     from django.core.management import execute_from_command_line
 9 | 
10 |     execute_from_command_line(sys.argv)
11 | 
--------------------------------------------------------------------------------
/src/newsletter/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/newsletter/__init__.py
--------------------------------------------------------------------------------
/src/newsletter/admin.py:
--------------------------------------------------------------------------------
 1 | from django.contrib import admin
 2 | 
 3 | # Register your models here.
 4 | 
 5 | from .forms import SignUpForm
 6 | from .models import SignUp
 7 | 
 8 | class SignUpAdmin(admin.ModelAdmin):
 9 | 	list_display = ["__unicode__", "timestamp", "updated"]
10 | 	form = SignUpForm
11 | 	# class Meta:
12 | 	# 	model = SignUp
13 | 
14 | 
15 | 
16 | admin.site.register(SignUp, SignUpAdmin)
--------------------------------------------------------------------------------
/src/newsletter/forms.py:
--------------------------------------------------------------------------------
 1 | from django import forms
 2 | 
 3 | from .models import SignUp
 4 | 
 5 | class ContactForm(forms.Form):
 6 | 	full_name = forms.CharField(required=False)
 7 | 	email = forms.EmailField()
 8 | 	message = forms.CharField()
 9 | 
10 | 
11 | class SignUpForm(forms.ModelForm):
12 | 	class Meta:
13 | 		model = SignUp
14 | 		fields = ['full_name', 'email']
15 | 		### exclude = ['full_name']
16 | 	
17 | 	def clean_email(self):
18 | 		email = self.cleaned_data.get('email')
19 | 		email_base, provider = email.split("@")
20 | 		domain, extension = provider.split('.')
21 | 		# if not domain == 'USC':
22 | 		# 	raise forms.ValidationError("Please make sure you use your USC email.")
23 | 		if not extension == "edu":
24 | 			raise forms.ValidationError("Please use a valid .EDU email address")
25 | 		return email
26 | 
27 | 	def clean_full_name(self):
28 | 		full_name = self.cleaned_data.get('full_name')
29 | 		#write validation code.
30 | 		return full_name
--------------------------------------------------------------------------------
/src/newsletter/migrations/0001_initial.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | from __future__ import unicode_literals
 3 | 
 4 | from django.db import models, migrations
 5 | 
 6 | 
 7 | class Migration(migrations.Migration):
 8 | 
 9 |     dependencies = [
10 |     ]
11 | 
12 |     operations = [
13 |         migrations.CreateModel(
14 |             name='SignUp',
15 |             fields=[
16 |                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
17 |                 ('email', models.EmailField(max_length=254)),
18 |                 ('full_name', models.CharField(max_length=120, null=True, blank=True)),
19 |                 ('timestamp', models.DateTimeField(auto_now_add=True)),
20 |                 ('updated', models.DateTimeField(auto_now=True)),
21 |             ],
22 |         ),
23 |     ]
24 | 
--------------------------------------------------------------------------------
/src/newsletter/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/newsletter/migrations/__init__.py
--------------------------------------------------------------------------------
/src/newsletter/models.py:
--------------------------------------------------------------------------------
 1 | from django.db import models
 2 | 
 3 | # Create your models here.
 4 | class SignUp(models.Model):
 5 | 	email = models.EmailField()
 6 | 	full_name = models.CharField(max_length=120, blank=True, null=True)
 7 | 	timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
 8 | 	updated = models.DateTimeField(auto_now_add=False, auto_now=True)
 9 | 
10 | 	def __unicode__(self): #Python 3.3 is __str__
11 | 		return self.email
--------------------------------------------------------------------------------
/src/newsletter/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | 
3 | # Create your tests here.
4 | 
--------------------------------------------------------------------------------
/src/newsletter/views.py:
--------------------------------------------------------------------------------
  1 | from django.conf import settings
  2 | from django.contrib.auth.decorators import login_required
  3 | from django.core.mail import send_mail
  4 | 
  5 | from django.shortcuts import render
  6 | 
  7 | from .forms import ContactForm, SignUpForm
  8 | from .models import SignUp
  9 | 
 10 | # Create your views here.
 11 | def home(request):
 12 | 	title = 'Sign Up Now'
 13 | 	form = SignUpForm(request.POST or None)
 14 | 	context = {
 15 | 		"title": title,
 16 | 		"form": form
 17 | 	}
 18 | 	if form.is_valid():
 19 | 		#form.save()
 20 | 		#print request.POST['email'] #not recommended
 21 | 		instance = form.save(commit=False)
 22 | 
 23 | 		full_name = form.cleaned_data.get("full_name")
 24 | 		if not full_name:
 25 | 			full_name = "New full name"
 26 | 		instance.full_name = full_name
 27 | 		# if not instance.full_name:
 28 | 		# 	instance.full_name = "Justin"
 29 | 		instance.save()
 30 | 		context = {
 31 | 			"title": "Thank you"
 32 | 		}
 33 | 
 34 | 	if request.user.is_authenticated() and request.user.is_staff:
 35 | 		#print(SignUp.objects.all())
 36 | 		# i = 1
 37 | 		# for instance in SignUp.objects.all():
 38 | 		# 	print(i)
 39 | 		# 	print(instance.full_name)
 40 | 		# 	i += 1
 41 | 
 42 | 		queryset = SignUp.objects.all().order_by('-timestamp') #.filter(full_name__iexact="Justin")
 43 | 		#print(SignUp.objects.all().order_by('-timestamp').filter(full_name__iexact="Justin").count())
 44 | 		context = {
 45 | 			"queryset": queryset
 46 | 		}
 47 | 
 48 | 	return render(request, "home.html", context)
 49 | 
 50 | 
 51 | @login_required
 52 | def contact(request):
 53 | 	title = 'Contact Us'
 54 | 	title_align_center = True
 55 | 	form = ContactForm(request.POST or None)
 56 | 	if form.is_valid():
 57 | 		# for key, value in form.cleaned_data.iteritems():
 58 | 		# 	print key, value
 59 | 		# 	#print form.cleaned_data.get(key)
 60 | 		form_email = form.cleaned_data.get("email")
 61 | 		form_message = form.cleaned_data.get("message")
 62 | 		form_full_name = form.cleaned_data.get("full_name")
 63 | 		# print email, message, full_name
 64 | 		subject = 'Site contact form'
 65 | 		from_email = settings.EMAIL_HOST_USER
 66 | 		to_email = [from_email, 'youotheremail@email.com']
 67 | 		contact_message = "%s: %s via %s"%( 
 68 | 				form_full_name, 
 69 | 				form_message, 
 70 | 				form_email)
 71 | 		some_html_message = """
 72 | 		hello 
 73 | 		"""
 74 | 		send_mail(subject, 
 75 | 				contact_message, 
 76 | 				from_email, 
 77 | 				to_email, 
 78 | 				html_message=some_html_message,
 79 | 				fail_silently=True)
 80 | 
 81 | 	context = {
 82 | 		"form": form,
 83 | 		"title": title,
 84 | 		"title_align_center": title_align_center,
 85 | 	}
 86 | 	return render(request, "forms.html", context)
 87 | 
 88 | 
 89 | 
 90 | 
 91 | 
 92 | 
 93 | 
 94 | 
 95 | 
 96 | 
 97 | 
 98 | 
 99 | 
100 | 
101 | 
102 | 
103 | 
--------------------------------------------------------------------------------
/src/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==1.8.3
2 | django-crispy-forms==1.4.0
3 | django-registration-redux==1.2
4 | wheel==0.24.0
5 | 
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/css/custom.css:
--------------------------------------------------------------------------------
1 | .text-align-center {
2 | 	text-align: center;
3 | }
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/css/navbar-static-top.css:
--------------------------------------------------------------------------------
 1 | body {
 2 |   min-height: 1000px;
 3 | }
 4 | 
 5 | .navbar-static-top {
 6 |   margin-bottom: 19px;
 7 |   background-color: #4E4E4E;
 8 |   border-color: #444444;
 9 | }
10 | 
11 | .navbar-default .navbar-brand {
12 |   color: #FFF;
13 | }
14 | 
15 | .navbar-default .navbar-brand:hover {
16 |   color: #777;
17 | }
18 | 
19 | .navbar-default .navbar-nav>li>a:hover {
20 |   color: #999;
21 | }
22 | 
23 | .navbar-default .navbar-toggle {
24 |  border-color: transparent !important;
25 | }
26 | 
27 | .navbar-toggle:hover {
28 | 	background-color: #444444 !important;
29 | }
30 | 
31 | .navbar-toggle {
32 | 	background-color: #444444 !important;
33 | }
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/img/example.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/static_in_pro/our_static/img/example.txt
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/img/marketing1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/static_in_pro/our_static/img/marketing1.jpg
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/img/mvp_landing_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/static_in_pro/our_static/img/mvp_landing_logo.png
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/js/ie10-viewport-bug-workaround.js:
--------------------------------------------------------------------------------
 1 | /*!
 2 |  * IE10 viewport hack for Surface/desktop Windows 8 bug
 3 |  * Copyright 2014 Twitter, Inc.
 4 |  * Licensed under the Creative Commons Attribution 3.0 Unported License. For
 5 |  * details, see http://creativecommons.org/licenses/by/3.0/.
 6 |  */
 7 | 
 8 | // See the Getting Started docs for more information:
 9 | // http://getbootstrap.com/getting-started/#support-ie10-width
10 | 
11 | (function () {
12 |   'use strict';
13 |   if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
14 |     var msViewportStyle = document.createElement('style')
15 |     msViewportStyle.appendChild(
16 |       document.createTextNode(
17 |         '@-ms-viewport{width:auto!important}'
18 |       )
19 |     )
20 |     document.querySelector('head').appendChild(msViewportStyle)
21 |   }
22 | })();
23 | 
--------------------------------------------------------------------------------
/src/static_in_pro/our_static/psd/mvp_landing_logo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/src/static_in_pro/our_static/psd/mvp_landing_logo.psd
--------------------------------------------------------------------------------
/src/templates/400.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | 
3 | 
4 | {% block content %}
5 | 
6 | 400 Error Occurred. Bad request, please try again. 
7 | 
8 | {% endblock %}
--------------------------------------------------------------------------------
/src/templates/403.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | 
3 | 
4 | {% block content %}
5 | 
6 | 403 Error Occurred. Permission Denied 
7 | 
8 | {% endblock %}
--------------------------------------------------------------------------------
/src/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | 
3 | 
4 | {% block content %}
5 | 
6 | 404 Error Occurred. Page Not Found 
7 | 
8 | {% endblock %}
--------------------------------------------------------------------------------
/src/templates/500.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | 
3 | 
4 | {% block content %}
5 | 
6 | 500 Error Occurred. Server error, we have been alerted, please try again later. 
7 | 
8 | {% endblock %}
--------------------------------------------------------------------------------
/src/templates/about.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | 
 3 | 
 4 | 
 5 | {% block content %}
 6 | 
 7 | 
 8 | 
 9 | 
{% if title %}{{ title|upper }}{% endif %} 
10 | 
This is about us. This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.
11 | 
This is about us. This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.
12 | 
This is about us. This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.This is about us.
13 | 
14 | 
15 | 
{% block head_title %}MVP Landing{% endblock %} 
15 | 
16 |     {% include 'head_css.html' %}
17 | 
18 |       
21 | 
22 | 
23 | 
24 |   
25 | 
26 |   
27 |   {% include 'navbar.html' %}
28 | 
29 | {% if messages %}
30 | 
31 | 
32 | 
33 | × Close 
38 | 
39 | 
47 |             
48 | 
49 |           
50 |             {% block content %}
51 | 
52 |             {% endblock %}
53 |               
54 | 
55 |     
 
56 | 
57 |     {% include "javascript.html" %}
58 |     
59 |     
60 |   
61 | 
--------------------------------------------------------------------------------
/src/templates/example_fluid.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | 
 3 | {% block jumbotron %}
 4 | _
 5 | {% endblock %}
 6 | 
 7 | {% block content %}
 8 | 
 9 | 
10 | 
11 | 
12 | 
13 | 
14 | 
15 |              .col-md-4
16 | 
17 | 
18 | 
19 |              
20 | 
21 | 
24 |   
.col-md-8
25 |         
26 |              
27 | 
28 | 
29 | 
30 | 
31 |              .col-md-4
32 | 
33 | 
34 | 
35 |              
36 |             
.col-md-4
37 | 
38 |         
39 | 
40 |   
41 |   
.col-md-4
42 | 
43 |     
47 | 
48 |     
49 | 
 28 |  
 29 | 	
 30 | 		
 31 | 		
Class Based Views 
 32 | 		
The MVP Landing project is designed to get your project started. The goal is to help you launch as soon as possible with the least amount of investment using time or money. Join Us today.
 33 | 		
 34 | 		Join Us » 
 35 | 		
 36 | 		
 37 | 		
 38 | 			VIDEO 
 39 | 
 40 |  		
 41 | 		
 42 | 	
 43 |  
You are logged in! 
 53 | 
 54 | 	{% if queryset %}
 55 | 	Welcome Staff 
 56 | 	
 57 | 	{% for instance in queryset %}
 58 | 		{{ forloop.counter }} {{ instance.email }} {{ instance.full_name }} {{ instance.timestamp|timesince }} ago is equal 
 64 | 
 65 | 	{% endif %}
 66 | 
 67 |  {% else %}
 68 | 
 69 | 
 70 |   
 71 |   	
 72 | 			
{{ title }}
 73 | 
 74 | 			
 80 | 	
 81 | 
 82 | 	
 83 | 
Django & Bootstrap
 84 | 			
 85 | 
 86 | 
 87 | 
 88 | 
Created for Starters 
 89 | 
 91 | 
 92 |  
 95 | 
 96 | 
 97 | 
 98 | 
 99 | 
100 | 
Always Open Source 
103 |  
107 | 
108 | 
109 | 
110 | 
111 | 
112 | 
113 | 
 5 |       
 6 |         
15 |         
16 |           
33 | 
34 | 
35 |           
36 |           {% if request.user.is_authenticated %}
37 |             Logout Register  
42 | 
43 |           {% if not request.user.is_authenticated and not "/accounts/login" in request.get_full_path %}
44 |             
53 |           {% endif %}
54 | 
55 | 
56 |         
57 |       
 
--------------------------------------------------------------------------------
/src/templates/registration/activate.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | 
4 | {% block content %}
5 | 
6 | {% trans "Account activation failed" %}
7 | 
8 | {% endblock %}
9 | 
--------------------------------------------------------------------------------
/src/templates/registration/activation_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | 
4 | {% block content %}
5 | {% trans "Your account is now activated." %}
6 | {% endblock %}
7 | 
--------------------------------------------------------------------------------
/src/templates/registration/activation_email.txt:
--------------------------------------------------------------------------------
 1 | {% load i18n %}
 2 | {% trans "Activate account at" %} {{ site.name }}:
 3 | 
 4 | Hello there!
 5 | 
 6 | Click the link below to activate your account.
 7 | 
 8 | http://{{ site.domain }}{% url 'registration_activate' activation_key %}
 9 | 
10 | 
11 | {% blocktrans %}The above link is valid for {{ expiration_days }} days.{% endblocktrans %}
12 | 
13 | -Team CFE
14 | 
--------------------------------------------------------------------------------
/src/templates/registration/activation_email_subject.txt:
--------------------------------------------------------------------------------
1 | Complete Registration for {{ site.name }}
2 | 
--------------------------------------------------------------------------------
/src/templates/registration/login.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load i18n %}
 3 | {% load crispy_forms_tags %}
 4 | 
 5 | 
 6 | {% block content %}
 7 | 
 8 | 
 9 | 
Login 
10 | 
17 | 
18 | 
19 | 
You have successfully logged out.
Login 
    
6 | {% endblock %}
7 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_change_done.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | 
4 | {% block content %}
5 | {% trans "Password changed" %}
6 | {% endblock %}
7 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_change_form.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load i18n %}
 3 | 
 4 | {% block content %}
 5 | 
11 | {% endblock %}
12 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_reset_complete.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load i18n %}
 3 | 
 4 | {% block content %}
 5 | 
 6 | {% trans "Password reset successfully" %}
 7 | 
 8 | {% trans "Log in" %} 
 9 | 
10 | {% endblock %}
11 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_reset_confirm.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load i18n %}
 3 | 
 4 | {% block content %}
 5 | 
 6 | {% if validlink %}
 7 | 
 8 | 
14 | 
15 | {% else %}
16 | 
17 | {% trans "Password reset failed" %}
18 | 
19 | {% endif %}
20 | 
21 | {% endblock %}
22 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_reset_done.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | 
4 | {% block content %}
5 | {% trans "Email with password reset instructions has been sent." %}
6 | {% endblock %}
7 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_reset_email.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Reset password at {{ site_name }}{% endblocktrans %}:
3 | {% block reset_link %}
4 | {{ protocol }}://{{ domain }}{% url 'auth_password_reset_confirm' uid token %}
5 | {% endblock %}
6 | 
--------------------------------------------------------------------------------
/src/templates/registration/password_reset_form.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load crispy_forms_tags %}
 3 | {% load i18n %}
 4 | 
 5 | {% block content %}
 6 | 
 7 | 
Password Reset 
 8 | 
Reset your password using your email below.
 9 | 
15 | 
{% trans "Registration is currently closed." %}
6 | {% endblock %}
7 | 
--------------------------------------------------------------------------------
/src/templates/registration/registration_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | 
4 | {% block content %}
5 | {% trans "You are now registered. Activation email sent." %}
6 | {% endblock %}
--------------------------------------------------------------------------------
/src/templates/registration/registration_form.html:
--------------------------------------------------------------------------------
 1 | {% extends "base.html" %}
 2 | {% load i18n %}
 3 | {% load crispy_forms_tags %}
 4 | 
 5 | 
 6 | {% block content %}
 7 | 
 8 | 
 9 | 
Register for free! 
10 | 
16 | 
17 | 
 4 | 
 5 | 
 6 | 
 7 | {% if title %}
 8 | 
{{ title }} 
 9 | {% endif %}
10 | 
11 | 
17 | 
18 | 
, because it just gets in the way.
 29 |                 from_box.parentNode.removeChild(ps[i]);
 30 |             } else if (ps[i].className.indexOf("help") != -1) {
 31 |                 // Move help text up to the top so it isn't below the select
 32 |                 // boxes or wrapped off on the side to the right of the add
 33 |                 // button:
 34 |                 from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
 35 |             }
 36 |         }
 37 | 
 38 |         //  or 
 39 |         var selector_div = quickElement('div', from_box.parentNode);
 40 |         selector_div.className = is_stacked ? 'selector stacked' : 'selector';
 41 | 
 42 |         // 
 43 |         var selector_available = quickElement('div', selector_div);
 44 |         selector_available.className = 'selector-available';
 45 |         var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
 46 |         quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name]));
 47 | 
 48 |         var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
 49 |         filter_p.className = 'selector-filter';
 50 | 
 51 |         var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input");
 52 | 
 53 |         var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]));
 54 | 
 55 |         filter_p.appendChild(document.createTextNode(' '));
 56 | 
 57 |         var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
 58 |         filter_input.id = field_id + '_input';
 59 | 
 60 |         selector_available.appendChild(from_box);
 61 |         var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link');
 62 |         choose_all.className = 'selector-chooseall';
 63 | 
 64 |         // 
 65 |         var selector_chooser = quickElement('ul', selector_div);
 66 |         selector_chooser.className = 'selector-chooser';
 67 |         var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link');
 68 |         add_link.className = 'selector-add';
 69 |         var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link');
 70 |         remove_link.className = 'selector-remove';
 71 | 
 72 |         // 
 73 |         var selector_chosen = quickElement('div', selector_div);
 74 |         selector_chosen.className = 'selector-chosen';
 75 |         var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
 76 |         quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name]));
 77 | 
 78 |         var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
 79 |         to_box.className = 'filtered';
 80 |         var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link');
 81 |         clear_all.className = 'selector-clearall';
 82 | 
 83 |         from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
 84 | 
 85 |         // Set up the JavaScript event handlers for the select box filter interface
 86 |         addEvent(filter_input, 'keypress', function(e) { SelectFilter.filter_key_press(e, field_id); });
 87 |         addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
 88 |         addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
 89 |         addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
 90 |         addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
 91 |         addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
 92 |         addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
 93 |         addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
 94 |         SelectBox.init(field_id + '_from');
 95 |         SelectBox.init(field_id + '_to');
 96 |         // Move selected from_box options to to_box
 97 |         SelectBox.move(field_id + '_from', field_id + '_to');
 98 | 
 99 |         if (!is_stacked) {
100 |             // In horizontal mode, give the same height to the two boxes.
101 |             var j_from_box = $(from_box);
102 |             var j_to_box = $(to_box);
103 |             var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }
104 |             if (j_from_box.outerHeight() > 0) {
105 |                 resize_filters(); // This fieldset is already open. Resize now.
106 |             } else {
107 |                 // This fieldset is probably collapsed. Wait for its 'show' event.
108 |                 j_to_box.closest('fieldset').one('show.fieldset', resize_filters);
109 |             }
110 |         }
111 | 
112 |         // Initial icon refresh
113 |         SelectFilter.refresh_icons(field_id);
114 |     },
115 |     refresh_icons: function(field_id) {
116 |         var from = $('#' + field_id + '_from');
117 |         var to = $('#' + field_id + '_to');
118 |         var is_from_selected = from.find('option:selected').length > 0;
119 |         var is_to_selected = to.find('option:selected').length > 0;
120 |         // Active if at least one item is selected
121 |         $('#' + field_id + '_add_link').toggleClass('active', is_from_selected);
122 |         $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected);
123 |         // Active if the corresponding box isn't empty
124 |         $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
125 |         $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
126 |     },
127 |     filter_key_press: function(event, field_id) {
128 |         var from = document.getElementById(field_id + '_from');
129 |         // don't submit form if user pressed Enter
130 |         if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
131 |             from.selectedIndex = 0;
132 |             SelectBox.move(field_id + '_from', field_id + '_to');
133 |             from.selectedIndex = 0;
134 |             event.preventDefault()
135 |             return false;
136 |         }
137 |     },
138 |     filter_key_up: function(event, field_id) {
139 |         var from = document.getElementById(field_id + '_from');
140 |         var temp = from.selectedIndex;
141 |         SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
142 |         from.selectedIndex = temp;
143 |         return true;
144 |     },
145 |     filter_key_down: function(event, field_id) {
146 |         var from = document.getElementById(field_id + '_from');
147 |         // right arrow -- move across
148 |         if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
149 |             var old_index = from.selectedIndex;
150 |             SelectBox.move(field_id + '_from', field_id + '_to');
151 |             from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
152 |             return false;
153 |         }
154 |         // down arrow -- wrap around
155 |         if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
156 |             from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
157 |         }
158 |         // up arrow -- wrap around
159 |         if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
160 |             from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
161 |         }
162 |         return true;
163 |     }
164 | }
165 | 
166 | })(django.jQuery);
167 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/actions.js:
--------------------------------------------------------------------------------
  1 | (function($) {
  2 | 	var lastChecked;
  3 | 
  4 | 	$.fn.actions = function(opts) {
  5 | 		var options = $.extend({}, $.fn.actions.defaults, opts);
  6 | 		var actionCheckboxes = $(this);
  7 | 		var list_editable_changed = false;
  8 | 		var checker = function(checked) {
  9 | 			if (checked) {
 10 | 				showQuestion();
 11 | 			} else {
 12 | 				reset();
 13 | 			}
 14 | 			$(actionCheckboxes).prop("checked", checked)
 15 | 				.parent().parent().toggleClass(options.selectedClass, checked);
 16 | 		},
 17 | 		updateCounter = function() {
 18 | 			var sel = $(actionCheckboxes).filter(":checked").length;
 19 | 			// _actions_icnt is defined in the generated HTML
 20 | 			// and contains the total amount of objects in the queryset
 21 | 			$(options.counterContainer).html(interpolate(
 22 | 			ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
 23 | 				sel: sel,
 24 | 				cnt: _actions_icnt
 25 | 			}, true));
 26 | 			$(options.allToggle).prop("checked", function() {
 27 | 				var value;
 28 | 				if (sel == actionCheckboxes.length) {
 29 | 					value = true;
 30 | 					showQuestion();
 31 | 				} else {
 32 | 					value = false;
 33 | 					clearAcross();
 34 | 				}
 35 | 				return value;
 36 | 			});
 37 | 		},
 38 | 		showQuestion = function() {
 39 | 			$(options.acrossClears).hide();
 40 | 			$(options.acrossQuestions).show();
 41 | 			$(options.allContainer).hide();
 42 | 		},
 43 | 		showClear = function() {
 44 | 			$(options.acrossClears).show();
 45 | 			$(options.acrossQuestions).hide();
 46 | 			$(options.actionContainer).toggleClass(options.selectedClass);
 47 | 			$(options.allContainer).show();
 48 | 			$(options.counterContainer).hide();
 49 | 		},
 50 | 		reset = function() {
 51 | 			$(options.acrossClears).hide();
 52 | 			$(options.acrossQuestions).hide();
 53 | 			$(options.allContainer).hide();
 54 | 			$(options.counterContainer).show();
 55 | 		},
 56 | 		clearAcross = function() {
 57 | 			reset();
 58 | 			$(options.acrossInput).val(0);
 59 | 			$(options.actionContainer).removeClass(options.selectedClass);
 60 | 		};
 61 | 		// Show counter by default
 62 | 		$(options.counterContainer).show();
 63 | 		// Check state of checkboxes and reinit state if needed
 64 | 		$(this).filter(":checked").each(function(i) {
 65 | 			$(this).parent().parent().toggleClass(options.selectedClass);
 66 | 			updateCounter();
 67 | 			if ($(options.acrossInput).val() == 1) {
 68 | 				showClear();
 69 | 			}
 70 | 		});
 71 | 		$(options.allToggle).show().click(function() {
 72 | 			checker($(this).prop("checked"));
 73 | 			updateCounter();
 74 | 		});
 75 | 		$("a", options.acrossQuestions).click(function(event) {
 76 | 			event.preventDefault();
 77 | 			$(options.acrossInput).val(1);
 78 | 			showClear();
 79 | 		});
 80 | 		$("a", options.acrossClears).click(function(event) {
 81 | 			event.preventDefault();
 82 | 			$(options.allToggle).prop("checked", false);
 83 | 			clearAcross();
 84 | 			checker(0);
 85 | 			updateCounter();
 86 | 		});
 87 | 		lastChecked = null;
 88 | 		$(actionCheckboxes).click(function(event) {
 89 | 			if (!event) { event = window.event; }
 90 | 			var target = event.target ? event.target : event.srcElement;
 91 | 			if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) {
 92 | 				var inrange = false;
 93 | 				$(lastChecked).prop("checked", target.checked)
 94 | 					.parent().parent().toggleClass(options.selectedClass, target.checked);
 95 | 				$(actionCheckboxes).each(function() {
 96 | 					if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
 97 | 						inrange = (inrange) ? false : true;
 98 | 					}
 99 | 					if (inrange) {
100 | 						$(this).prop("checked", target.checked)
101 | 							.parent().parent().toggleClass(options.selectedClass, target.checked);
102 | 					}
103 | 				});
104 | 			}
105 | 			$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
106 | 			lastChecked = target;
107 | 			updateCounter();
108 | 		});
109 | 		$('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
110 | 			list_editable_changed = true;
111 | 		});
112 | 		$('form#changelist-form button[name="index"]').click(function(event) {
113 | 			if (list_editable_changed) {
114 | 				return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
115 | 			}
116 | 		});
117 | 		$('form#changelist-form input[name="_save"]').click(function(event) {
118 | 			var action_changed = false;
119 | 			$('select option:selected', options.actionContainer).each(function() {
120 | 				if ($(this).val()) {
121 | 					action_changed = true;
122 | 				}
123 | 			});
124 | 			if (action_changed) {
125 | 				if (list_editable_changed) {
126 | 					return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
127 | 				} else {
128 | 					return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
129 | 				}
130 | 			}
131 | 		});
132 | 	};
133 | 	/* Setup plugin defaults */
134 | 	$.fn.actions.defaults = {
135 | 		actionContainer: "div.actions",
136 | 		counterContainer: "span.action-counter",
137 | 		allContainer: "div.actions span.all",
138 | 		acrossInput: "div.actions input.select-across",
139 | 		acrossQuestions: "div.actions span.question",
140 | 		acrossClears: "div.actions span.clear",
141 | 		allToggle: "#action-toggle",
142 | 		selectedClass: "selected"
143 | 	};
144 | })(django.jQuery);
145 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/actions.min.js:
--------------------------------------------------------------------------------
1 | (function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide();
2 | a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);
3 | h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,
4 | d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});
5 | a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};
6 | a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
7 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/admin/RelatedObjectLookups.js:
--------------------------------------------------------------------------------
  1 | // Handles related-objects functionality: lookup link for raw_id_fields
  2 | // and Add Another links.
  3 | 
  4 | function html_unescape(text) {
  5 |     // Unescape a string that was escaped using django.utils.html.escape.
  6 |     text = text.replace(/</g, '<');
  7 |     text = text.replace(/>/g, '>');
  8 |     text = text.replace(/"/g, '"');
  9 |     text = text.replace(/'/g, "'");
 10 |     text = text.replace(/&/g, '&');
 11 |     return text;
 12 | }
 13 | 
 14 | // IE doesn't accept periods or dashes in the window name, but the element IDs
 15 | // we use to generate popup window names may contain them, therefore we map them
 16 | // to allowed characters in a reversible way so that we can locate the correct
 17 | // element when the popup window is dismissed.
 18 | function id_to_windowname(text) {
 19 |     text = text.replace(/\./g, '__dot__');
 20 |     text = text.replace(/\-/g, '__dash__');
 21 |     return text;
 22 | }
 23 | 
 24 | function windowname_to_id(text) {
 25 |     text = text.replace(/__dot__/g, '.');
 26 |     text = text.replace(/__dash__/g, '-');
 27 |     return text;
 28 | }
 29 | 
 30 | function showAdminPopup(triggeringLink, name_regexp) {
 31 |     var name = triggeringLink.id.replace(name_regexp, '');
 32 |     name = id_to_windowname(name);
 33 |     var href = triggeringLink.href;
 34 |     if (href.indexOf('?') == -1) {
 35 |         href += '?_popup=1';
 36 |     } else {
 37 |         href  += '&_popup=1';
 38 |     }
 39 |     var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
 40 |     win.focus();
 41 |     return false;
 42 | }
 43 | 
 44 | function showRelatedObjectLookupPopup(triggeringLink) {
 45 |     return showAdminPopup(triggeringLink, /^lookup_/);
 46 | }
 47 | 
 48 | function dismissRelatedLookupPopup(win, chosenId) {
 49 |     var name = windowname_to_id(win.name);
 50 |     var elem = document.getElementById(name);
 51 |     if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
 52 |         elem.value += ',' + chosenId;
 53 |     } else {
 54 |         document.getElementById(name).value = chosenId;
 55 |     }
 56 |     win.close();
 57 | }
 58 | 
 59 | function showRelatedObjectPopup(triggeringLink) {
 60 |     var name = triggeringLink.id.replace(/^(change|add|delete)_/, '');
 61 |     name = id_to_windowname(name);
 62 |     var href = triggeringLink.href;
 63 |     var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
 64 |     win.focus();
 65 |     return false;
 66 | }
 67 | 
 68 | function dismissAddRelatedObjectPopup(win, newId, newRepr) {
 69 |     // newId and newRepr are expected to have previously been escaped by
 70 |     // django.utils.html.escape.
 71 |     newId = html_unescape(newId);
 72 |     newRepr = html_unescape(newRepr);
 73 |     var name = windowname_to_id(win.name);
 74 |     var elem = document.getElementById(name);
 75 |     var o;
 76 |     if (elem) {
 77 |         var elemName = elem.nodeName.toUpperCase();
 78 |         if (elemName == 'SELECT') {
 79 |             o = new Option(newRepr, newId);
 80 |             elem.options[elem.options.length] = o;
 81 |             o.selected = true;
 82 |         } else if (elemName == 'INPUT') {
 83 |             if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
 84 |                 elem.value += ',' + newId;
 85 |             } else {
 86 |                 elem.value = newId;
 87 |             }
 88 |         }
 89 |         // Trigger a change event to update related links if required.
 90 |         django.jQuery(elem).trigger('change');
 91 |     } else {
 92 |         var toId = name + "_to";
 93 |         o = new Option(newRepr, newId);
 94 |         SelectBox.add_to_cache(toId, o);
 95 |         SelectBox.redisplay(toId);
 96 |     }
 97 |     win.close();
 98 | }
 99 | 
100 | function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
101 |     objId = html_unescape(objId);
102 |     newRepr = html_unescape(newRepr);
103 |     var id = windowname_to_id(win.name).replace(/^edit_/, '');
104 |     var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
105 |     var selects = django.jQuery(selectsSelector);
106 |     selects.find('option').each(function() {
107 |         if (this.value == objId) {
108 |             this.innerHTML = newRepr;
109 |             this.value = newId;
110 |         }
111 |     });
112 |     win.close();
113 | };
114 | 
115 | function dismissDeleteRelatedObjectPopup(win, objId) {
116 |     objId = html_unescape(objId);
117 |     var id = windowname_to_id(win.name).replace(/^delete_/, '');
118 |     var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
119 |     var selects = django.jQuery(selectsSelector);
120 |     selects.find('option').each(function() {
121 |         if (this.value == objId) {
122 |             django.jQuery(this).remove();
123 |         }
124 |     }).trigger('change');
125 |     win.close();
126 | };
127 | 
128 | // Kept for backward compatibility
129 | showAddAnotherPopup = showRelatedObjectPopup;
130 | dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
131 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/calendar.js:
--------------------------------------------------------------------------------
  1 | /*
  2 | calendar.js - Calendar functions by Adrian Holovaty
  3 | depends on core.js for utility functions like removeChildren or quickElement
  4 | */
  5 | 
  6 | // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
  7 | var CalendarNamespace = {
  8 |     monthsOfYear: gettext('January February March April May June July August September October November December').split(' '),
  9 |     daysOfWeek: gettext('S M T W T F S').split(' '),
 10 |     firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
 11 |     isLeapYear: function(year) {
 12 |         return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0));
 13 |     },
 14 |     getDaysInMonth: function(month,year) {
 15 |         var days;
 16 |         if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
 17 |             days = 31;
 18 |         }
 19 |         else if (month==4 || month==6 || month==9 || month==11) {
 20 |             days = 30;
 21 |         }
 22 |         else if (month==2 && CalendarNamespace.isLeapYear(year)) {
 23 |             days = 29;
 24 |         }
 25 |         else {
 26 |             days = 28;
 27 |         }
 28 |         return days;
 29 |     },
 30 |     draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
 31 |         var today = new Date();
 32 |         var todayDay = today.getDate();
 33 |         var todayMonth = today.getMonth()+1;
 34 |         var todayYear = today.getFullYear();
 35 |         var todayClass = '';
 36 | 
 37 |         // Use UTC functions here because the date field does not contain time
 38 |         // and using the UTC function variants prevent the local time offset
 39 |         // from altering the date, specifically the day field.  For example:
 40 |         //
 41 |         // ```
 42 |         // var x = new Date('2013-10-02');
 43 |         // var day = x.getDate();
 44 |         // ```
 45 |         //
 46 |         // The day variable above will be 1 instead of 2 in, say, US Pacific time
 47 |         // zone.
 48 |         var isSelectedMonth = false;
 49 |         if (typeof selected != 'undefined') {
 50 |             isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month);
 51 |         }
 52 | 
 53 |         month = parseInt(month);
 54 |         year = parseInt(year);
 55 |         var calDiv = document.getElementById(div_id);
 56 |         removeChildren(calDiv);
 57 |         var calTable = document.createElement('table');
 58 |         quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year);
 59 |         var tableBody = quickElement('tbody', calTable);
 60 | 
 61 |         // Draw days-of-week header
 62 |         var tableRow = quickElement('tr', tableBody);
 63 |         for (var i = 0; i < 7; i++) {
 64 |             quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
 65 |         }
 66 | 
 67 |         var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
 68 |         var days = CalendarNamespace.getDaysInMonth(month, year);
 69 | 
 70 |         // Draw blanks before first of month
 71 |         tableRow = quickElement('tr', tableBody);
 72 |         for (var i = 0; i < startingPos; i++) {
 73 |             var _cell = quickElement('td', tableRow, ' ');
 74 |             _cell.className = "nonday";
 75 |         }
 76 | 
 77 |         // Draw days of month
 78 |         var currentDay = 1;
 79 |         for (var i = startingPos; currentDay <= days; i++) {
 80 |             if (i%7 == 0 && currentDay != 1) {
 81 |                 tableRow = quickElement('tr', tableBody);
 82 |             }
 83 |             if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) {
 84 |                 todayClass='today';
 85 |             } else {
 86 |                 todayClass='';
 87 |             }
 88 | 
 89 |             // use UTC function; see above for explanation.
 90 |             if (isSelectedMonth && currentDay == selected.getUTCDate()) {
 91 |                 if (todayClass != '') todayClass += " ";
 92 |                 todayClass += "selected";
 93 |             }
 94 | 
 95 |             var cell = quickElement('td', tableRow, '', 'class', todayClass);
 96 | 
 97 |             quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));');
 98 |             currentDay++;
 99 |         }
100 | 
101 |         // Draw blanks after end of month (optional, but makes for valid code)
102 |         while (tableRow.childNodes.length < 7) {
103 |             var _cell = quickElement('td', tableRow, ' ');
104 |             _cell.className = "nonday";
105 |         }
106 | 
107 |         calDiv.appendChild(calTable);
108 |     }
109 | }
110 | 
111 | // Calendar -- A calendar instance
112 | function Calendar(div_id, callback, selected) {
113 |     // div_id (string) is the ID of the element in which the calendar will
114 |     //     be displayed
115 |     // callback (string) is the name of a JavaScript function that will be
116 |     //     called with the parameters (year, month, day) when a day in the
117 |     //     calendar is clicked
118 |     this.div_id = div_id;
119 |     this.callback = callback;
120 |     this.today = new Date();
121 |     this.currentMonth = this.today.getMonth() + 1;
122 |     this.currentYear = this.today.getFullYear();
123 |     if (typeof selected != 'undefined') {
124 |         this.selected = selected;
125 |     }
126 | }
127 | Calendar.prototype = {
128 |     drawCurrent: function() {
129 |         CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
130 |     },
131 |     drawDate: function(month, year, selected) {
132 |         this.currentMonth = month;
133 |         this.currentYear = year;
134 | 
135 |         if(selected) {
136 |             this.selected = selected;
137 |         }
138 | 
139 |         this.drawCurrent();
140 |     },
141 |     drawPreviousMonth: function() {
142 |         if (this.currentMonth == 1) {
143 |             this.currentMonth = 12;
144 |             this.currentYear--;
145 |         }
146 |         else {
147 |             this.currentMonth--;
148 |         }
149 |         this.drawCurrent();
150 |     },
151 |     drawNextMonth: function() {
152 |         if (this.currentMonth == 12) {
153 |             this.currentMonth = 1;
154 |             this.currentYear++;
155 |         }
156 |         else {
157 |             this.currentMonth++;
158 |         }
159 |         this.drawCurrent();
160 |     },
161 |     drawPreviousYear: function() {
162 |         this.currentYear--;
163 |         this.drawCurrent();
164 |     },
165 |     drawNextYear: function() {
166 |         this.currentYear++;
167 |         this.drawCurrent();
168 |     }
169 | }
170 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/collapse.js:
--------------------------------------------------------------------------------
 1 | (function($) {
 2 | 	$(document).ready(function() {
 3 | 		// Add anchor tag for Show/Hide link
 4 | 		$("fieldset.collapse").each(function(i, elem) {
 5 | 			// Don't hide if fields in this fieldset have errors
 6 | 			if ($(elem).find("div.errors").length == 0) {
 7 | 				$(elem).addClass("collapsed").find("h2").first().append(' (
' + gettext("Show") +
 9 | 					' )');
10 | 			}
11 | 		});
12 | 		// Add toggle to anchor tag
13 | 		$("fieldset.collapse a.collapse-toggle").click(function(ev) {
14 | 			if ($(this).closest("fieldset").hasClass("collapsed")) {
15 | 				// Show
16 | 				$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
17 | 			} else {
18 | 				// Hide
19 | 				$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
20 | 			}
21 | 			return false;
22 | 		});
23 | 	});
24 | })(django.jQuery);
25 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/collapse.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' (
'+gettext("Show")+" )")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
2 | [a(this).attr("id")]);return false})})})(django.jQuery);
3 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/core.js:
--------------------------------------------------------------------------------
  1 | // Core javascript helper functions
  2 | 
  3 | // basic browser identification & version
  4 | var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
  5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
  6 | 
  7 | // Cross-browser event handlers.
  8 | function addEvent(obj, evType, fn) {
  9 |     if (obj.addEventListener) {
 10 |         obj.addEventListener(evType, fn, false);
 11 |         return true;
 12 |     } else if (obj.attachEvent) {
 13 |         var r = obj.attachEvent("on" + evType, fn);
 14 |         return r;
 15 |     } else {
 16 |         return false;
 17 |     }
 18 | }
 19 | 
 20 | function removeEvent(obj, evType, fn) {
 21 |     if (obj.removeEventListener) {
 22 |         obj.removeEventListener(evType, fn, false);
 23 |         return true;
 24 |     } else if (obj.detachEvent) {
 25 |         obj.detachEvent("on" + evType, fn);
 26 |         return true;
 27 |     } else {
 28 |         return false;
 29 |     }
 30 | }
 31 | 
 32 | function cancelEventPropagation(e) {
 33 |     if (!e) e = window.event;
 34 |     e.cancelBubble = true;
 35 |     if (e.stopPropagation) e.stopPropagation();
 36 | }
 37 | 
 38 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
 39 | function quickElement() {
 40 |     var obj = document.createElement(arguments[0]);
 41 |     if (arguments[2]) {
 42 |         var textNode = document.createTextNode(arguments[2]);
 43 |         obj.appendChild(textNode);
 44 |     }
 45 |     var len = arguments.length;
 46 |     for (var i = 3; i < len; i += 2) {
 47 |         obj.setAttribute(arguments[i], arguments[i+1]);
 48 |     }
 49 |     arguments[1].appendChild(obj);
 50 |     return obj;
 51 | }
 52 | 
 53 | // "a" is reference to an object
 54 | function removeChildren(a) {
 55 |     while (a.hasChildNodes()) a.removeChild(a.lastChild);
 56 | }
 57 | 
 58 | // ----------------------------------------------------------------------------
 59 | // Cross-browser xmlhttp object
 60 | // from http://jibbering.com/2002/4/httprequest.html
 61 | // ----------------------------------------------------------------------------
 62 | var xmlhttp;
 63 | /*@cc_on @*/
 64 | /*@if (@_jscript_version >= 5)
 65 |     try {
 66 |         xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 67 |     } catch (e) {
 68 |         try {
 69 |             xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 70 |         } catch (E) {
 71 |             xmlhttp = false;
 72 |         }
 73 |     }
 74 | @else
 75 |     xmlhttp = false;
 76 | @end @*/
 77 | if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
 78 |   xmlhttp = new XMLHttpRequest();
 79 | }
 80 | 
 81 | // ----------------------------------------------------------------------------
 82 | // Find-position functions by PPK
 83 | // See http://www.quirksmode.org/js/findpos.html
 84 | // ----------------------------------------------------------------------------
 85 | function findPosX(obj) {
 86 |     var curleft = 0;
 87 |     if (obj.offsetParent) {
 88 |         while (obj.offsetParent) {
 89 |             curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
 90 |             obj = obj.offsetParent;
 91 |         }
 92 |         // IE offsetParent does not include the top-level
 93 |         if (isIE && obj.parentElement){
 94 |             curleft += obj.offsetLeft - obj.scrollLeft;
 95 |         }
 96 |     } else if (obj.x) {
 97 |         curleft += obj.x;
 98 |     }
 99 |     return curleft;
100 | }
101 | 
102 | function findPosY(obj) {
103 |     var curtop = 0;
104 |     if (obj.offsetParent) {
105 |         while (obj.offsetParent) {
106 |             curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
107 |             obj = obj.offsetParent;
108 |         }
109 |         // IE offsetParent does not include the top-level
110 |         if (isIE && obj.parentElement){
111 |             curtop += obj.offsetTop - obj.scrollTop;
112 |         }
113 |     } else if (obj.y) {
114 |         curtop += obj.y;
115 |     }
116 |     return curtop;
117 | }
118 | 
119 | //-----------------------------------------------------------------------------
120 | // Date object extensions
121 | // ----------------------------------------------------------------------------
122 | 
123 | Date.prototype.getTwelveHours = function() {
124 |     hours = this.getHours();
125 |     if (hours == 0) {
126 |         return 12;
127 |     }
128 |     else {
129 |         return hours <= 12 ? hours : hours-12
130 |     }
131 | }
132 | 
133 | Date.prototype.getTwoDigitMonth = function() {
134 |     return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
135 | }
136 | 
137 | Date.prototype.getTwoDigitDate = function() {
138 |     return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
139 | }
140 | 
141 | Date.prototype.getTwoDigitTwelveHour = function() {
142 |     return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
143 | }
144 | 
145 | Date.prototype.getTwoDigitHour = function() {
146 |     return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
147 | }
148 | 
149 | Date.prototype.getTwoDigitMinute = function() {
150 |     return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
151 | }
152 | 
153 | Date.prototype.getTwoDigitSecond = function() {
154 |     return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
155 | }
156 | 
157 | Date.prototype.getHourMinute = function() {
158 |     return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
159 | }
160 | 
161 | Date.prototype.getHourMinuteSecond = function() {
162 |     return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
163 | }
164 | 
165 | Date.prototype.strftime = function(format) {
166 |     var fields = {
167 |         c: this.toString(),
168 |         d: this.getTwoDigitDate(),
169 |         H: this.getTwoDigitHour(),
170 |         I: this.getTwoDigitTwelveHour(),
171 |         m: this.getTwoDigitMonth(),
172 |         M: this.getTwoDigitMinute(),
173 |         p: (this.getHours() >= 12) ? 'PM' : 'AM',
174 |         S: this.getTwoDigitSecond(),
175 |         w: '0' + this.getDay(),
176 |         x: this.toLocaleDateString(),
177 |         X: this.toLocaleTimeString(),
178 |         y: ('' + this.getFullYear()).substr(2, 4),
179 |         Y: '' + this.getFullYear(),
180 |         '%' : '%'
181 |     };
182 |     var result = '', i = 0;
183 |     while (i < format.length) {
184 |         if (format.charAt(i) === '%') {
185 |             result = result + fields[format.charAt(i + 1)];
186 |             ++i;
187 |         }
188 |         else {
189 |             result = result + format.charAt(i);
190 |         }
191 |         ++i;
192 |     }
193 |     return result;
194 | }
195 | 
196 | // ----------------------------------------------------------------------------
197 | // String object extensions
198 | // ----------------------------------------------------------------------------
199 | String.prototype.pad_left = function(pad_length, pad_string) {
200 |     var new_string = this;
201 |     for (var i = 0; new_string.length < pad_length; i++) {
202 |         new_string = pad_string + new_string;
203 |     }
204 |     return new_string;
205 | }
206 | 
207 | String.prototype.strptime = function(format) {
208 |     var split_format = format.split(/[.\-/]/);
209 |     var date = this.split(/[.\-/]/);
210 |     var i = 0;
211 |     while (i < split_format.length) {
212 |         switch (split_format[i]) {
213 |             case "%d":
214 |                 var day = date[i];
215 |                 break;
216 |             case "%m":
217 |                 var month = date[i] - 1;
218 |                 break;
219 |             case "%Y":
220 |                 var year = date[i];
221 |                 break;
222 |             case "%y":
223 |                 var year = date[i];
224 |                 break;
225 |         }
226 |         ++i;
227 |     };
228 |     return new Date(year, month, day);
229 | }
230 | 
231 | // ----------------------------------------------------------------------------
232 | // Get the computed style for and element
233 | // ----------------------------------------------------------------------------
234 | function getStyle(oElm, strCssRule){
235 |     var strValue = "";
236 |     if(document.defaultView && document.defaultView.getComputedStyle){
237 |         strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
238 |     }
239 |     else if(oElm.currentStyle){
240 |         strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
241 |             return p1.toUpperCase();
242 |         });
243 |         strValue = oElm.currentStyle[strCssRule];
244 |     }
245 |     return strValue;
246 | }
247 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/inlines.js:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * Django admin inlines
  3 |  *
  4 |  * Based on jQuery Formset 1.1
  5 |  * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
  6 |  * @requires jQuery 1.2.6 or later
  7 |  *
  8 |  * Copyright (c) 2009, Stanislaus Madueke
  9 |  * All rights reserved.
 10 |  *
 11 |  * Spiced up with Code from Zain Memon's GSoC project 2009
 12 |  * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip.
 13 |  *
 14 |  * Licensed under the New BSD License
 15 |  * See: http://www.opensource.org/licenses/bsd-license.php
 16 |  */
 17 | (function($) {
 18 |   $.fn.formset = function(opts) {
 19 |     var options = $.extend({}, $.fn.formset.defaults, opts);
 20 |     var $this = $(this);
 21 |     var $parent = $this.parent();
 22 |     var updateElementIndex = function(el, prefix, ndx) {
 23 |       var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
 24 |       var replacement = prefix + "-" + ndx;
 25 |       if ($(el).prop("for")) {
 26 |         $(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
 27 |       }
 28 |       if (el.id) {
 29 |         el.id = el.id.replace(id_regex, replacement);
 30 |       }
 31 |       if (el.name) {
 32 |         el.name = el.name.replace(id_regex, replacement);
 33 |       }
 34 |     };
 35 |     var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
 36 |     var nextIndex = parseInt(totalForms.val(), 10);
 37 |     var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
 38 |     // only show the add button if we are allowed to add more items,
 39 |         // note that max_num = None translates to a blank string.
 40 |     var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
 41 |     $this.each(function(i) {
 42 |       $(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
 43 |     });
 44 |     if ($this.length && showAddButton) {
 45 |       var addButton;
 46 |       if ($this.prop("tagName") == "TR") {
 47 |         // If forms are laid out as table rows, insert the
 48 |         // "add" button in a new table row:
 49 |         var numCols = this.eq(-1).children().length;
 50 |         $parent.append('
' + options.addText + " ");
 51 |         addButton = $parent.find("tr:last a");
 52 |       } else {
 53 |         // Otherwise, insert it immediately after the last form:
 54 |         $this.filter(":last").after('
");
 55 |         addButton = $this.filter(":last").next().find("a");
 56 |       }
 57 |       addButton.click(function(e) {
 58 |         e.preventDefault();
 59 |         var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
 60 |         var template = $("#" + options.prefix + "-empty");
 61 |         var row = template.clone(true);
 62 |         row.removeClass(options.emptyCssClass)
 63 |           .addClass(options.formCssClass)
 64 |           .attr("id", options.prefix + "-" + nextIndex);
 65 |         if (row.is("tr")) {
 66 |           // If the forms are laid out in table rows, insert
 67 |           // the remove button into the last table cell:
 68 |           row.children(":last").append('
");
 69 |         } else if (row.is("ul") || row.is("ol")) {
 70 |           // If they're laid out as an ordered/unordered list,
 71 |           // insert an 
 after the last list item:
 72 |           row.append(' ' + options.deleteText + " ");
 73 |         } else {
 74 |           // Otherwise, just insert the remove button as the
 75 |           // last child element of the form's container:
 76 |           row.children(":first").append('
' + options.deleteText + " ");
 77 |         }
 78 |         row.find("*").each(function() {
 79 |           updateElementIndex(this, options.prefix, totalForms.val());
 80 |         });
 81 |         // Insert the new form when it has been fully edited
 82 |         row.insertBefore($(template));
 83 |         // Update number of total forms
 84 |         $(totalForms).val(parseInt(totalForms.val(), 10) + 1);
 85 |         nextIndex += 1;
 86 |         // Hide add button in case we've hit the max, except we want to add infinitely
 87 |         if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
 88 |           addButton.parent().hide();
 89 |         }
 90 |         // The delete button of each row triggers a bunch of other things
 91 |         row.find("a." + options.deleteCssClass).click(function(e) {
 92 |           e.preventDefault();
 93 |           // Remove the parent form containing this button:
 94 |           var row = $(this).parents("." + options.formCssClass);
 95 |           row.remove();
 96 |           nextIndex -= 1;
 97 |           // If a post-delete callback was provided, call it with the deleted form:
 98 |           if (options.removed) {
 99 |             options.removed(row);
100 |           }
101 |           // Update the TOTAL_FORMS form count.
102 |           var forms = $("." + options.formCssClass);
103 |           $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
104 |           // Show add button again once we drop below max
105 |           if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
106 |             addButton.parent().show();
107 |           }
108 |           // Also, update names and ids for all remaining form controls
109 |           // so they remain in sequence:
110 |           for (var i=0, formCount=forms.length; i
0;i.each(function(){a(this).not("."+
 2 | b.emptyCssClass).addClass(b.formCssClass)});if(i.length&&l){var f;if(i.prop("tagName")=="TR"){i=this.eq(-1).children().length;g.append(''+b.addText+" '+b.deleteText+" '+b.deleteText+"  0) {
23 |                         values.push(field.val());
24 |                     }
25 |                 });
26 |                 prepopulatedField.val(URLify(values.join(' '), maxLength));
27 |             };
28 | 
29 |             prepopulatedField.data('_changed', false);
30 |             prepopulatedField.change(function() {
31 |                 prepopulatedField.data('_changed', true);
32 |             });
33 | 
34 |             if (!prepopulatedField.val()) {
35 |                 $(dependencies.join(',')).keyup(populate).change(populate).focus(populate);
36 |             }
37 |         });
38 |     };
39 | })(django.jQuery);
40 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/prepopulate.min.js:
--------------------------------------------------------------------------------
1 | (function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery);
2 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/related-widget-wrapper.js:
--------------------------------------------------------------------------------
 1 | django.jQuery(function($){
 2 |     function updateLinks() {
 3 |         var $this = $(this);
 4 |         var siblings = $this.nextAll('.change-related, .delete-related');
 5 |         if (!siblings.length) return;
 6 |         var value = $this.val();
 7 |         if (value) {
 8 |             siblings.each(function(){
 9 |                 var elm = $(this);
10 |                 elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
11 |             });
12 |         } else siblings.removeAttr('href');
13 |     }
14 |     var container = $(document);
15 |     container.on('change', '.related-widget-wrapper select', updateLinks);
16 |     container.find('.related-widget-wrapper select').each(updateLinks);
17 |     container.on('click', '.related-widget-wrapper-link', function(event){
18 |         if (this.href) {
19 |             showRelatedObjectPopup(this);
20 |         }
21 |         event.preventDefault();
22 |     });
23 | });
24 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/timeparse.js:
--------------------------------------------------------------------------------
 1 | var timeParsePatterns = [
 2 |     // 9
 3 |     {   re: /^\d{1,2}$/i,
 4 |         handler: function(bits) {
 5 |             if (bits[0].length == 1) {
 6 |                 return '0' + bits[0] + ':00';
 7 |             } else {
 8 |                 return bits[0] + ':00';
 9 |             }
10 |         }
11 |     },
12 |     // 13:00
13 |     {   re: /^\d{2}[:.]\d{2}$/i,
14 |         handler: function(bits) {
15 |             return bits[0].replace('.', ':');
16 |         }
17 |     },
18 |     // 9:00
19 |     {   re: /^\d[:.]\d{2}$/i,
20 |         handler: function(bits) {
21 |             return '0' + bits[0].replace('.', ':');
22 |         }
23 |     },
24 |     // 3 am / 3 a.m. / 3am
25 |     {   re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
26 |         handler: function(bits) {
27 |             var hour = parseInt(bits[1]);
28 |             if (hour == 12) {
29 |                 hour = 0;
30 |             }
31 |             if (bits[2].toLowerCase() == 'p') {
32 |                 if (hour == 12) {
33 |                     hour = 0;
34 |                 }
35 |                 return (hour + 12) + ':00';
36 |             } else {
37 |                 if (hour < 10) {
38 |                     return '0' + hour + ':00';
39 |                 } else {
40 |                     return hour + ':00';
41 |                 }
42 |             }
43 |         }
44 |     },
45 |     // 3.30 am / 3:15 a.m. / 3.00am
46 |     {   re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
47 |         handler: function(bits) {
48 |             var hour = parseInt(bits[1]);
49 |             var mins = parseInt(bits[2]);
50 |             if (mins < 10) {
51 |                 mins = '0' + mins;
52 |             }
53 |             if (hour == 12) {
54 |                 hour = 0;
55 |             }
56 |             if (bits[3].toLowerCase() == 'p') {
57 |                 if (hour == 12) {
58 |                     hour = 0;
59 |                 }
60 |                 return (hour + 12) + ':' + mins;
61 |             } else {
62 |                 if (hour < 10) {
63 |                     return '0' + hour + ':' + mins;
64 |                 } else {
65 |                     return hour + ':' + mins;
66 |                 }
67 |             }
68 |         }
69 |     },
70 |     // noon
71 |     {   re: /^no/i,
72 |         handler: function(bits) {
73 |             return '12:00';
74 |         }
75 |     },
76 |     // midnight
77 |     {   re: /^mid/i,
78 |         handler: function(bits) {
79 |             return '00:00';
80 |         }
81 |     }
82 | ];
83 | 
84 | function parseTimeString(s) {
85 |     for (var i = 0; i < timeParsePatterns.length; i++) {
86 |         var re = timeParsePatterns[i].re;
87 |         var handler = timeParsePatterns[i].handler;
88 |         var bits = re.exec(s);
89 |         if (bits) {
90 |             return handler(bits);
91 |         }
92 |     }
93 |     return s;
94 | }
95 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/admin/js/urlify.js:
--------------------------------------------------------------------------------
  1 | var LATIN_MAP = {
  2 |     'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
  3 |     'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
  4 |     'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
  5 |     'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
  6 |     'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã':
  7 |     'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e',
  8 |     'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò':
  9 |     'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u',
 10 |     'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
 11 | };
 12 | var LATIN_SYMBOLS_MAP = {
 13 |     '©':'(c)'
 14 | };
 15 | var GREEK_MAP = {
 16 |     'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
 17 |     'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
 18 |     'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
 19 |     'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
 20 |     'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
 21 |     'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
 22 |     'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
 23 |     'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
 24 |     'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
 25 |     'Ϋ':'Y'
 26 | };
 27 | var TURKISH_MAP = {
 28 |     'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
 29 |     'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G'
 30 | };
 31 | var RUSSIAN_MAP = {
 32 |     'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
 33 |     'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
 34 |     'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
 35 |     'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
 36 |     'я':'ya',
 37 |     'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
 38 |     'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
 39 |     'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
 40 |     'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
 41 |     'Я':'Ya'
 42 | };
 43 | var UKRAINIAN_MAP = {
 44 |     'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
 45 | };
 46 | var CZECH_MAP = {
 47 |     'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
 48 |     'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
 49 |     'Ů':'U', 'Ž':'Z'
 50 | };
 51 | var POLISH_MAP = {
 52 |     'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z',
 53 |     'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S',
 54 |     'Ź':'Z', 'Ż':'Z'
 55 | };
 56 | var LATVIAN_MAP = {
 57 |     'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n',
 58 |     'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I',
 59 |     'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z'
 60 | };
 61 | var ARABIC_MAP = {
 62 |     'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d',
 63 |     'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t',
 64 |     'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m',
 65 |     'ن':'n', 'ه':'h', 'و':'o', 'ي':'y'
 66 | };
 67 | var LITHUANIAN_MAP = {
 68 |     'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u',
 69 |     'ž':'z',
 70 |     'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U',
 71 |     'Ž':'Z'
 72 | };
 73 | var SERBIAN_MAP = {
 74 |     'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj',
 75 |     'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj'
 76 | };
 77 | var AZERBAIJANI_MAP = {
 78 |     'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u',
 79 |     'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U'
 80 | };
 81 | 
 82 | var ALL_DOWNCODE_MAPS = [
 83 |     LATIN_MAP,
 84 |     LATIN_SYMBOLS_MAP,
 85 |     GREEK_MAP,
 86 |     TURKISH_MAP,
 87 |     RUSSIAN_MAP,
 88 |     UKRAINIAN_MAP,
 89 |     CZECH_MAP,
 90 |     POLISH_MAP,
 91 |     LATVIAN_MAP,
 92 |     ARABIC_MAP,
 93 |     LITHUANIAN_MAP,
 94 |     SERBIAN_MAP,
 95 |     AZERBAIJANI_MAP
 96 | ];
 97 | 
 98 | var Downcoder = {
 99 |     'Initialize': function() {
100 |         if (Downcoder.map) {  // already made
101 |             return;
102 |         }
103 |         Downcoder.map = {};
104 |         Downcoder.chars = [];
105 |         for (var i=0; ili>a:hover {
20 |   color: #999;
21 | }
22 | 
23 | .navbar-default .navbar-toggle {
24 |  border-color: transparent !important;
25 | }
26 | 
27 | .navbar-toggle:hover {
28 | 	background-color: #444444 !important;
29 | }
30 | 
31 | .navbar-toggle {
32 | 	background-color: #444444 !important;
33 | }
--------------------------------------------------------------------------------
/static_in_env/static_root/img/example.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/static_in_env/static_root/img/example.txt
--------------------------------------------------------------------------------
/static_in_env/static_root/img/marketing1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/static_in_env/static_root/img/marketing1.jpg
--------------------------------------------------------------------------------
/static_in_env/static_root/img/mvp_landing_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/static_in_env/static_root/img/mvp_landing_logo.png
--------------------------------------------------------------------------------
/static_in_env/static_root/js/ie10-viewport-bug-workaround.js:
--------------------------------------------------------------------------------
 1 | /*!
 2 |  * IE10 viewport hack for Surface/desktop Windows 8 bug
 3 |  * Copyright 2014 Twitter, Inc.
 4 |  * Licensed under the Creative Commons Attribution 3.0 Unported License. For
 5 |  * details, see http://creativecommons.org/licenses/by/3.0/.
 6 |  */
 7 | 
 8 | // See the Getting Started docs for more information:
 9 | // http://getbootstrap.com/getting-started/#support-ie10-width
10 | 
11 | (function () {
12 |   'use strict';
13 |   if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
14 |     var msViewportStyle = document.createElement('style')
15 |     msViewportStyle.appendChild(
16 |       document.createTextNode(
17 |         '@-ms-viewport{width:auto!important}'
18 |       )
19 |     )
20 |     document.querySelector('head').appendChild(msViewportStyle)
21 |   }
22 | })();
23 | 
--------------------------------------------------------------------------------
/static_in_env/static_root/psd/mvp_landing_logo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codingforentrepreneurs/Class-Based-Views/8eb26721d1fdbc3753dbc4d69072a313cc62aa23/static_in_env/static_root/psd/mvp_landing_logo.psd
--------------------------------------------------------------------------------
/webfaction/httpd.conf:
--------------------------------------------------------------------------------
 1 | ServerRoot "/home/cfedeploy/webapps/mvpland/apache2"
 2 | 
 3 | LoadModule authz_core_module modules/mod_authz_core.so
 4 | LoadModule dir_module        modules/mod_dir.so
 5 | LoadModule env_module        modules/mod_env.so
 6 | LoadModule log_config_module modules/mod_log_config.so
 7 | LoadModule mime_module       modules/mod_mime.so
 8 | LoadModule rewrite_module    modules/mod_rewrite.so
 9 | LoadModule setenvif_module   modules/mod_setenvif.so
10 | LoadModule wsgi_module       modules/mod_wsgi.so
11 | LoadModule unixd_module      modules/mod_unixd.so
12 | 
13 | LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
14 | CustomLog /home/cfedeploy/logs/user/access_mvpland.log combined
15 | ErrorLog /home/cfedeploy/logs/user/error_mvpland.log
16 | 
17 | Listen 14383
18 | KeepAlive Off
19 | SetEnvIf X-Forwarded-SSL on HTTPS=1
20 | ServerLimit 1
21 | StartServers 1
22 | MaxRequestWorkers 5
23 | MinSpareThreads 1
24 | MaxSpareThreads 3
25 | ThreadsPerChild 5
26 | 
27 | WSGIPythonPath /home/cfedeploy/webapps/mvpland:/home/cfedeploy/webapps/mvpland/src:/home/cfedeploy/webapps/mvpland/lib/python2.7
28 | WSGIDaemonProcess mvpland processes=2 threads=12 python-path=/home/cfedeploy/webapps/mvpland:/home/cfedeploy/webapps/mvpland/src:/home/cfedeploy/webapps/mvpland/lib/python2.7
29 | WSGIProcessGroup mvpland
30 | WSGIRestrictEmbedded On
31 | WSGILazyInitialization On
32 | WSGIScriptAlias / /home/cfedeploy/webapps/mvpland/src/trydjango18/wsgi.py
33 | 
--------------------------------------------------------------------------------