Skip to content

Commit

Permalink
ported links functionality to Django, prep'ed app for new billing rul…
Browse files Browse the repository at this point in the history
…es and python2.7
  • Loading branch information
Ross Karchner committed Nov 8, 2011
1 parent 15a2b62 commit a9987ef
Show file tree
Hide file tree
Showing 31 changed files with 221 additions and 237 deletions.
1 change: 0 additions & 1 deletion account/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
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'}))

Expand Down
1 change: 0 additions & 1 deletion account/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ def save_profile(profile, form):
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()
Expand Down
19 changes: 13 additions & 6 deletions app.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
application: techevents
version: cleanup
runtime: python
application: eventgrinder2
version: cleanup2
runtime: python27
api_version: 1
threadsafe: true

libraries:
- name: PIL
version: "1.1.7"
- name: django
version: "1.2"

handlers:


handlers:
- url: /static/([^/]*)/(.*)
static_files: static/\2
upload: static/(.*)
expiration: "24d"

- url: /tasks.*
script: main.py
script: main.application
login: admin

- url: .*
script: main.py
script: main.application

builtins:
- datastore_admin: on
5 changes: 1 addition & 4 deletions appengine_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
import os


os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')


sys.path= [os.path.join(os.path.dirname(__file__), 'shared'), os.path.join(os.path.dirname(__file__), '.')]+sys.path



Expand Down
1 change: 0 additions & 1 deletion events/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import datetime
from google.appengine.ext import db
from google.appengine.api import users
from sources.models import ICalendarSource
from eventsite.models import Eventsite
from account.models import Profile
from utility import slugify
Expand Down
2 changes: 1 addition & 1 deletion eventsite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_site(key_name=None):
def site_required(func):
def no_site(request, *args, **kwargs):
if not request.site:
return HttpResponse("No calendar with that name exists (yet!)")
return HttpResponseRedirect("/admin/create/")
else:
return HttpResponse("%s will return soon!" % request.site.name)

Expand Down
10 changes: 3 additions & 7 deletions eventsite/admin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@
class SiteCreateForm(forms.Form):
name = forms.CharField(max_length=255, required=True)
timezone=forms.ChoiceField(choices=timezones)
slug=forms.CharField(max_length=255, required=True)
audience=forms.CharField(max_length=255, required=True)



class SiteDetailsForm(forms.Form):
name = forms.CharField(max_length=255, required=True)
timezone=forms.ChoiceField(choices=timezones)
audience=forms.CharField(max_length=255, required=True)
google_analytics_code=forms.CharField(max_length=255, required=False)
google_site_verification=forms.CharField(max_length=255, required=False)
twitter=forms.CharField(max_length=255, required=False)
bsa_code=forms.CharField(max_length=255, required=False, widget=forms.Textarea)
offline=forms.BooleanField(required=False)
hostnames=forms.CharField(max_length=255, required=False)



def clean_hostnames(self):
Expand Down
10 changes: 2 additions & 8 deletions eventsite/admin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ def create_site(request):
if form.is_valid():
new_site=models.Eventsite(name=form.cleaned_data['name'].strip(),
timezone= form.cleaned_data['timezone'].strip(),
audience=form.cleaned_data['audience'].strip(),
hostnames=[hostname,],
key_name=hostname,
slug=form.cleaned_data['slug'])
slug=str(slugify(hostname)))
new_site.put()
return HttpResponseRedirect(reverse('admin-home'))
return render_to_response('eventsite/admin.html', locals(), context_instance=RequestContext(request))
Expand All @@ -66,12 +65,7 @@ def edit_site(request):
if form.is_valid(): # All validation rules pass
site.name=form.cleaned_data['name'].strip()
site.timezone= form.cleaned_data['timezone'].strip()
site.audience=form.cleaned_data['audience'].strip()
site.hostnames=form.cleaned_data['hostnames']
site.google_site_verification=form.cleaned_data['google_site_verification'].strip()
site.google_analytics_code=form.cleaned_data['google_analytics_code'].strip()
site.twitter=form.cleaned_data['twitter'] or None
site.bsa_code=form.cleaned_data['bsa_code'] or None
site.offline=form.cleaned_data['offline'] or None
site.put()
site.expire_assets()
Expand All @@ -81,7 +75,7 @@ def edit_site(request):
site=get_site()
if site:
site_details={'name':site.name, 'timezone':site.timezone, 'slug':site.slug,
'audience': site.audience, 'hostnames':",".join(site.hostnames),
'hostnames':",".join(site.hostnames),
'google_analytics_code':site.google_analytics_code,
'google_site_verification':site.google_site_verification,
'twitter':site.twitter,
Expand Down
1 change: 0 additions & 1 deletion eventsite/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class Eventsite(db.Model):
original_logo_version=db.IntegerProperty()
logo=db.BlobProperty()
logo_asset_href=db.StringProperty()
audience=db.TextProperty(required=False)
google_analytics_code=db.TextProperty(required=False)
google_site_verification=db.TextProperty(required=False)
disqus_shortname=db.TextProperty(required=False)
Expand Down
1 change: 0 additions & 1 deletion eventsite/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ def this_week_rss(request):



@cache_page(60 * 10)
@site_required
def front_page(request, tag=None):
start=request.site.today
Expand Down
39 changes: 5 additions & 34 deletions links/forms.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,13 @@
from datetime import date
import logging

from tipfy import RequestHandler, Response, redirect, cached_property
from tipfy.ext.jinja2 import Jinja2Mixin
from tipfy.ext.wtforms import Form, fields, validators, widgets
from tipfy.ext.wtforms.validators import ValidationError

from tipfy.ext.db import populate_entity

from wtforms.ext.dateutil.fields import DateField


from pytz.gae import pytz


# a set of HTML5 widgets for wtforms

from wtforms.widgets import Input

REQUIRED = validators.required()
from django import forms
from models import Link



class LinkWidget(Input):
def __init__(self, input_type='url'):
if input_type is not None:
self.input_type = input_type




class AddLinkForm(Form):
name = fields.TextField('Site Name', validators=[REQUIRED])
href=fields.TextField('URL', validators=[validators.URL(), REQUIRED], widget=LinkWidget())
class AddLinkForm(forms.Form):
name = forms.CharField(max_length=500)
href=forms.URLField()

def save(self):
new_link=Link(**self.data)
new_link=Link(**self.cleaned_data)
new_link.status='submitted'
new_link.put()

Expand Down
2 changes: 1 addition & 1 deletion links/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
urlpatterns = patterns('links.views',

url(r'^add/$','add', name="add_link"),
# url(r'^review/$','review', name="review_links"),
url(r'^review/$','review', name="review_links"),
# url(r'^change/$','add', name="change_link"),


Expand Down
29 changes: 26 additions & 3 deletions links/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,34 @@
from django.template import RequestContext
from django.contrib import messages

from account.utility import get_current_user, profile_required, get_current_profile
from account.utility import get_current_user, profile_required, get_current_profile, admin_required

from eventsite import site_required

from forms import AddLinkForm
from models import Link

@site_required
def add(request):
return(render_to_response('links/add.html', locals(), context_instance=RequestContext(request)))
if request.method == 'POST':
form=AddLinkForm(request.POST)
if form.is_valid():
form.save()
messages.add_message(request, messages.INFO, "Thank you for submitting a link!")
return redirect('/')


else:
form=AddLinkForm()
return(render_to_response('links/add.html', locals(), context_instance=RequestContext(request)))


@admin_required
def review(request):
if request.method=='POST':
link=Link.get_by_id(int(request.POST['id']))
link.status=request.POST['action']
link.put()

approved_links=Link.all().filter('status =', 'approved')
submitted_links=Link.all().filter('status =', 'submitted')
return(render_to_response('links/review.html', locals(), context_instance=RequestContext(request)))
11 changes: 1 addition & 10 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
# Django imports and other code go here...
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')


import django.core.handlers, django.core.handlers.wsgi

Expand All @@ -20,10 +17,4 @@



def main():
sys.path= [os.path.join(os.path.dirname(__file__), 'shared'), os.path.join(os.path.dirname(__file__), '.')]+sys.path
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)

if __name__ == '__main__':
main()
application = django.core.handlers.wsgi.WSGIHandler()
4 changes: 1 addition & 3 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#What is this crazy thing?

This is the current, production version of "Eventgrinder"-- which runs some calendar aggregator sites, like dctechevents.com
This is a "cleanup" branch of "Eventgrinder"-- which runs some calendar aggregator sites, like dctechevents.com

#Whatgrinder?

Expand All @@ -13,8 +13,6 @@ Lot's of reasons! Here's a few:
* I didn't concieve of it as open source, and it never occured to me that someone else might see the code.
* Testing? LOL
* There are a lot of half-implemented ideas in the code.
* It only runs on AppEngine
* It's written in at least two frameworks (Django and Tipfy), with a little bit of hacky WSGI middleware thrown in for reasons I forget.

# What is most broken?

Expand Down
2 changes: 1 addition & 1 deletion settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
#'messaging.messaging_context'
)

ROOT_URLCONF = 'django_urls'
ROOT_URLCONF = 'urls'

ROOT_PATH = os.path.dirname(__file__)

Expand Down
1 change: 1 addition & 0 deletions sources/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ICalendarEditForm(forms.Form):
source_key=forms.CharField(required=False)

def save(self):
from models import ICalendarSource
cleaned_data=self.cleaned_data
profile=get_current_profile()
from models import ICalendarSource
Expand Down
49 changes: 29 additions & 20 deletions sources/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from google.appengine.api.labs import taskqueue
from google.appengine.api import memcache

from sources.tasks import process_ical, process_gdata

from urllib import unquote

import gdata.calendar.service
Expand Down Expand Up @@ -49,41 +51,48 @@ def fetch(self,started=None, timestamp=None):
format_start="%Y%m%d%H%M"
if not started: started=str(datetime.now())
if not timestamp:timestamp= datetime.now().strftime("%Y%m%d%H%M")
if self.ical_href.startswith('http://www.google.com/calendar/ical/'):

if self.ical_href.startswith('http://www.google.com/calendar/ical/') or self.ical_href.startswith('https://www.google.com/calendar/ical/'):

gcal_id=unquote(self.ical_href[36:].split('/')[0])
query = gdata.calendar.service.CalendarEventQuery(gcal_id, 'public', 'full-noattendees')
query.start_min= self.site.today.strftime("%Y-%m-%d")
query.recurrence_expansion_end=(date.today()+relativedelta(months=3)).strftime("%Y-%m-%d")
query.start_max=(date.today()+relativedelta(months=3)).strftime("%Y-%m-%d")
query.singleevents='true'
result=urlfetch.fetch(query.ToUri(), allow_truncated=False, deadline=10)
logging.warning("fetching %s" % result.content)
if result.status_code == 200:
detection=chardet.detect(result.content)
self.last_fetch=datetime.now()
self.content=result.content.decode(detection['encoding'])
self.put()
cache_key="%s-%s-%s" %(self.site.slug, self.slug,timestamp)
memcache.add(cache_key, result.content.decode(detection['encoding']),600)
logging.warning("cached gdata with key %s"% cache_key)
taskqueue.add(url='/sources/split_gdata/', params={'ical_key': self.key(),
'cache_key':cache_key,
'timestamp':timestamp},
name=cache_key
)
logging.warning("enqueued splitting of %s" % self.ical_href)
process_gdata(self)
#cache_key="%s-%s-%s" %(self.site.slug, self.slug,timestamp)
#memcache.add(cache_key, ,600)
#logging.warning("cached gdata with key %s"% cache_key)
#taskqueue.add(url='/sources/split_gdata/', params={'ical_key': self.key(),
# 'cache_key':cache_key,
# 'timestamp':timestamp},
# name=cache_key
# )
#logging.warning("enqueued splitting of %s" % self.ical_href)
return

result=urlfetch.fetch(self.ical_href, allow_truncated=True, deadline=5)
result=urlfetch.fetch(self.ical_href, allow_truncated=False, deadline=5)
if result.status_code == 200:
detection=chardet.detect(result.content)
self.last_fetch=datetime.now()
self.content=result.content.decode(detection['encoding'])
self.put()
cache_key="%s-%s-%s" %(self.site.slug, self.slug,timestamp)
memcache.add(cache_key, result.content.decode(detection['encoding']),600)
logging.warning("cached ical with key %s"% cache_key)
taskqueue.add(url='/sources/split_ical/', params={'ical_key': self.key(),
'cache_key':cache_key,
'timestamp':timestamp},
name=cache_key
)
logging.warning("enqueued splitting of %s" % self.ical_href)
process_ical(self)
#cache_key="%s-%s-%s" %(self.site.slug, self.slug,timestamp)
#memcache.add(cache_key, result.content.decode(detection['encoding']),600)
#logging.warning("cached ical with key %s"% cache_key)
#taskqueue.add(url='/sources/split_ical/', params={'ical_key': self.key(),
# 'cache_key':cache_key,
# 'timestamp':timestamp},
# name=cache_key
# )
#logging.warning("enqueued splitting of %s" % self.ical_href)

Loading

0 comments on commit a9987ef

Please sign in to comment.