Skip to content
This repository has been archived by the owner on Sep 1, 2024. It is now read-only.

Commit

Permalink
Initial import from the private Pleft repository
Browse files Browse the repository at this point in the history
  • Loading branch information
sander committed Dec 22, 2010
0 parents commit 5388d01
Show file tree
Hide file tree
Showing 123 changed files with 10,806 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .hgignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
syntax: glob

*~
*.pyc
*.swp
*.mo
*.cjs
external/*
pleft/local_settings.py
674 changes: 674 additions & 0 deletions COPYING

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
This is the Pleft software that runs on www.pleft.com.
Documentation is limited right now, but please email sander.dijkhuis@gmail.com
for more details and to get involved.

System requirements:
- Django 1.2 or higher
- a Java runtime environment (for plovr)

Installation:
1. mkdir external
2. Download the most recent plovr build to the external/ dir, from:
http://code.google.com/p/plovr/downloads/list
3. Symlink external/plovr-[code].jar to external/plovr.jar
4. Create pleft/local_settings.py, based on one of the examples in that dir.
5. pleft/manage.py init
6. pleft/manage.py compile
7. pleft/manage.py mo

Run debug servers:
pleft/manage.py runplovr
pleft/manage.py runserver

Note:
- If you are using MySQL, make sure that the database is created using:
CREATE DATABASE name CHARACTER SET utf8
Also, for the user system to work, the email address field must be made
case sensitive, using:
ALTER TABLE plauth_user MODIFY email VARCHAR(255) COLLATE utf8_bin
99 changes: 99 additions & 0 deletions plapp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copyright 2009, 2010 Sander Dijkhuis <sander.dijkhuis@gmail.com>
#
# This file is part of Pleft.
#
# Pleft is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pleft is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pleft. If not, see <http://www.gnu.org/licenses/>.

# General utilities for Pleft.

import re

from django.template.defaultfilters import escape
from django.template.loader import render_to_string
from django.utils.text import wrap

def get_cache_key(data_type, **kwargs):
def _get(arg):
if arg in kwargs:
return str(kwargs[arg])
else:
return None
key = data_type + '_' + (_get('appointment') or _get('invitee'))
if _get('appointment') and _get('invitee'):
key += '_' + _get('invitee')
return key

def get_menu_cache_key(user):
return 'menu_%s' % user.id

def clear_menu_cache(user):
from django.core.cache import cache
cache.delete(get_menu_cache_key(user))

def send_mail(subject, template, address, name, title, url, initiator=''):
"""Send an appointment email"""
from django.conf import settings

content = prepare_mail(template, name, title, url, initiator)

params = {'sender': settings.MAIL_SENDER,
'to': '%s <%s>' % (name, address),
'subject': subject,
'body': content['body'],
'html': content['html']}

from django.core import mail

msg = mail.EmailMultiAlternatives(params['subject'],
params['body'],
params['sender'],
[params['to']])
msg.attach_alternative(params['html'], 'text/html')
msg.send()

def prepare_mail(template, name, title, url, initiator):
from django.conf import settings

abuse = settings.ABUSE_EMAIL
site = settings.SITE_DOMAIN

# Plain text email
body_params = { 'name': name,
'title_and_link': '{{ title_and_link }}',
'abuse_address': abuse,
'site_name': settings.SITE_NAME,
'site_link': settings.SITE_BASE + '/',
'initiator': initiator }
body = render_to_string(template, body_params)
body = re.sub('\n(\n)+', '\n\n', body)
body = wrap(body.strip(), 74) + '\n'
body = body.replace('{{ title_and_link }}',
' %s\n %s' % (title, url))

# HTML email
name = escape(name)
title = escape(title)
initiator = escape(initiator)
html_params = { 'name': name,
'title_and_link': '&nbsp; &nbsp; <a href="%s" style="color:blue"><b>%s</b></a>' % (url, title),
'abuse_address': '<a href="mailto:%s" style="color:blue">%s</a>' % (abuse, abuse),
'site_name': settings.SITE_NAME,
'site_link': '<a href="%s/" style="color:blue">%s</a>' % (settings.SITE_BASE, settings.SITE_DOMAIN),
'initiator': initiator }
html = render_to_string(template, html_params)
html = re.sub('\n(\n)+', '\n\n', html.strip())
html = html.replace('\n\n', '<p>').replace('\n', '<br>')
html = '<div style="font:14px Arial,sans-serif;color:#000;background:#fff;max-width:420px"><p><img src="%s" alt="%s"><p>%s</div>\n' % (settings.EMAIL_LOGO, settings.SITE_NAME, html)

return {'body': body, 'html': html}
20 changes: 20 additions & 0 deletions plapp/context_processors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2009, 2010 Sander Dijkhuis <sander.dijkhuis@gmail.com>
#
# This file is part of Pleft.
#
# Pleft is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pleft is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pleft. If not, see <http://www.gnu.org/licenses/>.

def settings(request):
from django.conf import settings
return { 'settings': settings }
55 changes: 55 additions & 0 deletions plapp/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2009, 2010 Sander Dijkhuis <sander.dijkhuis@gmail.com>
#
# This file is part of Pleft.
#
# Pleft is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pleft is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pleft. If not, see <http://www.gnu.org/licenses/>.

from email.utils import getaddresses, formataddr

import django.forms
from django.utils.translation import ugettext_lazy as _

class DateTimeListField(django.forms.CharField):
def clean(self, value):
value = super(DateTimeListField, self).clean(value)

datetimes = value.split('\n')

# FIXME: check them using DateTimeField first.

return datetimes

class EmailListField(django.forms.CharField):
"""
A Django form field which validates a list of email addresses.
Taken from http://www.djangosnippets.org/snippets/1677/
and modified
"""
default_error_messages = {
'invalid': _('Please enter a valid list of email addresses.')
}

def clean(self, value):
value = super(EmailListField, self).clean(value).strip() \
.replace(';', ',')

field = django.forms.EmailField()

try:
return getaddresses([', '.join([
formataddr((name, field.clean(addr)))
for name, addr in getaddresses([value])])])
except django.forms.ValidationError:
raise django.forms.ValidationError(self.error_messages['invalid'])
28 changes: 28 additions & 0 deletions plapp/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2009, 2010 Sander Dijkhuis <sander.dijkhuis@gmail.com>
#
# This file is part of Pleft.
#
# Pleft is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pleft is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pleft. If not, see <http://www.gnu.org/licenses/>.

from django import forms

import fields

class AppointmentForm(forms.Form):
description = forms.CharField(max_length=1000, required=False)
name = forms.CharField(max_length=100, required=False)
email = forms.EmailField(required=True)
invitees = fields.EmailListField(required=False)
dates = fields.DateTimeListField(required=False)
propose_more = forms.BooleanField(required=False)
129 changes: 129 additions & 0 deletions plapp/js/accountbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2009, 2010 Sander Dijkhuis <sander.dijkhuis@gmail.com>
//
// This file is part of Pleft.
//
// Pleft is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pleft is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pleft. If not, see <http://www.gnu.org/licenses/>.

/**
* @fileoverview The Account Bar for Plapp.
* @author sander.dijkhuis@gmail.com (Sander Dijkhuis)
*/

goog.provide('pleft.accountBar');

goog.require('goog.debug.ErrorHandler');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.net.XhrIo');
goog.require('goog.positioning.Corner');
goog.require('goog.string');
goog.require('goog.string.StringBuffer');
goog.require('goog.ui.Component.EventType');
goog.require('goog.ui.MenuItem');
goog.require('goog.ui.MenuSeparator');
goog.require('goog.ui.PopupMenu');
goog.require('goog.Uri');

/**
* Initializes the Account Bar on the current page.
*/
pleft.accountBar.init = function() {
var container = document.body;

if (window['signedIn'] === true) {
var email = window['email'];
} else {
var email = null;
}

var bar = pleft.accountBar.render_(email);
container.insertBefore(bar, container.firstChild);

if (window['signedIn'] === true) {
var menuButton = document.getElementById('ab-menu');

var menu = new goog.ui.PopupMenu();

var loading = new goog.ui.MenuItem(gettext('Loading…'));
loading.setEnabled(false);
menu.addItem(loading);

var isLoading = true;
goog.events.listen(menu, goog.ui.Component.EventType.BEFORE_SHOW, function(e) {
if (!isLoading)
return;

goog.net.XhrIo.send('/menu', function(event) {
if (event.target.getStatus() == 200) {
var data = event.target.getResponseJson()['a'];
for (var i = 0; i < data.length; i++) {
var item = new goog.ui.MenuItem(data[i][1], '/a#id=' + data[i][0]);
menu.addItemAt(item, 0);
menu.hide();
menu.setVisible(true);
}
} else {
var fail = new goog.ui.MenuItem(gettext('Menu temporarily unavailaible.'));
fail.setEnabled(false);
menu.addItemAt(fail, 0);
}
if (isLoading) {
menu.removeItem(loading);
isLoading = false;
}
});
});

menu.addItem(new goog.ui.MenuSeparator());
menu.addItem(new goog.ui.MenuItem(gettext('All appointments'),
'/appointments'));
menu.addItem(new goog.ui.MenuItem(gettext('New appointment'),
'/'));

menu.render(document.body);
menu.attach(menuButton, goog.positioning.Corner.BOTTOM_RIGHT,
goog.positioning.Corner.TOP_RIGHT);

goog.events.listen(menu, goog.ui.Component.EventType.ACTION, function(e) {
window.location = e.target.getModel();
});
} else {
bar.style.display = 'none';
}
};

/**
* Creates and returns an Account Bar DOM element.
*
* @param {string} email User’s email address.
* @return {Node} Account Bar's DOM element.
* @private
*/
pleft.accountBar.render_ = function(email) {
var output = new goog.string.StringBuffer();
output.append('<div id=ab-bar>');
if (email) {
output.append('<span id=ab-email>',
goog.string.htmlEscape(email),
'</span><a id=ab-menu href=\'javascript:void(0)\'>',
gettext('My appointments'),
'</a>');
output.append('<a id=ab-signout href=\'/signout\'>',
gettext('Sign out'),
'</a>');
}
output.append('</div>');

return goog.dom.htmlToDocumentFragment(output.toString());
};
Loading

0 comments on commit 5388d01

Please sign in to comment.