This repository has been archived by the owner on Sep 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial import from the private Pleft repository
- Loading branch information
0 parents
commit 5388d01
Showing
123 changed files
with
10,806 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,9 @@ | ||
syntax: glob | ||
|
||
*~ | ||
*.pyc | ||
*.swp | ||
*.mo | ||
*.cjs | ||
external/* | ||
pleft/local_settings.py |
Large diffs are not rendered by default.
Oops, something went wrong.
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,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 |
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,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': ' <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} |
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,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 } |
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,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']) |
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,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) |
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,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()); | ||
}; |
Oops, something went wrong.