From 58e643d2bf124a3322a459ffce60b1ded9c18a1b Mon Sep 17 00:00:00 2001 From: Nikolai Kristiansen Date: Mon, 23 Dec 2013 02:02:09 +0100 Subject: [PATCH] I <3 Django --- .gitignore | 8 + Gruntfile.js | 32 ++++ README.md | 40 ++++ duskenweb/__init__.py | 0 duskenweb/admin.py | 6 + duskenweb/models.py | 1 + duskenweb/settings.py | 117 ++++++++++++ duskenweb/static/config.rb | 10 + duskenweb/static/css/app.css | 78 ++++++++ duskenweb/static/js/application.js | 180 ++++++++++++++++++ duskenweb/static/js/dusken.js | 60 ++++++ duskenweb/static/sass/app.scss | 70 +++++++ duskenweb/templates/404.html | 10 + duskenweb/templates/base.html | 33 ++++ duskenweb/templates/index.html | 32 ++++ duskenweb/templates/profile.html | 14 ++ duskenweb/templates/registration/login.html | 6 + .../templates/registration/login_form.html | 27 +++ duskenweb/tests.py | 3 + duskenweb/urls.py | 33 ++++ duskenweb/views.py | 13 ++ duskenweb/wsgi.py | 14 ++ manage.py | 10 + package.json | 16 ++ requirements.txt | 7 + 25 files changed, 820 insertions(+) create mode 100644 .gitignore create mode 100644 Gruntfile.js create mode 100644 README.md create mode 100644 duskenweb/__init__.py create mode 100644 duskenweb/admin.py create mode 100644 duskenweb/models.py create mode 100644 duskenweb/settings.py create mode 100644 duskenweb/static/config.rb create mode 100644 duskenweb/static/css/app.css create mode 100644 duskenweb/static/js/application.js create mode 100644 duskenweb/static/js/dusken.js create mode 100644 duskenweb/static/sass/app.scss create mode 100644 duskenweb/templates/404.html create mode 100644 duskenweb/templates/base.html create mode 100644 duskenweb/templates/index.html create mode 100644 duskenweb/templates/profile.html create mode 100644 duskenweb/templates/registration/login.html create mode 100644 duskenweb/templates/registration/login_form.html create mode 100644 duskenweb/tests.py create mode 100644 duskenweb/urls.py create mode 100644 duskenweb/views.py create mode 100644 duskenweb/wsgi.py create mode 100644 manage.py create mode 100644 package.json create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ab2623 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.idea/ +*.swp +*.pyc +*.bak +.sass-cache +db.sqlite3 +node_modules +venv diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..accccfc --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,32 @@ +module.exports = function(grunt) { + // load all grunt tasks + require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); + + grunt.initConfig({ + duskenweb: { + // potential config here + }, + compass: { + dev: { + options: { + config: 'duskenweb/static/config.rb', + basePath: 'duskenweb/static/' + } + } + }, + watch: { + sass: { + files: ['duskenweb/static/sass/*.scss'], + tasks: ['compass:dev'], + }, + livereload: { + files: ['duskenweb/templates/**/*.html', 'duskenweb/static/**/*.css', 'duskenweb/static/**/*.js'], + options: { + livereload: true + } + } + } + }); + + grunt.registerTask('default', 'watch'); +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b25a5e --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Installation + + sudo apt-get install python-virtualenv python-dev + virtualenv --distribute venv + . venv/bin/activate + pip install -r requirements.txt + cd duskenweb + cp settings-sample.py settings.py + cd .. + ./manage.py syncdb --all + ./manage.py runserver + + npm install + grunt watch + +# TODO + +* Purchase membership-flow +* https +* cookies: secure, httpOnly + +Client: +* Rewrite client side code in Backbone.js + * Start here: https://github.com/backbone-boilerplate/backbone-boilerplate + * Backbone Extensions: + * https://github.com/amccloud/backbone-tastypie + * https://github.com/marionettejs + * https://github.com/tbranyen/backbone.layoutmanager + * https://github.com/PaulUithol/Backbone-relational + * https://github.com/jeromegn/Backbone.localStorage + * http://wyuenho.github.io/backgrid/ + * Chrome Browser Extension: https://chrome.google.com/webstore/detail/backbone-debugger/bhljhndlimiafopmmhjlgfpnnchjjbhd +* Inline validation + + +# References: + +* Express middleware: https://github.com/senchalabs/connect/wiki +* Reference project: https://github.com/madhums/node-express-mongoose-demo +* Backbone tutorial: http://www.codebeerstartups.com/2012/12/12-listening-to-dom-events-in-backbone-js-learning-backbone-js/ diff --git a/duskenweb/__init__.py b/duskenweb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/duskenweb/admin.py b/duskenweb/admin.py new file mode 100644 index 0000000..914bd7f --- /dev/null +++ b/duskenweb/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin + +from pydusken.models import DuskenAccessToken + +# Register your models here. +admin.site.register(DuskenAccessToken) diff --git a/duskenweb/models.py b/duskenweb/models.py new file mode 100644 index 0000000..137941f --- /dev/null +++ b/duskenweb/models.py @@ -0,0 +1 @@ +from django.db import models diff --git a/duskenweb/settings.py b/duskenweb/settings.py new file mode 100644 index 0000000..ccdc07a --- /dev/null +++ b/duskenweb/settings.py @@ -0,0 +1,117 @@ +""" +Django settings for duskenweb project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.6/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'v_-cub3st=0x3h-fafpz*+jqg+ug78jq7se8xn0&s^b9!8j6t_' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEMPLATE_DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +) +INSTALLED_APPS += ( + 'corsheaders', + 'longerusername', + 'django_extensions', + 'south', + 'pydusken', + # Our app + 'duskenweb', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'corsheaders.middleware.CorsMiddleware', +) + +AUTHENTICATION_BACKENDS = ( + 'pydusken.authentication.DuskenBackend', + 'django.contrib.auth.backends.ModelBackend', +) + +ROOT_URLCONF = 'duskenweb.urls' + +WSGI_APPLICATION = 'duskenweb.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.6/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + # Example PostgreSQL config: + #'ENGINE': 'django.db.backends.postgresql_psycopg2', + #'NAME': 'duskenweb_test', + #'USER': 'postgres', + #'PASSWORD': '', + #'HOST': '127.0.0.1', + #'PORT': '', + } +} + +# Internationalization +# https://docs.djangoproject.com/en/1.6/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Europe/Oslo' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + +STATIC_URL = '/static/' + +LOGIN_REDIRECT_URL = "/profile/" + +DUSKEN_CLIENT_ID = 'd802768a8afd9dec2660' +DUSKEN_CLIENT_SECRET = '3962467fe60a94727812053c8a4f44533f4ef610' + +CORS_ORIGIN_ALLOW_ALL = True +# Allow Ajax calls only from tuple of domain:port +#CORS_ORIGIN_WHITELIST = ( +# '127.0.0.1:3000', +# 'dusken.neuf.no:3000', +# 'dusken.neuf.no', +#) diff --git a/duskenweb/static/config.rb b/duskenweb/static/config.rb new file mode 100644 index 0000000..cca0ba7 --- /dev/null +++ b/duskenweb/static/config.rb @@ -0,0 +1,10 @@ +# Set this to the root of your project when deployed: +http_path = "/" +css_dir = "css" +sass_dir = "sass" +images_dir = "images" +javascripts_dir = "js" + +# output_style = :expanded or :nested or :compact or :compressed +# relative_assets = true +# line_comments = false diff --git a/duskenweb/static/css/app.css b/duskenweb/static/css/app.css new file mode 100644 index 0000000..29e9fa1 --- /dev/null +++ b/duskenweb/static/css/app.css @@ -0,0 +1,78 @@ +/* line 1, ../sass/app.scss */ +.title-header { + margin-bottom: 3em; +} + +/* line 4, ../sass/app.scss */ +.social-login { + text-align: center; +} +/* line 7, ../sass/app.scss */ +.social-login .btn-facebook-login { + width: 250px; + height: 40px; + background-color: #3b5998; + color: white; + font-weight: bold; + text-shadow: 0 -1px black; + font-size: 24px; + padding: 0; +} +/* line 17, ../sass/app.scss */ +.social-login .btn-facebook-login span { + font-size: 16px; + position: relative; + top: -1px; +} +/* line 23, ../sass/app.scss */ +.social-login .btn-facebook-login i { + position: relative; + top: 2px; + padding-right: 6px; +} +/* line 29, ../sass/app.scss */ +.social-login .btn-facebook-login:hover, .social-login .btn-facebook-login:focus { + background-color: #2f477a; + color: white; + outline: 0; +} + +/* line 38, ../sass/app.scss */ +.subtitle { + color: #555; +} + +/* line 41, ../sass/app.scss */ +.seperator { + margin: 1em 1em; + text-align: center; +} +/* line 45, ../sass/app.scss */ +.seperator .text { + padding-left: 4px; + padding-right: 4px; + font-style: italic; +} +/* line 51, ../sass/app.scss */ +.seperator:before { + display: inline-block; + content: ''; + width: 30%; + height: 1px; + background-color: #ccc; + margin-bottom: .25em; +} +/* line 59, ../sass/app.scss */ +.seperator:after { + display: inline-block; + content: ''; + width: 30%; + height: 1px; + background-color: #ccc; + margin-bottom: .25em; +} + +/* line 68, ../sass/app.scss */ +.text-center { + text-align: center; +} diff --git a/duskenweb/static/js/application.js b/duskenweb/static/js/application.js new file mode 100644 index 0000000..2927db1 --- /dev/null +++ b/duskenweb/static/js/application.js @@ -0,0 +1,180 @@ +/* Google+ button language */ +//window.___gcfg = { +// lang: 'no' +//}; +// Ref: https://developers.facebook.com/docs/facebook-login/using-auto-login/ +//window.fbAsyncInit = function() { +// // Initialize the Facebook SDK +// FB.init({ +// appId: '654851471204962', +// xfbml: true, +// status: true, +// cookie: true, +// }); +// +// // Check if the current user is logged in and has authorized the app +// //FB.getLoginStatus(checkLoginStatus); +// +// // Login in the current user via Facebook and ask for email permission +// $(".btn-facebook-login").on('click', function(e) { +// FB.login(checkLoginStatus, {scope:'email, user_birthday'}); +// }); +// +// function login_or_create_member(authResponse) { +// console.log("Facebook:", authResponse); +// // Ref: https://developers.facebook.com/docs/facebook-login/multiple-providers/ +// FB.api('/me', function(response) { +// var data = { +// last_name: response.last_name, +// first_name: response.first_name, +// username: response.username, +// email: response.email, +// facebook_id: response.id, +// date_of_birth: response.birthday +// }; +// /* Check for existing account by looking up email */ +// Dusken.findMember({email: data.email}, function(member) { +// if(member === undefined) { +// /* Create new account */ +// Dusken.register(data, function(response) { +// console.log(response); +// // TODO Hide login form +// $("form").css('opacity', 0.5); +// // login +// // render profile view with data from dusken. +// }); +// } else { +// // TODO what now? +// /* Check for verified email (before merging FB information into Dusken account) */ +// if(response.verified) { +// /* Member exists, authenticate and login */ +// // TODO Hide login form, render profile view with data from dusken. +// $("form").css('opacity', 0.5); +// +// } else { +// /* Send verification email and ask user to check it */ +// // TODO +// } +// } +// }); +// +// }); +// } +// // Check the result of the user status and display login button if necessary +// function checkLoginStatus(response) { +// if(response && response.status == 'connected') { +// console.log('User is authorized'); +// +// // Hide the login button +// //$(".btn-facebook-login").css('opacity', 0.3); +// +// // Now Personalize the User Experience +// // authResponse: +// // - accessToken: make requests to the Facebook APIs on behalf of that user. +// // - userID: the unique identifier for the user who's present in your app. +// //console.log('Access Token: ' + response.authResponse.accessToken); +// // User is logged in to FB and likes our FB app +// login_or_create_member(response.authResponse); +// } else { +// console.log('User is not authorized'); +// +// // Display the login button +// $(".btn-facebook-login").show(); +// } +// } +//}; + +// Load the SDK asynchronously +//(function(d){ +// var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; +// if (d.getElementById(id)) {return;} +// js = d.createElement('script'); js.id = id; js.async = true; +// js.src = "//connect.facebook.net/en_US/all.js"; +// ref.parentNode.insertBefore(js, ref); +//}(document)); + + +/* Google + */ +//function signinCallback(authResult) { +// if (authResult['access_token']) { +// // Update the app to reflect a signed in user +// // Hide the sign-in button now that the user is authorized, for example: +// $("#signinButton").hide(); +// console.log("Google+:", authResult); +// } else if (authResult['error']) { +// // Update the app to reflect a signed out user +// // Possible error values: +// // "user_signed_out" - User is signed-out +// // "access_denied" - User denied access to your app +// // "immediate_failed" - Could not automatically log in the user +// console.log('Sign-in state: ' + authResult['error']); +// } +//} + +/* Ref: http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery */ +$.fn.serializeObject = function() +{ + var o = {}; + var a = this.serializeArray(); + $.each(a, function() { + if (o[this.name]) { + if (!o[this.name].push) { + o[this.name] = [o[this.name]]; + } + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } + }); + return o; +}; + +$(function() { + /* Override options for local dev */ + Dusken.init({ + base_url: "http://127.0.0.1:8000/", + api_base_url: "http://127.0.0.1:8000/api/v1/", + }); + + //}); + /* Ref: + * - https://developers.facebook.com/docs/facebook-login/getting-started-web/ + * - https://developers.facebook.com/docs/facebook-login/checklist/ + * + * Test the following: + * - When someone new to your app logs in with Facebook + * - When someone who has logged in with Facebook in the past logs back in with Facebook + * - When someone cancels log in and then logs back in with Facebook + * - When someone revokes permissions previously granted to your app and then logs back in with Facebook + * - When your token has expired when someone logs in with Facebook + * */ + + //$(".sign-out-google-plus").on('click', function(e) { + // gapi.auth.signOut(); + //}); + /* Register new user */ + $(".btn-register").on('click', function(event) { + event.preventDefault(); + var data = $("form").serializeObject(); + Dusken.register(data, function(response) { + console.log(response); + $("form").html("Vi har sendt deg en epost, trykk på linken i for å fortsette registreringen."); + }, + function(jq_xhr) { + $("form .errors").html('
' +jq_xhr.responseText + '
'); + }); + }); + /* Login existing user */ + //$(".btn-login").on('click', function(event) { + // event.preventDefault(); + // var data = $("form").serializeObject(); + // Dusken.authenticate(data, function(response) { + // console.log(response); + // + // }, + // /* On error */ + // function(jq_xhr) { + // $("form .errors").html('
' +jq_xhr.responseText + '
'); + // }); + //}); +}); diff --git a/duskenweb/static/js/dusken.js b/duskenweb/static/js/dusken.js new file mode 100644 index 0000000..f73a413 --- /dev/null +++ b/duskenweb/static/js/dusken.js @@ -0,0 +1,60 @@ +var Dusken = { + options: { + base_url: "http://duskendev.neuf.no/", + api_base_url: "http://duskendev.neuf.no/api/v1/", + access_token: "", + }, + + _auth_header: function() { + /* http://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication */ + return {"Authorization": "Oauth"+ this.access_token }; + }, + + init: function(options) { + $.extend(true, this.options, options); + return this; + }, + authenticate: function(username, password, callback) { + $.post( + "/authenticate", + {username: username, password: password}, + callback); + return this; + }, + register: function(data, success, error) { + $.ajax({ + url: this.options.api_base_url + "member/register/", + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + dataType: "json", + // FIXME not secure + headers: this._auth_header(), + success: success, + error: error + }); + return this; + }, + getMember: function(member_id, callback) { + $.get( + this.options.api_base_url + "member/" + member_id, + null, + callback); + return this; + }, + findMember: function(data, success, error) { + // FIXME not secure + // FIXME need to use signed requests via serverside, instead of using username:apikey + $.ajax({ + url: this.options.api_base_url + "member/", + type: "GET", + data: data, + contentType: "application/json; charset=utf-8", + dataType: "json", + headers: this._auth_header(), + success: success, + error: error + }); + return this; + } +}; diff --git a/duskenweb/static/sass/app.scss b/duskenweb/static/sass/app.scss new file mode 100644 index 0000000..d6903fe --- /dev/null +++ b/duskenweb/static/sass/app.scss @@ -0,0 +1,70 @@ +.title-header { + margin-bottom: 3em; +} +.social-login { + text-align: center; + + .btn-facebook-login { + width: 250px; + height: 40px; + background-color: #3b5998; + color: white; + font-weight: bold; + text-shadow: 0 -1px black; + font-size: 24px; + padding: 0; + + span { + font-size: 16px; + position: relative; + top: -1px; + } + + i { + position: relative; + top: 2px; + padding-right: 6px; + } + + &:hover, + &:focus { + background-color: #2f477a; + color: white; + outline: 0; + } + + } +} +.subtitle{ + color: #555; +} +.seperator { + margin: 1em 1em; + text-align: center; + + .text { + padding-left: 4px; + padding-right: 4px; + font-style: italic; + } + + &:before { + display: inline-block; + content: ''; + width: 30%; + height: 1px; + background-color: #ccc; + margin-bottom: .25em; + } + &:after { + display: inline-block; + content: ''; + width: 30%; + height: 1px; + background-color: #ccc; + margin-bottom: .25em; + } +} +.text-center { + text-align: center; +} diff --git a/duskenweb/templates/404.html b/duskenweb/templates/404.html new file mode 100644 index 0000000..9a1c60d --- /dev/null +++ b/duskenweb/templates/404.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+

404

+
+
+
+{% endblock %} diff --git a/duskenweb/templates/base.html b/duskenweb/templates/base.html new file mode 100644 index 0000000..8f94e24 --- /dev/null +++ b/duskenweb/templates/base.html @@ -0,0 +1,33 @@ + + + + {{ title }} + + + + + + + + + +
+
+
+
+

D.U.S.K.E.N.

+ Dårlig Utrustet Studentsystem som Kan Endre Norge +
+
+
+
+ + + {% block content %} + {% endblock %} + + + + + + diff --git a/duskenweb/templates/index.html b/duskenweb/templates/index.html new file mode 100644 index 0000000..0bfd987 --- /dev/null +++ b/duskenweb/templates/index.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
Eller
+ +
+ +
+
Allerede medlem? Logg inn
+
+
+
+
+{% endblock %} diff --git a/duskenweb/templates/profile.html b/duskenweb/templates/profile.html new file mode 100644 index 0000000..534487c --- /dev/null +++ b/duskenweb/templates/profile.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% block content %} +
+
+
+

{{user}}

+
    +
  • Username: '{{user.username}}'
  • +
  • Email: '{{user.email}}'
  • +
+
+
+
+{% endblock %} diff --git a/duskenweb/templates/registration/login.html b/duskenweb/templates/registration/login.html new file mode 100644 index 0000000..c9b2cfb --- /dev/null +++ b/duskenweb/templates/registration/login.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% block content %} +
+ {% include "registration/login_form.html" %} +
+{% endblock %} diff --git a/duskenweb/templates/registration/login_form.html b/duskenweb/templates/registration/login_form.html new file mode 100644 index 0000000..c28e58e --- /dev/null +++ b/duskenweb/templates/registration/login_form.html @@ -0,0 +1,27 @@ +
+ {% csrf_token %} + {% if form.errors %} +
{{ form.errors }}
+ {% endif %} + +
+
+

Logg inn med epost og passord

+ +
+ +
+ +
+
+
diff --git a/duskenweb/tests.py b/duskenweb/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/duskenweb/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/duskenweb/urls.py b/duskenweb/urls.py new file mode 100644 index 0000000..ff73a24 --- /dev/null +++ b/duskenweb/urls.py @@ -0,0 +1,33 @@ +from django.conf import settings +from django.conf.urls import patterns, include, url +from django.contrib.auth.forms import SetPasswordForm +from django.contrib import admin + +from longerusername.forms import AuthenticationForm + +admin.autodiscover() + +urlpatterns = patterns('', + url(r'^admin/', include(admin.site.urls)), +) +urlpatterns += patterns('duskenweb.views', + url(r'^$', 'home', name='home'), + url(r'^profile/$', 'profile', name='profile'), +) + +# Authentication views +urlpatterns += patterns('django.contrib.auth.views', + url(r'^login/$', 'login', {'authentication_form': AuthenticationForm}, name='login'), + url(r'^logout/$', 'logout', name='logout'), + url(r'^password/change/$', # skip entering old password + 'password_change', + {'password_change_form': SetPasswordForm}, + name='password_change'), + url(r'^password/change/done/$', 'password_change_done', name='password_change_done'), + url(r'^password/reset/$', 'password_reset', name='password_reset'), + url(r'^password/reset/done$', 'password_reset_done', name='password_reset_done'), + url(r'^password/reset/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', + 'password_reset_confirm', + name='password_reset_confirm'), + url(r'^password/reset/complete/$', 'password_reset_complete', name='password_reset_complete'), +) diff --git a/duskenweb/views.py b/duskenweb/views.py new file mode 100644 index 0000000..c383e70 --- /dev/null +++ b/duskenweb/views.py @@ -0,0 +1,13 @@ +from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required + +# Create your views here. +def home(request): + if request.user.is_authenticated(): + return redirect('profile') + + return render(request, 'index.html') + +@login_required +def profile(request): + return render(request, 'profile.html') diff --git a/duskenweb/wsgi.py b/duskenweb/wsgi.py new file mode 100644 index 0000000..cfe909f --- /dev/null +++ b/duskenweb/wsgi.py @@ -0,0 +1,14 @@ +""" +WSGI config for duskenweb project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "duskenweb.settings") + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..bcafa4d --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "duskenweb.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/package.json b/package.json new file mode 100644 index 0000000..9fb4f35 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "duskenweb", + "version": "0.0.1", + "description": "", + "devDependencies": { + "grunt": "latest", + "grunt-contrib-watch": "latest", + "grunt-contrib-compass": "latest", + "matchdep": "latest" + }, + "repository": { + "type": "git", + "url": "git@git.neuf.no:duskenweb" + }, + "license": "GPL" +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..92abb23 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +Django==1.6.1 +django-extensions==1.2.5 +django-cors-headers==0.12 +psycopg2==2.5.1 +South==0.8.4 +#-e git://git.neuf.no/pydusken.git#egg=pydusken +-e ../pydusken