Browse Source

Not sure why these aren't in master but here we go! (#34)

* Load webpack only in debug.

* Second stab at buildfile.

* Move button.

* Add new line.

* Linting.

* Spelling mistake.

* Clean up.

* Use babel-polyfill.

* Updated Configuration Files for Fresh Install
feature/python-error-tracking
Drew Larson 7 years ago
committed by GitHub
parent
commit
960e107415
  1. 8
      .travis.yml
  2. 2
      bikeshop_project/.flake8
  3. 6
      bikeshop_project/assets/js/components/SignIn.jsx
  4. 5
      bikeshop_project/assets/js/components/SignedInList.jsx
  5. 3
      bikeshop_project/assets/js/members/components/MemberTable/index.jsx
  6. 4
      bikeshop_project/bikeshop/settings/base.py
  7. 20
      bikeshop_project/bikeshop/settings/development.py
  8. 9
      bikeshop_project/bikeshop/settings/production.py
  9. 3
      bikeshop_project/bikeshop/utils/member_import.py
  10. 2
      bikeshop_project/core/admin.py
  11. 2
      bikeshop_project/core/forms.py
  12. 2
      bikeshop_project/core/models.py
  13. 7
      bikeshop_project/core/templates/dashboard.html
  14. 2
      bikeshop_project/core/tests.py
  15. 6
      bikeshop_project/core/views.py
  16. 20
      bikeshop_project/package.json
  17. 2
      bikeshop_project/registration/admin.py
  18. 5
      bikeshop_project/registration/forms.py
  19. 2
      bikeshop_project/registration/serializers.py
  20. 4
      bikeshop_project/registration/tests/test_views.py
  21. 3
      bikeshop_project/registration/views.py
  22. 57
      bikeshop_project/webpack.base.config.js
  23. 62
      bikeshop_project/webpack.dev.config.js
  24. 2
      docker-compose.dev.yml
  25. 1
      requirements/development.txt

8
.travis.yml

@ -4,6 +4,10 @@ services:
before_install: before_install:
- docker build -t bcbc/workstand:production . - docker build -t bcbc/workstand:production .
after_success: after_success:
- bash -c 'echo $TRAVIS_BRANCH'
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"; - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
- docker push bcbc/workstand:production; - export REPO=bcbc/workstand
- export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "production"; else echo $TRAVIS_BRANCH ; fi`
- docker build -f Dockerfile -t $REPO:$COMMIT .
- docker tag $REPO:$COMMIT $REPO:$TAG
- docker tag $REPO:$COMMIT $REPO:travis-$TRAVIS_BUILD_NUMBER
- docker push $REPO

2
bikeshop_project/.flake8

@ -0,0 +1,2 @@
[flake8]
max-line-length = 120

6
bikeshop_project/assets/js/components/SignIn.jsx

@ -1,8 +1,5 @@
import ContentAdd from 'material-ui/svg-icons/content/add';
import fetch from 'isomorphic-fetch'; import fetch from 'isomorphic-fetch';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import moment from 'moment'; import moment from 'moment';
import { polyFill } from 'es6-promise';
import React from 'react'; import React from 'react';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
@ -150,9 +147,6 @@ export default class SignIn extends React.Component {
</div> </div>
<div className="mdl-grid"> <div className="mdl-grid">
<SignedInList members={this.state.signedIn} /> <SignedInList members={this.state.signedIn} />
<FloatingActionButton href="/members/new/">
<ContentAdd />
</FloatingActionButton>
</div> </div>
</div> </div>
); );

5
bikeshop_project/assets/js/components/SignedInList.jsx

@ -1,3 +1,5 @@
import ContentAdd from 'material-ui/svg-icons/content/add';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import _ from 'lodash'; import _ from 'lodash';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'; import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
@ -50,6 +52,9 @@ export default class SignedInList extends React.Component {
return ( return (
<div className="mdl-cell mdl-cell--12-col"> <div className="mdl-cell mdl-cell--12-col">
<h3>Members signed in</h3> <h3>Members signed in</h3>
<FloatingActionButton href="/members/new/">
<ContentAdd />
</FloatingActionButton>
<Table selectable={false}> <Table selectable={false}>
<TableHeader adjustForCheckbox={false} displaySelectAll={false}> <TableHeader adjustForCheckbox={false} displaySelectAll={false}>
<TableRow> <TableRow>

3
bikeshop_project/assets/js/members/components/MemberTable/index.jsx

@ -1,9 +1,8 @@
import React from 'react'; import React from 'react';
import { polyFill } from 'es6-promise';
import fetch from 'isomorphic-fetch'; import fetch from 'isomorphic-fetch';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'; import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
import FlatButton from 'material-ui/FlatButton'; import FlatButton from 'material-ui/FlatButton';
import { Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle } from 'material-ui/Toolbar'; import { Toolbar, ToolbarGroup} from 'material-ui/Toolbar';
import TextField from 'material-ui/TextField'; import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';

4
bikeshop_project/bikeshop/settings/base.py

@ -142,7 +142,7 @@ COMPRESS_PRECOMPILERS = (
WEBPACK_LOADER = { WEBPACK_LOADER = {
'DEFAULT': { 'DEFAULT': {
'CACHE': False, 'CACHE': False,
'BUNDLE_DIR_NAME': 'bundles/', # must end with slash 'BUNDLE_DIR_NAME': 'bundles/', # must end with slash
'STATS_FILE': os.path.join(BASE_DIR, '../webpack-stats.json'), 'STATS_FILE': os.path.join(BASE_DIR, '../webpack-stats.json'),
'POLL_INTERVAL': 0.1, 'POLL_INTERVAL': 0.1,
'IGNORE': ['.+\.hot-update.js', '.+\.map'] 'IGNORE': ['.+\.hot-update.js', '.+\.map']
@ -159,4 +159,4 @@ HAYSTACK_CONNECTIONS = {
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
LOGIN_REDIRECT_URL = 'home' LOGIN_REDIRECT_URL = 'home'
LOGIN_URL = 'login' LOGIN_URL = 'login'

20
bikeshop_project/bikeshop/settings/development.py

@ -1,5 +1,6 @@
import os
import sys import sys
from .base import * from .base import * # noqa
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
@ -10,8 +11,9 @@ DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = []
if 'test' in sys.argv or 'test_coverage' in sys.argv: #Covers regular testing and django-coverage # Covers regular testing and django-coverage
DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3' if 'test' in sys.argv or 'test_coverage' in sys.argv:
DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3' # noqa
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
@ -39,22 +41,16 @@ LOGGING = {
}, },
} }
INSTALLED_APPS += [ INSTALLED_APPS += [ # noqa
'corsheaders', 'corsheaders',
# 'debug_toolbar'
] ]
MIDDLEWARE_CLASSES.insert(0, 'django.middleware.common.CommonMiddleware') MIDDLEWARE_CLASSES.insert(0, 'django.middleware.common.CommonMiddleware') # noqa
# MIDDLEWARE_CLASSES += [ # MIDDLEWARE_CLASSES += [
# 'debug_toolbar.middleware.DebugToolbarMiddleware' # 'debug_toolbar.middleware.DebugToolbarMiddleware'
# ] # ]
# Don't worry about IP addresses, just show the toolbar.
DEBUG_TOOLBAR_CONFIG = {
'SHOW_TOOLBAR_CALLBACK': lambda *args: True
}
CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ['workstand.docker'] ALLOWED_HOSTS = ['workstand.docker','localhost']

9
bikeshop_project/bikeshop/settings/production.py

@ -1,4 +1,5 @@
from .base import * import os
from .base import * # noqa
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
@ -40,9 +41,9 @@ LOGGING = {
WEBPACK_LOADER = { WEBPACK_LOADER = {
'DEFAULT': { 'DEFAULT': {
'CACHE': True, 'CACHE': True,
'BUNDLE_DIR_NAME': 'dist/', # must end with slash 'BUNDLE_DIR_NAME': 'dist/', # must end with slash
'STATS_FILE': os.path.join(BASE_DIR, '../webpack-stats-prod.json'), 'STATS_FILE': os.path.join(BASE_DIR, '../webpack-stats-prod.json'), # noqa
'POLL_INTERVAL': 0.1, 'POLL_INTERVAL': 0.1,
'IGNORE': ['.+\.hot-update.js', '.+\.map'] 'IGNORE': ['.+\.hot-update.js', '.+\.map']
} }
} }

3
bikeshop_project/bikeshop/utils/member_import.py

@ -1,6 +1,4 @@
import csv import csv
import json
import sys
import os import os
import requests import requests
@ -12,7 +10,6 @@ from core.models import Membership, Payment
from registration.models import Member from registration.models import Member
def email_generator(): def email_generator():
url = 'http://randomword.setgetgo.com/get.php' url = 'http://randomword.setgetgo.com/get.php'
local = [] local = []

2
bikeshop_project/core/admin.py

@ -6,6 +6,6 @@ admin.site.register([Membership, Payment])
@admin.register(Visit) @admin.register(Visit)
class VistAdmin(admin.ModelAdmin): class VisitAdmin(admin.ModelAdmin):
ordering = ('created_at',) ordering = ('created_at',)
list_display = ('member', 'purpose', 'created_at') list_display = ('member', 'purpose', 'created_at')

2
bikeshop_project/core/forms.py

@ -1,5 +1,5 @@
import logging import logging
from django.forms import BooleanField, CharField, CheckboxInput, RadioSelect, ModelForm, TextInput, HiddenInput, ChoiceField from django.forms import BooleanField, CharField, CheckboxInput, RadioSelect, ModelForm, TextInput, HiddenInput
from registration.models import Member from registration.models import Member

2
bikeshop_project/core/models.py

@ -62,7 +62,7 @@ class Visit(models.Model):
(DONATE, 'donate'), (DONATE, 'donate'),
(STAFF, 'staff'), (STAFF, 'staff'),
) )
member = models.ForeignKey( member = models.ForeignKey(
'registration.Member', 'registration.Member',
on_delete=models.CASCADE on_delete=models.CASCADE

7
bikeshop_project/core/templates/dashboard.html

@ -58,3 +58,10 @@
<div id="root"></div> <div id="root"></div>
{% render_bundle 'signin' %} {% render_bundle 'signin' %}
{% endblock %} {% endblock %}
{% block scripts %}
{% render_bundle 'babelPolyfill' %}
{% if DEBUG %}
{% render_bundle 'webpack' %}
{% endif %}
{% endblock %}

2
bikeshop_project/core/tests.py

@ -1,3 +1 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

6
bikeshop_project/core/views.py

@ -1,5 +1,6 @@
import logging import logging
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
@ -18,13 +19,14 @@ logger = logging.getLogger(__name__)
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class DashboardView(View): class DashboardView(View):
def get(self, request): def get(self, request):
return TemplateResponse(request, 'dashboard.html') return TemplateResponse(request, 'dashboard.html', context={'DEBUG': settings.DEBUG})
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class NewMembershipView(TemplateView): class NewMembershipView(TemplateView):
template_name = 'membership_form.html' template_name = 'membership_form.html'
def get(self, request, member_id): def get(self, request, member_id, **kwargs):
membership_form = MembershipForm(initial=dict(member=member_id)) membership_form = MembershipForm(initial=dict(member=member_id))
payment_form = PaymentForm() payment_form = PaymentForm()
return self.render_to_response(dict(membership_form=membership_form, payment_form=payment_form)) return self.render_to_response(dict(membership_form=membership_form, payment_form=payment_form))

20
bikeshop_project/package.json

@ -4,14 +4,13 @@
"description": "A membership management app for the BCBC.", "description": "A membership management app for the BCBC.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.js --progress --colors", "build": "node_modules/.bin/webpack --config webpack.config.js --progress --colors",
"build-production": "node_modules/.bin/webpack --config webpack.prod.config.js --progress --colors", "build-production": "node_modules/.bin/webpack --config webpack.prod.config.js --progress --colors",
"watch": "node server.js" "watch": "node server.js"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"es6-promise": "^3.2.1",
"isomorphic-fetch": "^2.2.1", "isomorphic-fetch": "^2.2.1",
"material-ui": "^0.16.6", "material-ui": "^0.16.6",
"moment": "^2.13.0", "moment": "^2.13.0",
@ -25,10 +24,15 @@
"babel": "^6.5.2", "babel": "^6.5.2",
"babel-core": "^6.9.1", "babel-core": "^6.9.1",
"babel-loader": "^6.2.4", "babel-loader": "^6.2.4",
"babel-polyfill": "^6.22.0",
"babel-preset-es2015": "^6.9.0", "babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0", "babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0", "babel-preset-stage-0": "^6.5.0",
"css-loader": "^0.23.1", "css-loader": "^0.23.1",
"eslint": "^3.9.1",
"eslint-plugin-import": "^2.1.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.6.0",
"extract-text-webpack-plugin": "^1.0.1", "extract-text-webpack-plugin": "^1.0.1",
"i": "^0.3.5", "i": "^0.3.5",
"node-sass": "^3.4.2", "node-sass": "^3.4.2",
@ -40,10 +44,6 @@
"sass-loader": "^3.2.0", "sass-loader": "^3.2.0",
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"toolbox-loader": "0.0.3", "toolbox-loader": "0.0.3",
"webpack-dev-server": "^1.14.1", "webpack-dev-server": "^1.14.1"
"eslint": "^3.9.1",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-import": "^2.1.0",
"eslint-plugin-react": "^6.6.0"
} }
} }

2
bikeshop_project/registration/admin.py

@ -35,4 +35,4 @@ class CustomUserAdmin(UserAdmin):
class MemberAdmin(admin.ModelAdmin): class MemberAdmin(admin.ModelAdmin):
list_display = ('get_full_name',) list_display = ('get_full_name',)
ordering = ('last_name',) ordering = ('last_name',)
search_fields = ('email', 'first_name', 'last_name') search_fields = ('email', 'first_name', 'last_name')

5
bikeshop_project/registration/forms.py

@ -1,10 +1,11 @@
from django.forms import ModelForm, EmailInput, TextInput, DateInput, CheckboxSelectMultiple, CharField, CheckboxInput, BooleanField from django.forms import ModelForm, EmailInput, TextInput, DateInput, CheckboxInput, BooleanField
from django.utils import timezone from django.utils import timezone
from registration.models import Member from registration.models import Member
class MemberForm(ModelForm): class MemberForm(ModelForm):
waiver_substitute = BooleanField(required=False, label='I have read and agree to the above terms & conditions.', widget=CheckboxInput(attrs={'class': 'mdl-checkbox__input'})) waiver_substitute = BooleanField(required=False, label='I have read and agree to the above terms & conditions.',
widget=CheckboxInput(attrs={'class': 'mdl-checkbox__input'}))
class Meta: class Meta:
model = Member model = Member

2
bikeshop_project/registration/serializers.py

@ -10,4 +10,4 @@ class MemberSerializer(ModelSerializer):
class Meta: class Meta:
model = Member model = Member
fields = ('first_name', 'last_name', 'email', 'id') fields = ('first_name', 'last_name', 'email', 'id')

4
bikeshop_project/registration/tests/test_views.py

@ -8,10 +8,8 @@ from django.test import Client, TestCase
from core.models import Visit from core.models import Visit
from model_mommy import mommy from model_mommy import mommy
from copy import copy
from ..models import CustomUser, Member from ..models import CustomUser, Member
from ..views import MemberFormView
logger = logging.getLogger('bikeshop') logger = logging.getLogger('bikeshop')
@ -37,7 +35,7 @@ class TestMemberFormView(TestCase):
'last_name': 'Last', 'last_name': 'Last',
'post_code': 'H0H0H0', 'post_code': 'H0H0H0',
} }
response = c.post(url, data=member_data) c.post(url, data=member_data)
new_member = Member.objects.get(first_name='First', last_name='Last') new_member = Member.objects.get(first_name='First', last_name='Last')
self.assertTrue(new_member) self.assertTrue(new_member)

3
bikeshop_project/registration/views.py

@ -58,7 +58,8 @@ class MemberFormView(View):
class MemberSearchView(View): class MemberSearchView(View):
def get(self, request, query): def get(self, request, query):
sqs = SearchQuerySet().models(Member).autocomplete(text=query)[:5] sqs = SearchQuerySet().models(Member).autocomplete(text=query)[:5]
results = [dict(name=result.object.get_full_name(), email=result.object.email, id=result.object.id) for result in sqs] results = [dict(name=result.object.get_full_name(), email=result.object.email, id=result.object.id)
for result in sqs]
data = json.dumps(dict(results=results)) data = json.dumps(dict(results=results))

57
bikeshop_project/webpack.base.config.js

@ -1,38 +1,35 @@
var path = require("path") const path = require('path');
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
const autoprefixer = require('autoprefixer'); const autoprefixer = require('autoprefixer');
require('babel-polyfill');
module.exports = { module.exports = {
context: __dirname, context: __dirname,
entry: {
signin: './assets/js/index',
members: './assets/js/members/index',
babelPolyfill: 'babel-polyfill',
},
entry: { output: {
signin: './assets/js/index', path: path.resolve('./assets/bundles/'),
members: './assets/js/members/index', filename: '[name]-[hash].js',
}, },
output: { plugins: [
path: path.resolve('./assets/bundles/'),
filename: "[name]-[hash].js"
},
plugins: [ ], // add all common plugins here
], // add all common plugins here
module: { module: {
loaders: [ loaders: [],
},
]
},
resolve: { resolve: {
modulesDirectories: [ modulesDirectories: [
'node_modules', 'node_modules',
'bower_components' 'bower_components',
], ],
extensions: ['', '.js', '.jsx', '.scss'] extensions: ['', '.js', '.jsx', '.scss'],
}, },
postcss: [autoprefixer] postcss: [autoprefixer],
} };

62
bikeshop_project/webpack.dev.config.js

@ -1,45 +1,47 @@
var path = require("path") const webpack = require('webpack');
var webpack = require('webpack') const BundleTracker = require('webpack-bundle-tracker');
var BundleTracker = require('webpack-bundle-tracker')
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin');
require('babel-polyfill');
var config = require('./webpack.base.config.js')
const config = require('./webpack.base.config.js');
// Use webpack dev server // Use webpack dev server
config.entry = { config.entry = {
webpack: [ webpack: [
'webpack-dev-server/client?http://webpack.docker:3000', 'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server', 'webpack/hot/only-dev-server',
], ],
signin: './assets/js/index', signin: './assets/js/index',
members: './assets/js/members/index', members: './assets/js/members/index',
} babelPolyfill: 'babel-polyfill',
};
// override django's STATIC_URL for webpack bundles // override django's STATIC_URL for webpack bundles
config.output.publicPath = 'http://webpack.docker:3000/assets/bundles/' config.output.publicPath = 'http://localhost:3000/assets/bundles/';
config.devtool = 'eval-source-map'; config.devtool = 'eval-source-map';
// Add HotModuleReplacementPlugin and BundleTracker plugins // Add HotModuleReplacementPlugin and BundleTracker plugins
config.plugins = config.plugins.concat([ config.plugins = config.plugins.concat([
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(), new webpack.NoErrorsPlugin(),
new BundleTracker({filename: './webpack-stats.json'}), new BundleTracker({ filename: './webpack-stats.json' }),
new ExtractTextPlugin('react-toolbox.css', {allChunks: true}), new ExtractTextPlugin('react-toolbox.css', { allChunks: true }),
]) ]);
// Add a loader for JSX files with react-hot enabled // Add a loader for JSX files with react-hot enabled
config.module.loaders.push( config.module.loaders.push(
{ {
test: /\.jsx?$/, test: /\.jsx?$/,
exclude: /node_modules/, exclude: /node_modules/,
loaders: ['react-hot','babel-loader'] loaders: ['react-hot', 'babel-loader'],
}, },
{ {
test: /(\.scss|\.css)$/, test: /(\.scss|\.css)$/,
loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass?sourceMap!toolbox') loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass?sourceMap!toolbox'),
} }
) );
module.exports = config module.exports = config;

2
docker-compose.dev.yml

@ -9,7 +9,7 @@ services:
- "8000:8000" - "8000:8000"
- "62260:62260" - "62260:62260"
volumes: volumes:
- ./bikeshop_project:/code - ./bikeshop_project:/code:rw
redis: redis:
restart: always restart: always
db: db:

1
requirements/development.txt

@ -2,3 +2,4 @@
-r testing.txt -r testing.txt
django-debug-toolbar django-debug-toolbar
django-cors-headers django-cors-headers
flake8

Loading…
Cancel
Save