forked from caseysoftware/eventgrinder
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ross M Karchner
committed
Apr 18, 2011
0 parents
commit 14281ba
Showing
1,611 changed files
with
219,161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
*.pyc | ||
bin/ | ||
.svn | ||
.hg/ | ||
.hgignore | ||
.installed.cfg | ||
bin/ | ||
eggs/ | ||
etc/ | ||
var/ | ||
*.svn | ||
.DS_Store | ||
|
||
# Compiled source # | ||
################### | ||
*.com | ||
*.class | ||
*.dll | ||
*.exe | ||
*.o | ||
*.so | ||
|
||
# Packages # | ||
############ | ||
# it's better to unpack these files and commit the raw source | ||
# git has its own built in compression methods | ||
*.7z | ||
*.dmg | ||
*.gz | ||
*.iso | ||
*.jar | ||
*.rar | ||
*.tar | ||
*.zip | ||
|
||
# Logs and databases # | ||
###################### | ||
*.log | ||
*.sql | ||
*.sqlite | ||
|
||
# OS generated files # | ||
###################### | ||
.DS_Store? | ||
ehthumbs.db | ||
Icon? | ||
Thumbs.db |
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from django import forms | ||
from django.forms.util import ErrorList | ||
from django.template.defaultfilters import slugify | ||
|
||
from google.appengine.api.users import get_current_user | ||
from account.utility import profile_required, get_current_profile | ||
|
||
from models import Profile | ||
from eventsite import get_site | ||
|
||
from html5.forms import URLInput, DateInput, TextInput, EmailInput | ||
|
||
|
||
|
||
class ProfileForm(forms.Form): | ||
nickname = forms.CharField(max_length=255, help_text="What you want to be known as on the site") | ||
email=forms.EmailField(required=True, help_text="Where should we send email?", widget=EmailInput) | ||
subscribe = forms.BooleanField(required=False, help_text="Do you want to get the weekly events email?") | ||
link=forms.URLField(required=False, help_text="This can be the URL of your blog, twitter page, LinkedIn profile, homepage, or anything else.", | ||
widget=TextInput(attrs={'placeholder':'http://whatever'})) | ||
|
||
def clean(self): | ||
site=get_site() | ||
cleaned_data = self.cleaned_data | ||
nickname = cleaned_data.get("nickname") | ||
email = cleaned_data.get("email") | ||
profile=get_current_profile() | ||
existing_profile_with_slug=site.profile_set.filter('slug =', unicode(slugify(nickname))).get() | ||
existing_profile_with_email=site.profile_set.filter('email =', email).get() | ||
if (existing_profile_with_slug != None and existing_profile_with_slug.key() != profile.key()): | ||
msg = u"Someone else already took that nickname!" | ||
self._errors["nickname"] = ErrorList([msg]) | ||
del cleaned_data['nickname'] | ||
if (existing_profile_with_email != None and existing_profile_with_email.key() != profile.key()): | ||
msg = u"Someone has already registered with that email" | ||
self._errors["email"] = ErrorList([msg]) | ||
del cleaned_data['email'] | ||
|
||
return super(ProfileForm, self).clean() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from google.appengine.ext import db | ||
from aetycoon import DerivedProperty | ||
|
||
from eventsite.models import Eventsite | ||
|
||
# import code for encoding urls and generating md5 hashes | ||
import urllib, hashlib, os | ||
|
||
|
||
class Profile(db.Model): | ||
nickname=db.StringProperty(required=False, indexed=False) | ||
link=db.LinkProperty(required=False, indexed=False) | ||
email=db.EmailProperty(required=False) | ||
slug=db.StringProperty(required=False) | ||
site=db.ReferenceProperty(Eventsite) | ||
user=db.UserProperty() | ||
confirmed_at=db.DateTimeProperty(required=False) | ||
# Verification stuff | ||
verified_at=db.DateTimeProperty(required=False) | ||
# Permission stuff | ||
userlevel=db.IntegerProperty(required=True, default=0) | ||
subscribes=db.BooleanProperty(required=False, default=0) | ||
|
||
def verify_email(self,email): | ||
key_string= email+ str(datetime.now()) | ||
md5=hashlib.md5() | ||
md5.update(key_string) | ||
verification=PendingVerification(parent=self, proposed_email=email, code=md5.hexdigest()) | ||
|
||
@property | ||
def is_editor(self): | ||
return (self.userlevel > 9) | ||
|
||
|
||
|
||
@property | ||
def profile_details(self): | ||
return{'nickname': self.nickname, | ||
'email': self.email or self.user.email, | ||
'subscribes':self.subscribes or False} | ||
|
||
@property | ||
def gravatar(self): | ||
size=15 | ||
gravatar = "http://www.gravatar.com/avatar.php?" | ||
gravatar += urllib.urlencode({'gravatar_id':hashlib.md5(self.email).hexdigest(), 'size':str(size), 'd':'monsterid'}) | ||
return gravatar | ||
|
||
|
||
def slugify(value): | ||
""" | ||
Normalizes string, converts to lowercase, removes non-alpha characters, | ||
and converts spaces to hyphens. | ||
Borrowed from Django, while trying to decouple my models from Django itself | ||
""" | ||
import unicodedata | ||
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') | ||
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) | ||
return unicode(re.sub('[-\s]+', '-', value)) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from django import template | ||
from account.utility import get_current_user, create_logout_url | ||
from google.appengine.api import users | ||
|
||
|
||
|
||
register = template.Library() | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from django.conf.urls.defaults import * | ||
|
||
|
||
urlpatterns = patterns('account', | ||
url(r'^signout/$', 'views.signout', name="account-signout"), | ||
url(r'^profile-setup', 'views.profile_setup', name='profile-setup'), | ||
url(r'^$', 'views.edit_profile', name="account-edit"), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import logging, os | ||
|
||
from google.appengine.api import users | ||
from google.appengine.api.users import get_current_user, create_login_url | ||
from google.appengine.ext.db import Query | ||
|
||
from django.http import HttpResponse, HttpResponseRedirect | ||
from django.shortcuts import render_to_response, redirect | ||
from django.core.urlresolvers import reverse | ||
from django.contrib import messages | ||
|
||
#from messaging import notice | ||
|
||
from eventsite import get_site, site_required | ||
|
||
from models import Profile | ||
|
||
|
||
|
||
def get_current_profile(): | ||
site=get_site() | ||
user=get_current_user() | ||
if not site: return None | ||
if not user: return None | ||
profile=Profile.get_or_insert(site.slug+user.user_id(), user=user, site=site, subscribes=False) | ||
return profile | ||
|
||
def create_signin_url(dest='/'): | ||
return reverse('account-signin')+'?continue='+dest | ||
|
||
|
||
def create_profile_confirm_url(dest='/'): | ||
return reverse('profile-setup')+'?continue='+dest | ||
|
||
|
||
|
||
|
||
def profile_required(func): | ||
def replacement_view(request, *args, **kwargs): | ||
site=get_site() | ||
|
||
user=get_current_user() | ||
if user and not site: | ||
return func(request, *args, **kwargs) | ||
|
||
if not user: | ||
return redirect(create_signin_url(request.get_full_path())) | ||
|
||
profile=get_current_profile() | ||
if not profile.confirmed_at: | ||
return redirect(create_profile_confirm_url(request.get_full_path())) | ||
request.site= site | ||
request.profile=profile | ||
return func(request, *args, **kwargs) | ||
|
||
return site_required(replacement_view) | ||
|
||
|
||
def admin_required(func): | ||
def replacement_view(request, *args, **kwargs): | ||
g_user=users.get_current_user() | ||
if not users.is_current_user_admin(): | ||
|
||
return redirect(create_signin_url(dest=request.get_full_path())) | ||
|
||
|
||
return func(request, *args, **kwargs) | ||
|
||
return profile_required(replacement_view) | ||
|
||
def userlevel_required(level): | ||
def replacement_decorator(func): | ||
def replacement_view(request, *args, **kwargs): | ||
profile=get_current_profile() | ||
if not (users.is_current_user_admin() or profile.userlevel >= level): | ||
messages.add_message(request, messages.INFO,"You don't have access to that page") | ||
return HttpResponseRedirect('/') | ||
|
||
|
||
|
||
return func(request, *args, **kwargs) | ||
|
||
return profile_required(replacement_view) | ||
return replacement_decorator | ||
|
||
def create_logout_url(dest): | ||
return aeoid.users.create_logout_url(dest) | ||
|
||
|
||
|
||
def profile_for_user(user, keys_only=False): | ||
q=Query(Profile, keys_only=keys_only).filter('user =', user) | ||
return q.fetch(1)[0] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from django.shortcuts import render_to_response | ||
from django.http import HttpResponse, HttpResponseRedirect | ||
from google.appengine.api import users | ||
from django.core.urlresolvers import reverse | ||
from django.template import RequestContext | ||
from django.template.defaultfilters import slugify, striptags | ||
from django.contrib import messages | ||
|
||
from google.appengine.api.users import get_current_user, create_login_url | ||
from google.appengine.api.labs import taskqueue | ||
|
||
from account.utility import get_current_user, profile_required, get_current_profile | ||
from account.forms import ProfileForm | ||
from account.models import Profile | ||
|
||
from eventsite import site_required, get_site | ||
#from messaging import notice | ||
|
||
|
||
import os | ||
from datetime import datetime | ||
|
||
@site_required | ||
def signin(request): | ||
if request.method=='POST': | ||
dest_url=request.POST.get('continue') | ||
federated_identity=request.POST.get('openid_url') | ||
|
||
login_url=create_login_url(dest_url=dest_url, federated_identity=federated_identity) | ||
return HttpResponseRedirect(login_url) | ||
|
||
else: | ||
dest=request.GET.get('continue', reverse('front-page')) | ||
google_login_url=create_login_url(dest_url=dest, federated_identity="https://www.google.com/accounts/o8/id") | ||
yahoo_login_url=create_login_url(dest_url=dest, federated_identity="http://yahoo.com/") | ||
return(render_to_response('account/signin.html', locals(), context_instance=RequestContext(request))) | ||
|
||
|
||
|
||
def signout(request): | ||
messages.add_message(request, messages.INFO,"You've signed out. Come back any time!") | ||
return HttpResponseRedirect('/') | ||
|
||
|
||
|
||
def save_profile(profile, form): | ||
nickname=striptags(form.cleaned_data['nickname'].strip()) | ||
profile.nickname=nickname | ||
profile.email= form.cleaned_data['email'].strip() | ||
profile.slug=unicode(slugify(nickname)) | ||
profile.confirmed_at=datetime.now() | ||
profile.link=form.cleaned_data['link'] or None | ||
profile.subscribes=form.cleaned_data['subscribe'] | ||
profile.put() | ||
if profile.subscribes: | ||
site=get_site() | ||
chimp=site.chimp | ||
taskqueue.add(url='/subscriptions/subscribe_email/', | ||
params={'apikey': chimp.apikey, | ||
'list_id': chimp.listid, | ||
'email': form.cleaned_data['email']}) | ||
|
||
|
||
|
||
@profile_required | ||
def edit_profile(request): | ||
profile=get_current_profile() | ||
if request.method == 'POST': # If the form has been submitted... | ||
form = ProfileForm(request.POST) # A form bound to the POST data | ||
if form.is_valid(): # All validation rules pass | ||
save_profile(profile, form) | ||
messages.add_message(request, messages.INFO,"Your profile has been saved!") | ||
return HttpResponseRedirect('/') # Redirect after POST | ||
|
||
|
||
|
||
current_settings={'nickname':profile.nickname, | ||
'email': profile.email, | ||
'subscribe':profile.subscribes, | ||
'link': profile.link} | ||
|
||
form=ProfileForm(current_settings) | ||
return(render_to_response('account/edit.html', locals(), context_instance=RequestContext(request))) | ||
|
||
def view_profile(request): | ||
return HttpResponse("not implemented") | ||
|
||
|
||
|
||
@site_required | ||
def profile_setup(request): | ||
hostname=os.environ['HTTP_HOST'] | ||
dest=request.GET.get('continue', reverse('front-page')) | ||
user=get_current_user() | ||
profile=get_current_profile() | ||
|
||
if not profile: | ||
return HttpResponseRedirect(create_signin_url(reverse('account-edit'))) | ||
|
||
if request.method == 'POST': # If the form has been submitted... | ||
form = ProfileForm(request.POST) # A form bound to the POST data | ||
if form.is_valid(): # All validation rules pass | ||
save_profile(profile, form) | ||
return HttpResponseRedirect(dest) # Redirect after POST | ||
else: | ||
form = ProfileForm(initial=profile.profile_details) | ||
|
||
return(render_to_response('account/profile-setup.html', locals(), context_instance=RequestContext(request))) |
Submodule aetycoon
added at
8978d4
Oops, something went wrong.