display of borrowability and library holdings

needed another date column on acqs to manage this
bookpanel getting complicated- moved some logic into tempalte tags
library page now shows b2u books it owns
"library" has its own view now
pull/1/head
eric 2013-10-18 12:36:55 -04:00
parent 6910f1aa0c
commit 93d128102e
10 changed files with 194 additions and 100 deletions

View File

@ -8,6 +8,11 @@ from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Acq.refreshes'
db.add_column('core_acq', 'refreshes',
self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2013, 10, 17, 0, 0), auto_now_add=True, blank=True),
keep_default=False)
# Adding field 'Acq.lib_acq'
db.add_column('core_acq', 'lib_acq',
self.gf('django.db.models.fields.related.ForeignKey')(related_name='loans', null=True, to=orm['core.Acq']),
@ -15,6 +20,9 @@ class Migration(SchemaMigration):
def backwards(self, orm):
# Deleting field 'Acq.refreshes'
db.delete_column('core_acq', 'refreshes')
# Deleting field 'Acq.lib_acq'
db.delete_column('core_acq', 'lib_acq_id')
@ -74,6 +82,7 @@ class Migration(SchemaMigration):
'lib_acq': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loans'", 'null': 'True', 'to': "orm['core.Acq']"}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'nonce': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'refreshes': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 10, 17, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['auth.User']"}),
'watermarked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['booxtream.Boox']", 'null': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['core.Work']"})
@ -126,7 +135,7 @@ class Migration(SchemaMigration):
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 10, 16, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 10, 17, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),

View File

@ -262,6 +262,7 @@ class Acq(models.Model):
CHOICES = ((INDIVIDUAL,'Individual license'),(LIBRARY,'Library License'),(BORROWED,'Borrowed from Library'), (TESTING,'Just for Testing'), (RESERVE,'On Reserve'),)
created = models.DateTimeField(auto_now_add=True)
expires = models.DateTimeField(null=True)
refreshes = models.DateTimeField(auto_now_add=True, default=now())
work = models.ForeignKey("Work", related_name='acqs', null=False)
user = models.ForeignKey(User, related_name='acqs')
license = models.PositiveSmallIntegerField(null = False, default = INDIVIDUAL,
@ -318,6 +319,9 @@ class Acq(models.Model):
def expire_in(self, delta):
self.expires = now()+delta
self.save()
if self.lib_acq:
self.lib_acq.refreshes = now()+ (timedelta(days=14))
self.lib_acq.save()
@property
def on_reserve(self):
@ -335,9 +339,10 @@ class Acq(models.Model):
def borrowable(self):
if self.license == RESERVE and not self.expired:
return True
if self.license != LIBRARY:
if self.license == LIBRARY:
return self.refreshes < datetime.now()
else:
return False
return Acq.objects.filter(lib_acq=self,expires__gt=datetime.now()).count()==0
@ -1108,25 +1113,37 @@ class Work(models.Model):
acqs=Acq.objects.none()
def __init__(self,acqs):
self.acqs=acqs
def is_active(self):
if self.acqs.count()==0:
return False
for acq in self.acqs:
if acq.expires is None:
return True
if acq.expires > now():
return True
return False
@property
def is_active(self):
return self.acqs.filter(expires__isnull = True).count()>0 or self.acqs.filter(expires__gt= now()).count()>0
@property
def borrowed(self):
loans = self.acqs.filter(license=BORROWED,expires__gt= now())
if loans.count()==0:
return None
else:
return loans[0]
@property
def purchased(self):
for acq in self.acqs:
if acq.license == INDIVIDUAL:
return True
return False
purchases = self.acqs.filter(license=INDIVIDUAL)
if purchases.count()==0:
return None
else:
return purchases[0]
@property
def lib_acqs(self):
return self.acqs.filter(license=LIBRARY)
@property
def borrowable(self):
return self.acqs.filter(license=LIBRARY, refreshes__lt=now()).count()>0
def get_user_license(self,user):
if user==None or not user.is_authenticated():
if user==None or user.is_anonymous():
return None
return self.user_license(self.acqs.filter(user=user))

View File

@ -882,8 +882,9 @@ class LibTests(TestCase):
self.assertTrue(new_acq.borrowable)
reserve_acq = Acq.objects.create(user=u,work=c.work,license= RESERVE, lib_acq = new_acq)
self.assertTrue(reserve_acq.borrowable)
print reserve_acq.expires
self.assertTrue(reserve_acq.expires< now()+timedelta(hours=3))
self.assertFalse(new_acq.borrowable)
self.assertTrue(reserve_acq.expires< now()+timedelta(hours=3))
reserve_acq.borrow()
self.assertTrue(reserve_acq.expires> now()+timedelta(hours=3))

View File

@ -1,5 +1,6 @@
{% load humanize %}
{% load purchased %}
{% load lib_acqs %}
{% with work.first_ebook as first_ebook %}
{% with work.last_campaign.supporters as supporters %}
{% with work.cover_image_thumbnail as thumbnail %}
@ -10,7 +11,7 @@
{% with work.last_campaign.deadline as deadline %}
{% with work.id as workid %}
{% with request.user.wishlist.works.all as wishlist %}
{% purchased %}
{% purchased %}{% lib_acqs %}
<div class="thewholebook listview tabs {% if first_ebook or status == 'SUCCESSFUL' %}tabs-1{% else %}{% if status == 'ACTIVE' %}tabs-2{% else %}tabs-3{% endif %}{% endif %}">
<div class="listview book-list">
<div class="listview panelback side2">
@ -18,7 +19,7 @@
<div class="greenpanel2">
{% if last_campaign %}
{% comment %}top section: campaign info + optional action button. Varies by campaign status.{% endcomment %}
{% if status == 'SUCCESSFUL' %}
{% if status == 'SUCCESSFUL' or license_is_active or borrowable %}
<div class="greenpanel_top">
{% comment %}bibliographic data{% endcomment %}
<div class="white_text">
@ -29,21 +30,41 @@
<div class="moreinfo">
<a href="{% if workid %}{% url work workid %}{% else %}{% url googlebooks googlebooks_id %}{% endif %}" target="_top">More Info</a>
</div>
{% if purchased %}
<div class="unglued_white">
<b>Purchased!</b>
</div>
{% else %}{% if borrowed %}
<b>Borrowed!</b>
<p><b>Until</b> {{ borrowed.expires|date:"M d, Y" }}</p>
{% else %}{% if borrowable %}
<div class="unglued_white">
<b>Library has it!</b>
<p><b>{{ lib_acqs.count }}</b>{% ifequal lib_acqs.count 1 %} copy{% else %} copies{% endifequal %}</p>
</div>
{% else %}
<div class="unglued_white">
<b>UNGLUED!</b>
<p><b>On:</b> {{ deadline|date:"M d, Y" }}</p>
<p><b>Raised:</b> {{ work.last_campaign.current_total|floatformat:0|intcomma }}</p>
</div>
</div>
{% endif %}{% endif %}{% endif %}
</div>
<div class="add_button">
{% include "book_panel_addbutton.html" %}
</div>
<div class="white_text bottom_button" >
{% if first_ebook %}
{% if purchased %}
<a href="{% url download workid %}" class="hijax"><span class="read_itbutton button_text"><span>Read it Now</span></span></a>
{% else %}{% if borrowed %}
<a href="{% url download workid %}" class="hijax"><span class="read_itbutton button_text"><span>Read it Now</span></span></a>
{% else %}{% if borrowable %}
<a href="{% url borrow workid %}?library={{library}}" class="hijax"><span class="read_itbutton button_text"><span>Borrow It</span></span></a>
{% else %}{% if first_ebook %}
<a href="{% url download workid %}" class="hijax"><span class="read_itbutton button_text"><span>Read it Now</span></span></a>
{% else %}
<a href="{% url work workid %}"><span class="read_itbutton button_text"><span>Coming Soon</span></span></a>
{% endif %}
{% endif %}{% endif %}{% endif %}{% endif %}
</div>
{% else %}{% if status == 'ACTIVE' %}
<div class="greenpanel_top">
@ -65,7 +86,7 @@
<p>by {{ deadline|naturalday:"M d, Y" }}</p>
{% else %}
<p><b>${{ work.last_campaign.left|floatformat:0|intcomma }}</b> needed</p>
<p>now ungluing on </p>
<p>will unglue on </p>
<p>{{ work.last_campaign.cc_date|naturalday:"M d, Y" }}</p>
{% endifequal %}
</div>
@ -80,13 +101,9 @@
</div>
<div class="white_text bottom_button" >
{% ifequal work.last_campaign.type 1 %}
<a href="{% url pledge work_id=workid %}"><span class="read_itbutton pledge button_text"><span>Pledge</span></span></a>
<a href="{% url pledge work_id=workid %}"><span class="read_itbutton pledge button_text"><span>Pledge</span></span></a>
{% else %}
{% if purchased %}
<a href="{% url download workid %}"><span class="read_itbutton pledge button_text"><span>Download</span></span></a>
{% else %}
<a href="{% url purchase work_id=workid %}"><span class="read_itbutton pledge button_text"><span>Purchase</span></span></a>
{% endif %}
<a href="{% url purchase work_id=workid %}"><span class="read_itbutton pledge button_text"><span>Purchase</span></span></a>
{% endifequal %}
</div>
{% endif %}
@ -166,50 +183,37 @@
</div>
{% comment %}same logic as above{% endcomment %}
{% if request.user.is_anonymous %}
{% if show_pledge %}
<div class="listview panelfront side1 add-wishlist">
<span class="booklist_pledge"><a href="{% url pledge work_id=workid %}" class="fakeinput">Pledge</a></span>
</div>
{% else %}{% if show_purchase %}
<div class="listview panelfront side1 add-wishlist">
<span class="booklist_pledge"><a href="{% url purchase work_id=workid %}" class="fakeinput">Purchase</a></span>
</div>
{% else %}{% if request.user.is_anonymous %}
<div class="listview panelfront side1 create-account">
<span title="{% if workid %}{% url work workid %}{% else %}{% url googlebooks googlebooks_id %}{% endif %}">Login to Add</span>
</div>
{% else %}{% if request.user.id in supporters %}
<div class="listview panelfront side1 on-wishlist">
<span>Pledged!</span>
</div>
{% else %}{% ifequal supporter request.user %}
{% comment %} used only on your own supporter page. {% endcomment %}
{% ifequal status "ACTIVE" %}
<div class="listview panelfront side1 pledge">
{% ifequal work.last_campaign.type 1 %}
<span class="booklist_pledge"><a href="{% url pledge work_id=workid %}" class="fakeinput">Pledge</a></span>
{% else %}
{% if purchased %}
<span class="booklist_pledge"><a href="{% url download workid %}" class="fakeinput">Download</a></span>
{% else %}
<span class="booklist_pledge"><a href="{% url purchase work_id=workid %}" class="fakeinput">Purchase</a></span>
{% endif %}
{% endifequal %}
</div>
{% else %}
{% else %}{% if work in wishlist %}
{% ifequal supporter request.user %}
{% comment %} used only on your own supporter page. {% endcomment %}
<div class="listview panelfront side1 remove-wishlist">
<span id="l{{ workid }}">Un-list</span>
</div>
{% else %}
<div class="listview panelfront side1 on-wishlist">
{% if purchased %}
<span>Purchased!</span>
{% else %}{% if borrowed %}
<span>Borrowed!</span>
{% else %}{% if request.user.id in supporters %}
<span>Pledged!</span>
{% else %}
<span>On My List!</span>
{% endif %}{% endif %}{% endif %}
</div>
{% endifequal %}
{% else %}{% ifequal status "ACTIVE" %}
<div class="listview panelfront side1 add-wishlist">
{% ifequal work.last_campaign.type 1 %}
<span class="booklist_pledge"><a href="{% url pledge work_id=workid %}" class="fakeinput">Pledge</a></span>
{% else %}
{% if purchased %}
<span class="booklist_pledge"><a href="{% url download workid %}" class="fakeinput">Download</a></span>
{% else %}
<span class="booklist_pledge"><a href="{% url purchase work_id=workid %}" class="fakeinput">Purchase</a></span>
{% endif %}
{% endifequal %}
</div>
{% else %}{% if work in wishlist %}
<div class="listview panelfront side1 on-wishlist">
<span>On My List!</span>
</div>
{% else %}
<div class="listview panelfront side1 add-wishlist">
{% if on_search_page %}
@ -218,15 +222,17 @@
<span class="work_id" id="l{{ workid }}">Add to My List</span>
{% endif %}
</div>
{% endif %}{% endifequal %}{% endifequal %}{% endif %}{% endif %}
{% endif %}{% endif %}{% endif %}{% endif %}
<div class="listview panelfront side1 booklist-status">
{% ifequal status "ACTIVE" %}
{% ifequal work.last_campaign.type 1 %}
{% if library %}
<span class="booklist-status-text"><b>{{ lib_acqs.count }}</b> {% ifequal lib_acqs.count 1 %} copy{% else %} copies{% endifequal %}</span>
{% else %}{% ifequal work.last_campaign.type 1 %}
<span class="booklist-status-text"><b>${{ work.last_campaign.current_total|floatformat:0|intcomma }}</b>/<b>${{ work.last_campaign.target|floatformat:0|intcomma }}</b></span>
{% else %}
<span class="booklist-status-text"><b>${{ work.last_campaign.left|floatformat:0|intcomma }}</b> to go</span>
{% endifequal %}
{% endifequal %}{% endif %}
{% else %}{% ifequal status "INITIALIZED" %}
<span class="booklist-status-label">Status:&nbsp;</span><span class="booklist-status-text">Coming soon!</span>
{% else %}{% ifequal status "SUCCESSFUL" %}
@ -245,8 +251,14 @@
If no ebook but there is an active or successful campaign: progress toward goal
Otherwise: number of wishes
{% endcomment %}
{% if first_ebook %}
<a href="{% url download workid %}" class="hijax"><div class="read_itbutton"><span>Read it Now</span></div></a>
{% if purchased %}
<a href="{% url download workid %}" class="hijax"><div class="read_itbutton"><span>Read it Now</span></div></a>
{% else %}{% if borrowed %}
<a href="{% url download workid %}" class="hijax"><div class="read_itbutton"><span>Read it Now</span></div></a>
{% else %}{% if borrowable %}
<a href="{% url borrow workid %}?library={{library}}" class="hijax"><div class="read_itbutton"><span>Borrow It</span></div></a>
{% else %}{% if first_ebook %}
<a href="{% url download workid %}" class="hijax"><div class="read_itbutton"><span>Read it Now</span></div></a>
{% else %}{% if status == 'ACTIVE' or status == 'SUCCESSFUL' %}
<div class="booklist-status-img">
<img src="/static/images/images/icon-book-37by25-{{ work.percent_unglued }}.png" title="book list status" alt="book list status" />
@ -258,7 +270,7 @@
{% else %}
<a href="{% if workid %}{% url work workid %}{% else %}{% url googlebooks googlebooks_id %}{% endif %}?tab=3" class="nobold"><span class="rounded"><span class="grey"><span class="panelnope">Listed by&nbsp;</span>0</span></span></a>
{% endif %}
{% endif %}{% endif %}
{% endif %}{% endif %}{% endif %}{% endif %}{% endif %}
</div>
<div class="listview panelfront side1 ebooks">

View File

@ -150,8 +150,7 @@ function highlightTarget(targetdiv) {
<div class="content-block-heading wantto" id="tabs">
<ul class="tabs">
<li class="tabs1"><a href="#">Unglued</a></li>
<li class="tabs2"><a href="#">Active</a></li>
<li class="tabs3"><a href="#">Wishlisted</a></li>
<li class="tabs2"><a href="#">Available</a></li>
</ul>
<ul class="book-list-view">
@ -257,20 +256,6 @@ function highlightTarget(targetdiv) {
{% endfor %}
</div>
{% lazy_paginate 20 works_wished using "works_wished" %}
{% for work in works_wished %}
<div class="{% cycle 'row1' 'row2' %}">
{% with work.googlebooks_id as googlebooks_id %}
{% include "book_panel.html" %}
{% endwith %}
</div>
{% endfor %}
<div class="pagination content-block-heading tabs-3">
{% get_pages %}
{% for page in pages %}
<a href="{{ page.path }}#3" class="endless_page_link">{{ page.number }}</a>
{% endfor %}
</div>
{% endifequal %}
</div>

View File

@ -0,0 +1,38 @@
from django import template
from regluit.utils.localdatetime import now
from regluit.parameters import *
register = template.Library()
@register.simple_tag(takes_context=True)
def bookpanel(context):
work = context['work']
library = context.get('library',None)
user = context['request'].user
campaign = context.get('last_campaign', None)
# compute a boolean that's true if bookpanel should show a "pledge" button...
# campaign is ACTIVE, type 1 - PLEDGE
# user has not pledged or user is anonymous
show_pledge = False
if campaign and campaign.type==PLEDGE:
if user.is_anonymous() or not user.id in context.get('supporters', []):
show_pledge = True
context['show_pledge'] = show_pledge
# compute a boolean that's true if bookpanel should show a "purchase" button...
# campaign is ACTIVE, type 2 - BUY2UNGLUE
# user has not purchased or user is anonymous
# user has not borrowed or user is anonymous
# work not available in users library
# not on the library page
show_purchase = False
if campaign and campaign.type==BUY2UNGLUE:
if user.is_anonymous() or not context.get('license_is_active', False):
if not context.get('borrowable', False):
if not library:
show_purchase = True
context['show_purchase'] = show_purchase
return ''

View File

@ -0,0 +1,16 @@
from regluit.utils.localdatetime import now
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def lib_acqs(context):
work = context['work']
library = context.get('library',False)
if not library:
return ''
user_license = work.get_user_license(library.user)
if user_license:
context['lib_acqs'] = user_license.lib_acqs
else:
context['lib_acqs'] = None
return ''

View File

@ -7,9 +7,22 @@ register = template.Library()
def purchased(context):
work = context['work']
user = context['request'].user
try:
user_license = work.get_user_licence(user)
if user.is_anonymous():
return ''
user_license = work.get_user_license(user)
if user_license:
context['purchased'] = user_license.purchased
except:
context['purchased'] = False
context['borrowed'] = user_license.borrowed
context['license_is_active'] = user_license.is_active
else:
context['purchased'] = None
context['borrowed'] = None
context['license_is_active'] = False
borrowable = False
for library in user.profile.libraries:
lib_license=work.get_user_license(library.user)
if lib_license and lib_license.borrowable:
borrowable = True
continue
context['borrowable'] = borrowable
return ''

View File

@ -48,7 +48,7 @@ urlpatterns = patterns(
url(r"^next/$", "next", name="next"),
url(r"^supporter/(?P<supporter_username>[^/]+)/$", "supporter", {'template_name': 'supporter.html'}, name="supporter"),
url(r"^supporter/(?P<userlist>[^/]+)/marc/$", "marc", name="user_marc"),
url(r"^library/(?P<library>[^/]+)/$", "library", name="library"),
url(r"^library/(?P<library_name>[^/]+)/$", "library", name="library"),
url(r"^accounts/manage/$", login_required(ManageAccount.as_view()), name="manage_account"),
url(r"^search/$", "search", name="search"),
url(r"^privacy/$", TemplateView.as_view(template_name="privacy.html"),

View File

@ -1858,16 +1858,19 @@ def supporter(request, supporter_username, template_name, extra_context={}):
context.update(extra_context)
return render(request, template_name, context)
def library(request,library):
def library(request,library_name):
context={}
try:
# determine if the supporter is a library
authenticator = Authenticator(request,library)
authenticator = Authenticator(request,library_name)
context['authenticator'] = authenticator
context['library'] = authenticator.library
context['library'] = library = authenticator.library
except Library.DoesNotExist:
raise Http404
return supporter(request,library,template_name='libraryauth/library.html', extra_context=context)
context['works_active']= models.Work.objects.filter(acqs__user=library.user,acqs__license=LIBRARY).distinct()
context['activetab'] = "#2"
return supporter(request,library_name,template_name='libraryauth/library.html', extra_context=context)