├── .gitignore
├── LICENSE-MIT
├── README.md
├── bootstrap-fileprogress.jquery.json
├── bower.json
├── src
└── bootstrap-uploadprogress.js
└── test
├── README.md
├── db.sqlite3
├── manage.py
├── project
├── __init__.py
├── progress
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ ├── base.html
│ │ ├── package_form.html
│ │ ├── package_form_modal.html
│ │ └── package_list.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── settings.py
├── urls.py
└── wsgi.py
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | test/components
2 | test/upload
3 | *.pyc
4 | db.sqlite3
5 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Jakob Aarøe Dam
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap UploadProgress
2 |
3 | Bootstrap UploadProgress is a simple plugin that adds an upload progress bar to forms that upload files. This improves
4 | on most browsers that lack any progress indication of uploads.
5 |
6 | ## Getting Started, Documentation and Examples
7 | https://aarhusworks.com/2015/05/27/bootstrap-uploadprogress.html
8 |
9 | ## Bug tracker
10 |
11 | Have a bug or a feature request? [Please open a new issue](https://github.com/jakobadam/bootstrap-uploadprogress/issues).
12 |
13 | ## Copyright and license
14 |
15 | Bootstrap UploadProgress is an open source project, sponsored by [Aarhusworks](http://aarhusworks.com), and released under terms of the MIT Licence.
16 |
--------------------------------------------------------------------------------
/bootstrap-fileprogress.jquery.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap-uploadprogress",
3 | "title": "Bootstrap progressbar on input file",
4 | "version": "v1.0.0",
5 | "description": "jQuery Uploadprogress for Bootstrap - Progressbar for forms with file inputs",
6 | "keywords": ["jquery", "file", "upload", "boostrap", "multiple", "input"],
7 | "homepage": "http://aarhusworks.com/bootstrap-uploadprogress/",
8 | "demo": "",
9 | "bugs": "https://github.com/jakobadam/bootstrap-uploadprogress/issues",
10 | "author": {
11 | "name": "Jakob Aarøe Dam",
12 | "url": "https://github.com/jakobadam"
13 | },
14 | "maintainers": [
15 | {
16 | "name": "Jakob Aarøe Dam",
17 | "url": "https://github.com/jakobadam"
18 | }
19 | ],
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/jakobadam/bootstrap-uploadprogress"
23 | },
24 | "licenses": [
25 | {
26 | "type": "MIT",
27 | "url": "http://www.opensource.org/licenses/MIT"
28 | }
29 | ],
30 | "devDependencies": {
31 | "jquery": ">=1.5"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap-uploadprogress",
3 | "version": "1.0.0",
4 | "homepage": "https://github.com/jakobadam/bootstrap-uploadprogress",
5 | "authors": [
6 | "Jakob Aarøe Dam"
7 | ],
8 | "description": "Bootstrap Uploadprogress is a simple plugin to get an upload progressbar.",
9 | "main": "src/bootstrap-uploadprogress.js",
10 | "keywords": [
11 | "bootstrap",
12 | "fileupload",
13 | "uploadprogress"
14 | ],
15 | "license": "MIT",
16 | "ignore": [
17 | "**/.*",
18 | "node_modules",
19 | "bower_components",
20 | "test",
21 | "tests"
22 | ],
23 | "dependencies": {
24 | "jquery": ">=1.6"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/bootstrap-uploadprogress.js:
--------------------------------------------------------------------------------
1 | /*
2 | * bootstrap-uploadprogress
3 | * github: https://github.com/jakobadam/bootstrap-uploadprogress
4 | *
5 | * Copyright (c) 2015 Jakob Aarøe Dam
6 | * Version 1.0.0
7 | * Licensed under the MIT license.
8 | */
9 | (function($){
10 | "use strict";
11 |
12 | $.support.xhrFileUpload = !!(window.FileReader && window.ProgressEvent);
13 | $.support.xhrFormData = !!window.FormData;
14 |
15 | if(!$.support.xhrFileUpload || !$.support.xhrFormData){
16 | // skip decorating form
17 | return;
18 | }
19 |
20 | var template = '
\
21 |
\
22 |
\
23 | \
27 |
\
28 |
\
29 |
\
30 |
\
32 | 0%\
33 |
\
34 |
\
35 |
\
36 | \
39 |
\
40 |
\
41 |
';
42 |
43 | var Uploadprogress = function(element, options){
44 | this.options = options;
45 | this.$element = $(element);
46 | };
47 |
48 | Uploadprogress.prototype = {
49 |
50 | constructor: function() {
51 | this.$form = this.$element;
52 | this.$form.on('submit', $.proxy(this.submit, this));
53 | this.$modal = $(this.options.template);
54 | this.$modal_message = this.$modal.find('.modal-message');
55 | this.$modal_title = this.$modal.find('.modal-title');
56 | this.$modal_footer = this.$modal.find('.modal-footer');
57 | this.$modal_bar = this.$modal.find('.progress-bar');
58 |
59 | this.$modal.on('hidden.bs.modal', $.proxy(this.reset, this));
60 | },
61 |
62 | reset: function(){
63 | this.$modal_title = this.$modal_title.text('Uploading');
64 | this.$modal_footer.hide();
65 | this.$modal_bar.addClass('progress-bar-success');
66 | this.$modal_bar.removeClass('progress-bar-danger');
67 | if(this.xhr){
68 | this.xhr.abort();
69 | }
70 | },
71 |
72 | submit: function(e) {
73 | e.preventDefault();
74 |
75 | this.$modal.modal({
76 | backdrop: 'static',
77 | keyboard: false
78 | });
79 |
80 | // We need the native XMLHttpRequest for the progress event
81 | var xhr = new XMLHttpRequest();
82 | this.xhr = xhr;
83 |
84 | xhr.addEventListener('load', $.proxy(this.success, this, xhr));
85 | xhr.addEventListener('error', $.proxy(this.error, this, xhr));
86 | //xhr.addEventListener('abort', function(){});
87 |
88 | xhr.upload.addEventListener('progress', $.proxy(this.progress, this));
89 |
90 | var form = this.$form;
91 |
92 | xhr.open(form.attr('method'), window.location.href);
93 | xhr.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest');
94 |
95 | var data = new FormData(form.get(0));
96 | xhr.send(data);
97 | },
98 |
99 | success: function(xhr) {
100 | if(xhr.status == 0 || xhr.status >= 400){
101 | // HTTP 500 ends up here!?!
102 | return this.error(xhr);
103 | }
104 | this.set_progress(100);
105 | var url;
106 | var content_type = xhr.getResponseHeader('Content-Type');
107 |
108 | // make it possible to return the redirect URL in
109 | // a JSON response
110 | if(content_type.indexOf('application/json') !== -1){
111 | var response = $.parseJSON(xhr.responseText);
112 | url = response.location;
113 | }
114 | else{
115 | url = this.options.redirect_url;
116 | }
117 | window.location.href = url;
118 | },
119 |
120 | // handle form error
121 | // we replace the form with the returned one
122 | error: function(xhr){
123 | this.$modal_title.text('Upload failed');
124 |
125 | this.$modal_bar.removeClass('progress-bar-success');
126 | this.$modal_bar.addClass('progress-bar-danger');
127 | this.$modal_footer.show();
128 |
129 | var content_type = xhr.getResponseHeader('Content-Type');
130 |
131 | // Replace the contents of the form, with the returned html
132 | if(xhr.status === 422){
133 | var new_html = $.parseHTML(xhr.responseText);
134 | this.replace_form(new_html);
135 | this.$modal.modal('hide');
136 | }
137 | // Write the error response to the document.
138 | else{
139 | var response_text = xhr.responseText;
140 | if(content_type.indexOf('text/plain') !== -1){
141 | response_text = '' + response_text + '
';
142 | }
143 | document.write(xhr.responseText);
144 | }
145 | },
146 |
147 | set_progress: function(percent){
148 | this.$modal_bar.attr('aria-valuenow', percent);
149 | this.$modal_bar.text(percent + '%');
150 | this.$modal_bar.css('width', percent + '%');
151 | },
152 |
153 | progress: function(/*ProgressEvent*/e){
154 | var percent = Math.round((e.loaded / e.total) * 100);
155 | this.set_progress(percent);
156 | },
157 |
158 | // replace_form replaces the contents of the current form
159 | // with the form in the html argument.
160 | // We use the id of the current form to find the new form in the html
161 | replace_form: function(html){
162 | var new_form;
163 | var form_id = this.$form.attr('id');
164 | if(form_id !== undefined){
165 | new_form = $(html).find('#' + form_id);
166 | }
167 | else{
168 | new_form = $(html).find('form');
169 | }
170 |
171 | // add the filestyle again
172 | new_form.find(':file').filestyle({buttonBefore: true});
173 | this.$form.html(new_form.children());
174 | }
175 | };
176 |
177 | $.fn.uploadprogress = function(options, value){
178 | return this.each(function(){
179 | var _options = $.extend({}, $.fn.uploadprogress.defaults, options);
180 | var file_progress = new Uploadprogress(this, _options);
181 | file_progress.constructor();
182 | });
183 | };
184 |
185 | $.fn.uploadprogress.defaults = {
186 | template: template
187 | //redirect_url: ...
188 |
189 | // need to customize stuff? Add here, and change code accordingly.
190 | };
191 |
192 | })(window.jQuery);
193 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap UploadProgress test using Django
2 |
3 | This is a test of bootstrap-uploadprogress using Django. It uses
4 | uploading of software packages -- which are usually large files -- to
5 | demonstrate the functionality.
6 |
7 | ## Getting started
8 |
9 | Install Django and friends
10 | ```
11 | $ pip install -r requirements.txt
12 | ```
13 |
14 | Install Javascript prerequisites
15 | ```
16 | $ ./manange.py bower install
17 | ```
18 |
19 | Run development server
20 | ```
21 | $ ./manage.py runserver
22 | ```
23 |
24 | ## Test
25 |
26 | Point browser to http://localhost:8000
27 |
28 | ```
29 | $ firefox localhost:8080
30 | ```
31 |
32 | Go and upload something big.
33 |
--------------------------------------------------------------------------------
/test/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakobadam/bootstrap-uploadprogress/76aa8344bd914950053788879443a1d2cec5a9f9/test/db.sqlite3
--------------------------------------------------------------------------------
/test/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", "project.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError:
10 | # The above import may fail for some other reason. Ensure that the
11 | # issue is really that Django is missing to avoid masking other
12 | # exceptions on Python 2.
13 | try:
14 | import django
15 | except ImportError:
16 | raise ImportError(
17 | "Couldn't import Django. Are you sure it's installed and "
18 | "available on your PYTHONPATH environment variable? Did you "
19 | "forget to activate a virtual environment?"
20 | )
21 | raise
22 | execute_from_command_line(sys.argv)
23 |
--------------------------------------------------------------------------------
/test/project/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakobadam/bootstrap-uploadprogress/76aa8344bd914950053788879443a1d2cec5a9f9/test/project/__init__.py
--------------------------------------------------------------------------------
/test/project/progress/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakobadam/bootstrap-uploadprogress/76aa8344bd914950053788879443a1d2cec5a9f9/test/project/progress/__init__.py
--------------------------------------------------------------------------------
/test/project/progress/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/test/project/progress/apps.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.apps import AppConfig
4 |
5 |
6 | class ProgressConfig(AppConfig):
7 | name = 'progress'
8 |
--------------------------------------------------------------------------------
/test/project/progress/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from models import Package
4 |
5 | def _get_widget(placeholder):
6 | return forms.TextInput(attrs={'placeholder':placeholder})
7 |
8 | class PackageForm(forms.ModelForm):
9 |
10 | class Meta:
11 | exclude = []
12 | model = Package
13 | widgets = {
14 | 'name': _get_widget('Enter package name')
15 | }
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/project/progress/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10.1 on 2016-09-13 16:02
3 | from __future__ import unicode_literals
4 |
5 | import django.core.validators
6 | from django.db import migrations, models
7 | import re
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='Package',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('name', models.CharField(db_index=True, max_length=512, validators=[django.core.validators.RegexValidator(re.compile(b'^[-a-zA-Z0-9_() .]+$'), b'Use ASCII characters only')], verbose_name=b'Software name')),
23 | ('file', models.FileField(upload_to=b'', verbose_name=b'File')),
24 | ],
25 | options={
26 | 'ordering': ('name',),
27 | },
28 | ),
29 | ]
30 |
--------------------------------------------------------------------------------
/test/project/progress/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakobadam/bootstrap-uploadprogress/76aa8344bd914950053788879443a1d2cec5a9f9/test/project/progress/migrations/__init__.py
--------------------------------------------------------------------------------
/test/project/progress/models.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from django.db import models
4 | from django.core.validators import RegexValidator
5 |
6 | RE_PACKAGE_NAME = re.compile(r'^[-a-zA-Z0-9_() .]+$')
7 |
8 | class Package(models.Model):
9 |
10 | class Meta:
11 | ordering = ('name',)
12 |
13 | name = models.CharField(
14 | db_index=True,
15 | max_length=512,
16 | verbose_name='Software name',
17 | validators=[RegexValidator(RE_PACKAGE_NAME, 'Use ASCII characters only')]
18 | )
19 |
20 | file = models.FileField(
21 | verbose_name='File'
22 | )
23 |
--------------------------------------------------------------------------------
/test/project/progress/templates/base.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {% block page_title%}{% endblock %} | {% block site_title%}{% endblock %}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
20 |
21 |
22 | {% block base_head %}{% endblock %}
23 | {% block head %}{% endblock %}
24 |
25 |
26 |
27 |
28 |
29 |
30 | {% for message in messages %}
31 |
35 | {{ message | safe }}
36 |
37 | {% endfor %}
38 |
39 |
40 |
41 | {% block body %}{% endblock %}
42 |
43 |
44 |
45 |
46 |
47 | {% block scripts %}{% endblock %}
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/test/project/progress/templates/package_form.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% load static %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block page_title%}Upload Software Package{% endblock %}
7 |
8 | {% block body %}
9 |
10 |
11 |
{% if object.id %}Update {{object}}{% else %}Upload Package{% endif %}
12 |
13 |
14 |
25 |
26 |
27 |
Cancel
28 |
29 | {% endblock%}
30 |
31 | {% block scripts %}
32 |
33 |
34 |
35 |
41 | {% endblock %}
42 |
--------------------------------------------------------------------------------
/test/project/progress/templates/package_form_modal.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% load static %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block page_title%}Upload Software Package{% endblock %}
7 |
8 | {% block body %}
9 |
10 |
11 |
{% if object.id %}Update {{object}}{% else %}Upload Package{% endif %}
12 |
13 |
Example: form inside modal
14 |
15 |
16 |
17 |
53 |
54 |
55 |
56 |
57 | {% endblock%}
58 |
59 | {% block scripts %}
60 |
61 |
62 |
63 |
77 | {% endblock %}
78 |
--------------------------------------------------------------------------------
/test/project/progress/templates/package_list.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | {% load static %}
3 |
4 | {% block page_title%}Packages{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
Packages
10 |
11 |
12 |
13 |
14 |
15 | Name |
16 | Size |
17 | Actions |
18 |
19 |
20 |
21 | {% for package in packages %}
22 |
23 | {{package.name}} |
24 | {{package.file.size|filesizeformat}} |
25 |
26 |
35 | |
36 |
37 | {% endfor %}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 | {% endblock %}
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/test/project/progress/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/test/project/progress/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | from . import views
4 |
5 | urlpatterns = [
6 | # Examples:
7 | # url(r'^$', 'testprogress.views.home', name='home'),
8 | # url(r'^blog/', include('blog.urls')),
9 |
10 | url(r'^$', views.package_list, name='package_list'),
11 | url(r'^add/$', views.package_add, name='package_add'),
12 | url(r'^edit/(?P\d+)/$', views.package_edit, name='package_edit'),
13 | url(r'^delete/(?P\d+)/$', views.package_delete, name='package_delete'),
14 | ]
15 |
--------------------------------------------------------------------------------
/test/project/progress/views.py:
--------------------------------------------------------------------------------
1 | from django import shortcuts
2 | from django import http
3 |
4 | from django.core.urlresolvers import reverse
5 | from django.views.decorators.http import require_http_methods
6 | from django.contrib import messages
7 |
8 | from .models import Package
9 | from .forms import PackageForm
10 |
11 | def package_list(request):
12 | return shortcuts.render(request, 'package_list.html', {
13 | 'packages': Package.objects.all()
14 | })
15 |
16 | def package_add(request, instance=None):
17 | status = 200
18 | if request.method == 'POST':
19 | form = PackageForm(request.POST, request.FILES, instance=instance)
20 |
21 | if form.is_valid():
22 | instance = form.save()
23 | messages.success(request, u'{} uploaded'.format(instance))
24 | return http.HttpResponseRedirect(reverse('package_list'))
25 | else:
26 | status = 422
27 | else:
28 | form = PackageForm(instance=instance)
29 |
30 | return shortcuts.render(request, 'package_form.html', {
31 | 'form':form
32 | }, status=status)
33 |
34 | def package_edit(request, pk):
35 | package = shortcuts.get_object_or_404(Package, pk=pk)
36 | return package_add(request, instance=package)
37 |
38 | @require_http_methods(['POST'])
39 | def package_delete(request, pk):
40 | package = shortcuts.get_object_or_404(Package, pk=pk)
41 | package.delete()
42 | messages.info(request, 'Deleted {}'.format(package))
43 | return http.HttpResponseRedirect(reverse('package_list'))
44 |
45 |
--------------------------------------------------------------------------------
/test/project/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for progress project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.10.1.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.10/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.10/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = '!#s%vt0m5z801g5#i^^ov(y#y*j&&h04(zg^o(817i-o4t=bk6'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = []
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 |
41 | 'crispy_forms',
42 | 'djangobower',
43 |
44 | 'project.progress'
45 |
46 | ]
47 |
48 |
49 | MIDDLEWARE_CLASSES = [
50 | 'django.middleware.security.SecurityMiddleware',
51 | 'django.contrib.sessions.middleware.SessionMiddleware',
52 | 'django.middleware.common.CommonMiddleware',
53 | 'django.middleware.csrf.CsrfViewMiddleware',
54 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
55 | 'django.contrib.messages.middleware.MessageMiddleware',
56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
57 | ]
58 |
59 | MIDDLEWARE = [
60 | 'django.contrib.sessions.middleware.SessionMiddleware',
61 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
62 | 'django.contrib.messages.middleware.MessageMiddleware',
63 | ]
64 |
65 | ROOT_URLCONF = 'project.urls'
66 |
67 | TEMPLATES = [
68 | {
69 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
70 | 'DIRS': [],
71 | 'APP_DIRS': True,
72 | 'OPTIONS': {
73 | 'context_processors': [
74 | 'django.template.context_processors.debug',
75 | 'django.template.context_processors.request',
76 | 'django.contrib.auth.context_processors.auth',
77 | 'django.contrib.messages.context_processors.messages',
78 | ],
79 | },
80 | },
81 | ]
82 |
83 | WSGI_APPLICATION = 'project.wsgi.application'
84 |
85 |
86 | # Database
87 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
88 |
89 | DATABASES = {
90 | 'default': {
91 | 'ENGINE': 'django.db.backends.sqlite3',
92 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
93 | }
94 | }
95 |
96 |
97 | # Password validation
98 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
99 |
100 | AUTH_PASSWORD_VALIDATORS = [
101 | {
102 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
103 | },
104 | {
105 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
106 | },
107 | {
108 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
109 | },
110 | {
111 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
112 | },
113 | ]
114 |
115 |
116 | # Internationalization
117 | # https://docs.djangoproject.com/en/1.10/topics/i18n/
118 |
119 | LANGUAGE_CODE = 'en-us'
120 |
121 | TIME_ZONE = 'UTC'
122 |
123 | USE_I18N = True
124 |
125 | USE_L10N = True
126 |
127 | USE_TZ = True
128 |
129 |
130 | # Static files (CSS, JavaScript, Images)
131 | # https://docs.djangoproject.com/en/1.10/howto/static-files/
132 |
133 | STATIC_URL = '/static/'
134 |
135 | CRISPY_TEMPLATE_PACK = 'bootstrap3'
136 | BOWER_INSTALLED_APPS = (
137 | 'bootstrap#3.3',
138 | 'html5shiv',
139 | 'respond',
140 | 'bootstrap-filestyle',
141 | # 'bootstrap-uploadprogress' # Use this in production.
142 | )
143 | # For bootstrap-uploadprogress.js
144 | STATICFILES_DIRS = (
145 | "../..",
146 | )
147 |
148 | BOWER_COMPONENTS_ROOT = os.path.join(BASE_DIR, 'components')
149 | MEDIA_ROOT = os.path.join(BASE_DIR, 'upload')
150 |
151 | STATICFILES_FINDERS = (
152 | 'django.contrib.staticfiles.finders.FileSystemFinder',
153 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
154 | 'djangobower.finders.BowerFinder',
155 | )
156 |
--------------------------------------------------------------------------------
/test/project/urls.py:
--------------------------------------------------------------------------------
1 | """progress URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf.urls import url, include
17 | from django.contrib import admin
18 |
19 | urlpatterns = [
20 | url(r'^admin/', admin.site.urls),
21 | url(r'', include('project.progress.urls'))
22 | ]
23 |
--------------------------------------------------------------------------------
/test/project/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for progress 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.10/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", "project.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/test/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==2.2.8
2 | django-bower
3 | django-crispy-forms
4 | six
5 |
--------------------------------------------------------------------------------