split version into label and iter

pull/1/head
eric 2016-09-23 14:53:54 -04:00
parent e8d4ab82be
commit 5fc4d631ff
9 changed files with 98 additions and 62 deletions

View File

@ -902,8 +902,8 @@ def load_from_yaml(yaml_url, test_mode=False):
rights = cc.match_license(metadata.rights),
format = ebook_format,
edition = edition,
version = metadata._version
)
ebook.set_version(metadata._version)
return work.id

View File

@ -11,10 +11,19 @@ class Migration(migrations.Migration):
]
operations = [
migrations.AlterField(
migrations.RemoveField(
model_name='ebook',
name='version',
field=models.CharField(max_length=255, null=True, blank=True),
),
migrations.AddField(
model_name='ebook',
name='version_iter',
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name='ebook',
name='version_label',
field=models.CharField(default=b'', max_length=255, blank=True),
),
migrations.AlterField(
model_name='edition',
@ -41,6 +50,11 @@ class Migration(migrations.Migration):
name='age_level',
field=models.CharField(default=b'', max_length=5, blank=True, choices=[(b'', b'No Rating'), (b'5-6', b"Children's - Kindergarten, Age 5-6"), (b'6-7', b"Children's - Grade 1-2, Age 6-7"), (b'7-8', b"Children's - Grade 2-3, Age 7-8"), (b'8-9', b"Children's - Grade 3-4, Age 8-9"), (b'9-11', b"Children's - Grade 4-6, Age 9-11"), (b'12-14', b'Teen - Grade 7-9, Age 12-14'), (b'15-18', b'Teen - Grade 10-12, Age 15-18'), (b'18-', b'Adult/Advanced Reader')]),
),
migrations.AlterField(
model_name='work',
name='openlibrary_lookup',
field=models.DateTimeField(null=True, blank=True),
),
migrations.AlterField(
model_name='work',
name='publication_range',

View File

@ -969,7 +969,7 @@ class Campaign(models.Model):
new_ebfs = []
for to_do in to_dos:
edition = to_do['ebook'].edition
version = to_do['ebook'].version
version = {'label':to_do['ebook'].version_label, 'iter':to_do['ebook'].version_iter}
if to_do['ebook'].format == 'pdf':
try:
added = ask_pdf({'campaign':self, 'work':self.work, 'site':Site.objects.get_current()})
@ -1015,7 +1015,8 @@ class Campaign(models.Model):
rights=self.license,
provider="Unglue.it",
url=ebf.file.url,
version=ebf.version
version_label=ebf.version['label'],
version_iter=ebf.version['iter'],
)
ebf.ebook = ebook
ebf.save()

View File

@ -90,7 +90,7 @@ class Work(models.Model):
created = models.DateTimeField(auto_now_add=True, db_index=True,)
title = models.CharField(max_length=1000)
language = models.CharField(max_length=5, default="en", null=False, db_index=True,)
openlibrary_lookup = models.DateTimeField(null=True)
openlibrary_lookup = models.DateTimeField(null=True, blank=True)
num_wishes = models.IntegerField(default=0, db_index=True)
description = models.TextField(default='', null=True, blank=True)
selected_edition = models.ForeignKey("Edition", related_name='selected_works', null=True)
@ -365,11 +365,10 @@ class Work(models.Model):
return EbookFile.objects.filter(edition__work=self, format='pdf').exclude(file='').order_by('-created')
def versions(self):
version_labels = ['']
for ebook in self.ebooks():
if not ebook.version_label in version_labels:
version_labels = []
for ebook in self.ebooks_all():
if ebook.version_label and not ebook.version_label in version_labels:
version_labels.append(ebook.version_label)
version_labels.remove('')
return version_labels
def formats(self):
@ -382,9 +381,9 @@ class Work(models.Model):
def remove_old_ebooks(self):
# this method is triggered after an file upload or new ebook saved
old = Ebook.objects.filter(edition__work=self, active=True).order_by('-created')
old = Ebook.objects.filter(edition__work=self, active=True).order_by('-version_iter', '-created')
# keep most recent ebook for each format and version label
# keep highest version ebook for each format and version label
done_format_versions = []
for eb in old:
format_version = '{}_{}'.format(eb.format, eb.version_label)
@ -1014,7 +1013,8 @@ class EbookFile(models.Model):
format='mobi',
url=new_mobi_ebf.file.url,
rights=self.ebook.rights,
version=self.ebook.version,
version_label=self.ebook.version_label,
version_iter=self.ebook.version_iter,
)
new_mobi_ebf.ebook = new_ebook
new_mobi_ebf.save()
@ -1030,7 +1030,8 @@ class Ebook(models.Model):
download_count = models.IntegerField(default=0)
active = models.BooleanField(default=True)
filesize = models.PositiveIntegerField(null=True)
version = models.CharField(max_length=255, null=True, blank=True)
version_label = models.CharField(max_length=255, default="", blank=True)
version_iter = models.PositiveIntegerField(default=0)
# use 'PD-US', 'CC BY', 'CC BY-NC-SA', 'CC BY-NC-ND', 'CC BY-NC', 'CC BY-ND', 'CC BY-SA', 'CC0'
rights = models.CharField(max_length=255, null=True, choices=cc.CHOICES, db_index=True)
@ -1087,19 +1088,35 @@ class Ebook(models.Model):
return self.provider
@property
def version_label(self):
if self.version is None:
return ''
version_match = re.search(r'(.*)\.(\d+)$',self.version)
return version_match.group(1) if version_match else self.version
@property
def version_iter(self):
if self.version is None:
return 0
version_match = re.search(r'(.*)\.(\d+)$',self.version)
return int(version_match.group(2)) if version_match else 0
def version(self):
if self.version_label is None:
return '.{}'.format(self.version_iter)
else:
return '().{}'.format(self.version_label, self.version_iter)
def set_version(self, version):
#set both version_label and version_iter with one string with format "version.iter"
version_pattern = r'(.*)\.(\d+)$'
match = re.match(version_pattern,version)
if match:
(self.version_label, self.version_iter) = (match.group(1), match.group(2))
else:
self.version_label = version
self.save()
def set_next_iter(self):
# set the version iter to the next unused iter for that version
for ebook in Ebook.objects.filter(
edition=self.edition,
version_label=self.version_label,
format=self.format,
provider=self.provider
).order_by('-version_iter'):
iter = ebook.version_iter
break
self.version_iter = iter + 1
self.save()
@property
def rights_badge(self):
if self.rights is None:

View File

@ -280,8 +280,9 @@ def test_file(the_file):
raise forms.ValidationError(_('%s is not a valid PDF file' % the_file.name) )
class EbookFileForm(forms.ModelForm):
version = forms.CharField(max_length=512, required=False)
file = forms.FileField(max_length=16777216)
version_label = forms.CharField(max_length=512, required=False)
new_version_label = forms.CharField(required=False)
def __init__(self, campaign_type=BUY2UNGLUE, *args, **kwargs):
super(EbookFileForm, self).__init__(*args, **kwargs)
@ -293,6 +294,10 @@ class EbookFileForm(forms.ModelForm):
choices = (('pdf', 'PDF'), ('epub', 'EPUB'), ('mobi', 'MOBI'))
)
def clean_version_label(self):
new_label = self.data.get('new_version_label','')
return new_label if new_label else self.cleaned_data['version_label']
def clean_format(self):
if self.campaign_type is BUY2UNGLUE:
return 'epub'
@ -310,18 +315,25 @@ class EbookFileForm(forms.ModelForm):
model = EbookFile
widgets = { 'edition': forms.HiddenInput}
exclude = { 'created', 'asking', 'ebook' }
class EbookForm(forms.ModelForm):
file = forms.FileField(max_length=16777216, required=False)
url = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 60},))
version_label = forms.CharField(required=False)
new_version_label = forms.CharField(required=False)
class Meta:
model = Ebook
exclude = ('created', 'download_count', 'active', 'filesize')
exclude = ('created', 'download_count', 'active', 'filesize', 'version_iter')
widgets = {
'edition': forms.HiddenInput,
'user': forms.HiddenInput,
'provider': forms.HiddenInput,
}
def clean_version_label(self):
new_label = self.data.get('new_version_label','')
return new_label if new_label else self.cleaned_data['version_label']
def clean_provider(self):
new_provider = Ebook.infer_provider(self.cleaned_data['url'])
if not new_provider:

View File

@ -8,7 +8,7 @@
{% for ebook in edition.ebooks.all %}
{% if ebook.active %}
<a href="{% url 'download_ebook' ebook.id %}">{{ ebook.format }}</a> {{ebook.rights}} at {{ebook.provider}}.
{% if ebook.version %} {{ ebook.version }}. {% endif %}
{% if ebook.version_label %} {{ ebook.version_label }} (v{{ ebook.version_iter }}). {% endif %}
Downloaded {{ ebook.download_count }} times since {{ ebook.created }}<br />
{% endif %}
{% endfor %}
@ -27,30 +27,20 @@
or...<br />
{{ ebook_form.file.errors }}<span>Upload an ebook file: {{ ebook_form.file }}</span><br /><br />
{{ ebook_form.format.errors }}<span>File Format: {{ ebook_form.format }}</span>&nbsp;&nbsp;&nbsp;
{{ ebook_form.rights.errors }}<span>License: {{ ebook_form.rights }}</span><br />
{% if admin %}
{{ ebook_form.version.errors }}<span>Version: {{ ebook_form.version }} </span><br />
{% else %}
<input type="hidden" value="" name="version" />
{{ ebook_form.rights.errors }}<span>License: {{ ebook_form.rights }}</span><br /><br />
<span>Version Label (optional): {% if edition.work.versions %}
<select id='version_label'>
<option value=""> (no label) </option>
{% for vers in edition.work.versions %}<option value="{{ vers }}" >{{ vers }}</option>{% endfor %}
</select> or add a new version label:
{% endif %}
{{ ebook_form.new_version_label.errors }} {{ ebook_form.new_version_label }} </span> <br />
<br /><input type="submit" name="add_ebook" value="add link/upload ebook" />
</form>
{% if admin %}
<h3>Note on versions</h4>
<p>
Unglue.it's version strings have two components, a label and a iteration.
The iteration is denoted by a dot and a number at the end of version string, and is assumed to be 0 if not given explicitly.
Unglue.it will show the user just the label and will suppress display of all but the highest iteration for a given label.
so if the ebooks have versions "", ".1", "1.0.0", "1.0.2", "Open Access" and "Open Access.1", Unglue.it will display 3 ebooks labelled "", "1.0" and "Open Access".
If you want ebooks from two editions with the same format to display, give them different version labels.
If you want ebooks from two editions with the same format and provider to display, give them different version labels.
</p>
<p> The existing version labels for this work are:
<ul>
{% for vers in edition.work.versions %}
<li>{% if vers %}"{{ vers }}"{% else %}"" [no version specified]{% endif %}</li>
<ul>
{% endfor %}
{% endif %}
</div>
{% else %}
<div> Adding ebook links is disabled for this work.</div>

View File

@ -24,7 +24,7 @@
<h2>Active eBooks for this Work</h2>
{% for ebook in edition.work.ebooks %}
<a href="{% url 'download_ebook' ebook.id %}">{{ ebook.format }}</a> {{ebook.rights}} at {{ebook.provider}}.
{% if ebook.version %} {{ ebook.version }}. {% endif %}
{% if ebook.version_label %} {{ ebook.version_label }}. {% endif %} v{{ ebook.version_iter }}
Downloaded {{ ebook.download_count }} times since {{ ebook.created }}<br />
{% endfor %}
{% endif %}
@ -76,16 +76,17 @@ For ePUB files, use the <a href=https://code.google.com/p/epubcheck/">epubcheck<
{% csrf_token %}
{{form.edition.errors}}{{form.edition}}
<p>{{form.format.errors}}Format: {{form.format}}</p>
{% if edition.work.versions %}
<p>There are named versions for this ebook. Specify the version you want to replace.<br /> {{form.version.errors}}Version: <select id="version">
<option value="{{ version }}" >---</option>
{% for version in edition.work.versions %}
<option value="{{ version }}" >{{ version }}</option>
{% endfor %}
</select></p>
{% else %}
<input type="hidden" value="" id="version" name="version"/>
{% endif %}
<h3>Note on versions</h4>
<p>
If you want ebooks from two editions with the same format and provider to display, give them different version labels.
</p>
<span>Version Label (optional): {% if edition.work.versions %}
<select id='version_label'>
<option value=""> (no label) </option>
{% for vers in edition.work.versions %}<option value="{{ vers }}" >{{ vers }}</option>{% endfor %}
</select> or add a new version label:
{% endif %}
{{ form.new_version_label.errors }} {{ form.new_version_label }} </span> <br />
<p>{{form.file.errors}}Upload File: {{form.file}}</p>
<input type="submit" id="submit_file" value="submit ebook file">
</form>

View File

@ -431,7 +431,7 @@
This work has been downloaded {{ work.download_count }} times via unglue.it ebook links.
<ol>
{% for ebook in work.ebooks.all %}
<li>{{ ebook.download_count }} - {{ ebook.format }} {% if ebook.version %} {{ ebook.version }} {% endif %}({{ ebook.rights }}) at {{ ebook.provider }}. </li>
<li>{{ ebook.download_count }} - {{ ebook.format }} {% if ebook.version_label %} ({{ ebook.version_label }}) {% endif %}({{ ebook.rights }}) at {{ ebook.provider }}. </li>
{% endfor %}
</ol>
</div>

View File

@ -467,12 +467,12 @@ def edition_uploads(request, edition_id):
format=form.instance.format,
url=form.instance.file.url,
rights=edition.work.last_campaign().license,
version=form.cleaned_data['version'],
version_label=form.cleaned_data.get('version_label', ''),
active=False,
provider="Unglue.it",
)
form.instance.ebook = new_ebook
form.instance.save()
form.instance.ebook.set_next_iter()
else:
context['upload_error'] = form.errors
@ -688,6 +688,7 @@ def manage_ebooks(request, edition_id, by=None):
new_ebf.save()
else:
ebook_form.save()
ebook_form.instance.set_next_iter()
edition.work.remove_old_ebooks()
alert = 'Thanks for adding an ebook to unglue.it!'
else: