From ccb1f0dd869f068b8c1fa1d078aa18a1db0dd25f Mon Sep 17 00:00:00 2001
From: eric
Date: Wed, 27 Nov 2013 22:14:52 -0500
Subject: [PATCH] create and edit Library objects, which now have names and
owners
---
frontend/templates/base.html | 3 +
frontend/templates/explore.html | 4 +-
frontend/templates/libraries.html | 15 ++-
frontend/templates/libraryauth/edit.html | 39 ++++++
frontend/templates/libraryauth/library.html | 8 +-
frontend/templates/libraryauth/list.html | 4 +-
frontend/templates/libraryauth/users.html | 4 +-
.../notification/library_join/full.txt | 4 +-
.../notification/library_join/notice.html | 6 +-
frontend/templates/supporter.html | 2 +-
libraryauth/forms.py | 40 ++++++
...dd_field_library_approved__add_field_li.py | 115 ++++++++++++++++++
libraryauth/models.py | 9 +-
.../templates/libraryauth/cardnum_join.html | 2 +-
.../templates/libraryauth/email_join.html | 2 +-
.../templates/libraryauth/ip_join.html | 2 +-
libraryauth/urls.py | 12 +-
libraryauth/views.py | 86 +++++++++++--
18 files changed, 321 insertions(+), 36 deletions(-)
create mode 100644 frontend/templates/libraryauth/edit.html
create mode 100644 libraryauth/migrations/0003_auto__add_field_library_name__add_field_library_approved__add_field_li.py
diff --git a/frontend/templates/base.html b/frontend/templates/base.html
index cb740e0c..04b8bff2 100644
--- a/frontend/templates/base.html
+++ b/frontend/templates/base.html
@@ -155,6 +155,9 @@ Not needed on newly designed home page?
Rights Holder Tools
Privacy
Terms of Use
+ {% for library in user.libraries.all %}
+ {{ library }} Administration
+ {% endfor %}
{% if user.is_staff %}
Unglue.it Administration
Create New Editions
diff --git a/frontend/templates/explore.html b/frontend/templates/explore.html
index 3dcb4987..066b70ed 100644
--- a/frontend/templates/explore.html
+++ b/frontend/templates/explore.html
@@ -11,7 +11,7 @@
{% if not request.user.is_anonymous %}
My Books
{% for library in request.user.profile.libraries %}
- {{ library }}
+ {{ library }}
{% endfor %}
{% else %}
@@ -55,7 +55,7 @@
{% endfor %}
{% if library %}
- More from {{ library }}
+ More from {{ library }}
{% endif %}
diff --git a/frontend/templates/libraries.html b/frontend/templates/libraries.html
index eb66df1f..3f351d8a 100644
--- a/frontend/templates/libraries.html
+++ b/frontend/templates/libraries.html
@@ -25,16 +25,21 @@
We love libraries because we're from the library world. And because we live in a real world that still needs libraries. We've built Unglue.it in part because we've seen that the ebook system we have now really doesn't work for libraries, and we believe in making things better.
We started out with "Pledge" campaigns to help books become Creative Commons licensed ebooks.
-We’ve added "Buy-to-Unglue" campaigns to so that libraries can lend ebooks on the road to being unglued.
+We’ve added "Buy-to-Unglue" campaigns to so that libraries can lend ebooks on the road to being unglued. We've built a free distribution platform to help libraries distribute these books.
{{ library }} is participating in Unglue.it. That means you can borrow Unglue.it ebooks owned by {{ library }} (when available). Here's a list of the ebooks available to {{ library }} members.
{{ library }} is participating in Unglue.it. That means you can borrow Unglue.it ebooks owned by {{ library }} (when available). Here's a list of the ebooks available to {{ library }} members.
When you buy an ebook through unglue.it, you'll be offered the option to by a library license in stead of an individual license. That means that {{ library }} will own the ebook, but you'll be the first in line to borrow it. After two weeks, the book will be available to other members of {{ library }}.
@@ -22,6 +22,6 @@
{{ supporter.library }} is a Library participating in Unglue.it.
Click here to use {{ supporter.library }}'s books.
+
{{ supporter.library }} is a Library participating in Unglue.it.
Click here to use {{ supporter.library }}'s books.
{% endif %}
diff --git a/libraryauth/forms.py b/libraryauth/forms.py
index 4c2930d5..54df3d5d 100644
--- a/libraryauth/forms.py
+++ b/libraryauth/forms.py
@@ -1,4 +1,9 @@
+from django import forms
from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _
+
+from .models import Library
class AuthForm(AuthenticationForm):
def __init__(self, request=None, *args, **kwargs):
@@ -8,3 +13,38 @@ class AuthForm(AuthenticationForm):
else:
super(AuthForm, self).__init__(*args, **kwargs)
+class NewLibraryForm(forms.ModelForm):
+ username = forms.RegexField(
+ label=_("Library Username"),
+ max_length=30,
+ regex=r'^[\w.@+-]+$',
+ help_text = _("30 characters or fewer."),
+ error_messages = {
+ 'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")
+ },
+ initial = '',
+ )
+ email = forms.EmailField(
+ label=_("notification email address for library"),
+ max_length=100,
+ error_messages={'required': 'Please enter an email address for the library.'},
+ )
+ def clean_username(self):
+ username= self.cleaned_data['username']
+ try:
+ user = User.objects.get(username=username)
+ raise forms.ValidationError(_("That username is already in use, please choose another."))
+ except User.DoesNotExist:
+ self.instance.user = User(username=username)
+ return username
+
+
+ class Meta:
+ model = Library
+ fields = 'name', 'backend', 'email', 'username'
+ widgets = {'name':forms.TextInput(attrs={'size':'40'})}
+
+class LibraryForm(forms.ModelForm):
+ class Meta:
+ model = Library
+ fields = 'name', 'backend',
diff --git a/libraryauth/migrations/0003_auto__add_field_library_name__add_field_library_approved__add_field_li.py b/libraryauth/migrations/0003_auto__add_field_library_name__add_field_library_approved__add_field_li.py
new file mode 100644
index 00000000..22dd5796
--- /dev/null
+++ b/libraryauth/migrations/0003_auto__add_field_library_name__add_field_library_approved__add_field_li.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'Library.name'
+ db.add_column('libraryauth_library', 'name',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=80),
+ keep_default=False)
+
+ # Adding field 'Library.approved'
+ db.add_column('libraryauth_library', 'approved',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding field 'Library.owner'
+ db.add_column('libraryauth_library', 'owner',
+ self.gf('django.db.models.fields.related.ForeignKey')(default=10, related_name='libraries', to=orm['auth.User']),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'Library.name'
+ db.delete_column('libraryauth_library', 'name')
+
+ # Deleting field 'Library.approved'
+ db.delete_column('libraryauth_library', 'approved')
+
+ # Deleting field 'Library.owner'
+ db.delete_column('libraryauth_library', 'owner_id')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'libraryauth.block': {
+ 'Meta': {'ordering': "['lower']", 'object_name': 'Block'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'blocks'", 'to': "orm['libraryauth.Library']"}),
+ 'lower': ('regluit.libraryauth.models.IPAddressModelField', [], {'unique': 'True', 'db_index': 'True'}),
+ 'upper': ('regluit.libraryauth.models.IPAddressModelField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
+ },
+ 'libraryauth.cardpattern': {
+ 'Meta': {'object_name': 'CardPattern'},
+ 'checksum': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'card_patterns'", 'to': "orm['libraryauth.Library']"}),
+ 'pattern': ('django.db.models.fields.CharField', [], {'max_length': '20'})
+ },
+ 'libraryauth.emailpattern': {
+ 'Meta': {'object_name': 'EmailPattern'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'email_patterns'", 'to': "orm['libraryauth.Library']"}),
+ 'pattern': ('django.db.models.fields.CharField', [], {'max_length': '20'})
+ },
+ 'libraryauth.library': {
+ 'Meta': {'object_name': 'Library'},
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'backend': ('django.db.models.fields.CharField', [], {'default': "'ip'", 'max_length': '10'}),
+ 'group': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'libraries'", 'to': "orm['auth.User']"}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'to': "orm['auth.User']"})
+ },
+ 'libraryauth.libraryuser': {
+ 'Meta': {'object_name': 'LibraryUser'},
+ 'credential': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True'}),
+ 'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'library_users'", 'to': "orm['libraryauth.Library']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_libraries'", 'to': "orm['auth.User']"})
+ }
+ }
+
+ complete_apps = ['libraryauth']
\ No newline at end of file
diff --git a/libraryauth/models.py b/libraryauth/models.py
index a5c3b515..2e1d60d8 100644
--- a/libraryauth/models.py
+++ b/libraryauth/models.py
@@ -9,6 +9,7 @@ from django.db.models import Q
from django.db.models.signals import post_save
from django.forms import IPAddressField as BaseIPAddressField
from django.utils.translation import ugettext_lazy as _
+from django.core.urlresolvers import reverse
class Library(models.Model):
'''
@@ -21,10 +22,13 @@ class Library(models.Model):
('cardnum', 'Library Card Number check'),
('email', 'e-mail pattern check'),
),default='ip')
+ name = models.CharField(max_length=80, default='')
+ approved = models.BooleanField(default=False)
+ owner = models.ForeignKey(User, related_name="libraries")
credential = None
def __unicode__(self):
- return self.user.username
+ return unicode(self.name)
def add_user(self, user):
user.groups.add(self.group)
@@ -38,6 +42,9 @@ class Library(models.Model):
@property
def join_template(self):
return 'libraryauth/' + self.backend + '_join.html'
+
+ def get_absolute_url(self):
+ return reverse('library', args=[self.user.username])
def add_group(sender, created, instance, **kwargs):
if created:
diff --git a/libraryauth/templates/libraryauth/cardnum_join.html b/libraryauth/templates/libraryauth/cardnum_join.html
index 34d56b54..e0c8204e 100644
--- a/libraryauth/templates/libraryauth/cardnum_join.html
+++ b/libraryauth/templates/libraryauth/cardnum_join.html
@@ -1,5 +1,5 @@