Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 75 additions & 15 deletions admin.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,95 @@
from django.contrib import admin

from plugins.books.models import *
import plugins.books.models as models


@admin.register(models.BookSetting)
class BookSettingAdmin(admin.ModelAdmin):
list_display = ('book_page_title',)


class ContributorLinkInline(admin.TabularInline):
model = models.ContributorLink
extra = 1
raw_id_fields = ('contributor',)


@admin.register(models.Chapter)
class ChapterAdmin(admin.ModelAdmin):
"""Displays objects in the Django admin interface."""
list_display = ('title', 'number', 'book', 'pages', 'doi')
list_filter = ('book',)
search_fields = ('title',)
search_fields = ('title', 'book__title', 'doi')
raw_id_fields = ('book',)
filter_horizontal = ('contributors',)
inlines = [ContributorLinkInline]


@admin.register(models.BookAccess)
class BookAccessAdmin(admin.ModelAdmin):
list_display = ('book', 'chapter', 'type', 'format', 'country', 'accessed')
list_filter = ('book', 'type', 'format', 'country')
search_fields = ('book__title', 'chapter__title')


@admin.register(models.Book)
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher_name', 'date_published', 'is_open_access')
list_filter = ('is_open_access', 'peer_reviewed', 'date_published', 'category')
search_fields = ('title', 'subtitle', 'publisher_name', 'isbn', 'doi')
raw_id_fields = ('category',)
filter_horizontal = ('keywords', 'publisher_notes', 'linked_repository_objects')


@admin.register(models.Contributor)
class ContributorAdmin(admin.ModelAdmin):
list_display = ('last_name', 'first_name', 'affiliation')
search_fields = ('first_name', 'last_name', 'affiliation', 'email')


@admin.register(models.ContributorLink)
class ContributorLinkAdmin(admin.ModelAdmin):
list_display = ('contributor', 'book', 'chapter', 'order')
list_filter = ('book', 'chapter')
raw_id_fields = ('contributor', 'book', 'chapter')


@admin.register(models.Format)
class FormatAdmin(admin.ModelAdmin):
list_display = ('title', 'book', 'sequence')
list_filter = ('book',)
search_fields = ('book__title',)
search_fields = ('title', 'filename')
raw_id_fields = ('book',)


@admin.register(models.Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'slug', 'display_title')
search_fields = ('name', 'slug')


@admin.register(models.BookPreprint)
class BookPreprintAdmin(admin.ModelAdmin):
list_display = ('book', 'preprint', 'order')
list_filter = ('book',)
raw_id_fields = ('book', 'preprint')


@admin.register(models.KeywordBook)
class KeywordBookAdmin(admin.ModelAdmin):
list_display = ('keyword', 'book', 'order')
list_filter = ('book',)
search_fields = ('keyword__word',)
raw_id_fields = ('keyword', 'book')


@admin.register(models.KeywordChapter)
class KeywordChapterAdmin(admin.ModelAdmin):
list_display = ('keyword', 'chapter', 'order')
list_filter = ('chapter',)
search_fields = ('keyword__word',)
raw_id_fields = ('keyword', 'chapter')

admin_list = [
(Book, ),
(Contributor,),
(Format,),
(BookAccess, BookAccessAdmin),
(Chapter, ChapterAdmin),
(Category,),
(BookSetting, BookSettingAdmin)
]

[admin.site.register(*t) for t in admin_list]
@admin.register(models.PublisherNote)
class PublisherNoteAdmin(admin.ModelAdmin):
list_display = ('note',)
search_fields = ('note',)
89 changes: 77 additions & 12 deletions forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django_summernote.widgets import SummernoteWidget

from plugins.books import models, files
from repository import models as repository_models


class DateInput(forms.DateInput):
Expand Down Expand Up @@ -44,7 +45,7 @@ class BookForm(forms.ModelForm):

class Meta:
model = models.Book
exclude = ('keywords', 'publisher_notes')
exclude = ('keywords', 'publisher_notes', 'linked_repository_objects')
widgets = {
'description': SummernoteWidget(),
'date_published': DateInput(),
Expand All @@ -53,30 +54,37 @@ class Meta:

class ContributorForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
book = kwargs.pop('book', None)
super(ContributorForm, self).__init__(*args, **kwargs)

self.fields['sequence'].initial = book.get_next_contributor_sequence()

class Meta:
model = models.Contributor
exclude = ('book',)
fields = (
'first_name',
'middle_name',
'last_name',
'affiliation',
'email',
)


class FormatForm(forms.ModelForm):

file = forms.FileField()

def __init__(self, *args, **kwargs):
super(FormatForm, self).__init__(*args, **kwargs)
if self.instance and self.instance.pk and self.instance.filename:
self.fields['file'].required = False

class Meta:
model = models.Format
exclude = ('book', 'filename')

def save(self, commit=True, *args, **kwargs):
save_format = super(FormatForm, self).save(commit=False)
file = self.cleaned_data["file"]
filename = files.save_file_to_disk(file, save_format)
save_format.filename = filename

if file:
filename = files.save_file_to_disk(file, save_format)
save_format.filename = filename

if commit:
save_format.save()
Expand All @@ -91,11 +99,27 @@ def clean(self):

class ChapterForm(forms.ModelForm):

contributors = forms.ModelMultipleChoiceField(
queryset=models.Contributor.objects.none(),
required=False,
)

def __init__(self, *args, **kwargs):
items = kwargs.pop('items', None)
super(ChapterForm, self).__init__(*args, **kwargs)
self.fields['contributors'].widget = TableMultiSelect(items=items)
self.fields['contributors'].required = False
# Set queryset from items
pks = [row.get('object').pk for row in items if row.get('object')]
self.fields['contributors'].queryset = models.Contributor.objects.filter(
pk__in=pks,
)
# Set initial from existing ContributorLinks
if self.instance and self.instance.pk:
self.fields['contributors'].initial = list(
models.ContributorLink.objects.filter(
chapter=self.instance,
).values_list('contributor_id', flat=True)
)

file = forms.FileField(required=False)

Expand All @@ -110,7 +134,6 @@ class Meta:
'date_embargo',
'date_published',
'sequence',
'contributors',
'license_information',
'custom_how_to_cite',
]
Expand All @@ -131,6 +154,34 @@ def save(self, commit=True, book=None, *args, **kwargs):

return save_chapter

def save_chapter_contributors(self, chapter):
selected_contributors = self.cleaned_data.get('contributors', [])
existing_links = models.ContributorLink.objects.filter(chapter=chapter)

# Remove links for contributors no longer selected
existing_links.exclude(
contributor__in=selected_contributors,
).delete()

# Add links for newly selected contributors
existing_contributor_ids = set(
existing_links.values_list('contributor_id', flat=True)
)
next_order = (
existing_links.order_by('-order').values_list(
'order', flat=True,
).first() or 0
) + 1

for contributor in selected_contributors:
if contributor.pk not in existing_contributor_ids:
models.ContributorLink.objects.create(
contributor=contributor,
chapter=chapter,
order=next_order,
)
next_order += 1


class DateForm(forms.Form):
start_date = forms.DateField(widget=DateInput())
Expand Down Expand Up @@ -165,3 +216,17 @@ def save(self, commit=True):
save_category.save()

return save_category


class PreprintSelectionForm(forms.Form):
preprint_id = forms.ModelChoiceField(
queryset=repository_models.Preprint.objects.none(),
label="Select a Preprint",
required=True,
)

def __init__(self, *args, **kwargs):
available_preprints = kwargs.pop('available_preprints', None)
super().__init__(*args, **kwargs)
if available_preprints is not None:
self.fields['preprint_id'].queryset = available_preprints
26 changes: 25 additions & 1 deletion hooks.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe

from utils.function_cache import cache



@cache(600)
def nav_hook(context):
return '<li><a href="{url}"><i class="fa fa-book"></i> Books</a></li>'.format(
url=reverse('books_admin')
)


def linked_books(context):
request = context.get("request")
preprint = context.get("preprint")

if not preprint or not hasattr(preprint, "get_linked_books"):
return ""

theme = getattr(preprint.repository, "theme", "OLH")
template_path = f"books/{theme}/repository_linked_books.html"

books = preprint.get_linked_books()

return mark_safe(render_to_string(
template_path,
{
"preprint": preprint,
"linked_books": books,
},
request=request,
))
40 changes: 37 additions & 3 deletions logic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from plugins.books import models
from datetime import date, timedelta, datetime
from dateutil.relativedelta import relativedelta
Expand Down Expand Up @@ -151,10 +153,42 @@ def book_metrics_by_month(books, date_parts):
return data, dates, current_year, previous_year


def get_chapter_contributor_items(book):
contributors = models.Contributor.objects.filter(
book=book,
def swap_order(item, direction, queryset, order_field='order'):
"""Swap an item's order with its neighbour in an ordered queryset."""
# Normalize orders to be sequential
for index, obj in enumerate(queryset):
if getattr(obj, order_field) != index:
setattr(obj, order_field, index)
obj.save()
item.refresh_from_db()

current_order = getattr(item, order_field)

if direction == 'up':
neighbour = queryset.filter(**{order_field: current_order - 1}).first()
if neighbour:
setattr(neighbour, order_field, current_order)
neighbour.save()
setattr(item, order_field, current_order - 1)
item.save()
elif direction == 'down':
neighbour = queryset.filter(**{order_field: current_order + 1}).first()
if neighbour:
setattr(neighbour, order_field, current_order)
neighbour.save()
setattr(item, order_field, current_order + 1)
item.save()


def trigger_message(name, direction):
"""Build a JSON HX-Trigger-After-Swap header value with proper escaping."""
return json.dumps(
{"showMessage": {"value": "{} moved {}.".format(name, direction)}}
)


def get_chapter_contributor_items(book):
contributors = book.contributors.all()
items = list()
items.append({'object': None, 'cells': ['First Name', 'Last Name', 'Email']})

Expand Down
Empty file added management/__init__.py
Empty file.
Empty file added management/commands/__init__.py
Empty file.
Loading