1414from django .utils import timezone
1515from django .core .exceptions import ValidationError
1616
17+ from core import models as core_models
18+ from core .file_system import JanewayFileSystemStorage
19+ from core .model_utils import M2MOrderedThroughField
1720from metrics .logic import get_iso_country_code
1821from utils .shared import get_ip_address
19- from core import models as core_models
2022from plugins .books import files
21- from core .file_system import JanewayFileSystemStorage
2223
2324
2425fs = JanewayFileSystemStorage ()
@@ -42,7 +43,7 @@ class BookSetting(models.Model):
4243
4344 def save (self , * args , ** kwargs ):
4445 if not self .pk and BookSetting .objects .exists ():
45- raise ValidationError ('There is can be only one BookSetting instance' )
46+ raise ValidationError ('There can be only one BookSetting instance' )
4647 return super (BookSetting , self ).save (* args , ** kwargs )
4748
4849
@@ -87,11 +88,15 @@ class Book(models.Model):
8788 null = True ,
8889 on_delete = models .SET_NULL ,
8990 )
90- description = models .TextField ()
91- pages = models .PositiveIntegerField ()
91+ description = models .TextField (null = True , blank = True )
92+ pages = models .PositiveIntegerField (null = True , blank = True )
9293
9394 is_edited_volume = models .BooleanField (default = False )
9495 is_open_access = models .BooleanField (default = True )
96+ date_embargo = models .DateField (
97+ blank = True ,
98+ null = True ,
99+ )
95100 date_published = models .DateField (
96101 blank = True ,
97102 null = True ,
@@ -126,14 +131,37 @@ class Book(models.Model):
126131 help_text = "Add copyright and/or license information here." ,
127132 )
128133
134+ keywords = M2MOrderedThroughField (
135+ 'submission.Keyword' ,
136+ blank = True , null = True , through = 'books.KeywordBook' ,
137+ )
138+ publisher_notes = models .ManyToManyField (
139+ 'books.PublisherNote' ,
140+ null = True ,
141+ blank = True ,
142+ related_name = "book" ,
143+ help_text = 'Free-text public publisher notes regarding this book' ,
144+ )
145+
146+ custom_how_to_cite = models .TextField (
147+ blank = True , null = True ,
148+ help_text = "Custom 'how to cite' text. To be used only if the block"
149+ " generated by Janeway is not suitable." ,
150+ )
151+
152+
129153 def __str__ (self ):
130154 return self .title
131155
156+ @property
132157 def citation (self ):
133- return "{authors} {year}. <em>{title}</em>" .format (
134- authors = self .contributors_citation (),
135- year = self .date_published .year ,
136- title = self .full_title (),
158+ return (
159+ self .custom_how_to_cite
160+ or "{authors} {year}. <em>{title}</em>" .format (
161+ authors = self .contributors_citation (),
162+ year = self .date_published .year ,
163+ title = self .full_title (),
164+ )
137165 )
138166
139167 def contributors_citation (self ):
@@ -367,18 +395,27 @@ class Chapter(models.Model):
367395 max_length = 255 ,
368396 )
369397 description = models .TextField ()
370- pages = models .PositiveIntegerField ()
398+ pages = models .PositiveIntegerField (blank = True , null = True )
371399 doi = models .CharField (
372400 max_length = 200 ,
373401 blank = True ,
374402 null = True ,
375403 verbose_name = 'DOI' ,
376404 help_text = '10.xxx/1234' ,
377405 )
378- number = models .PositiveIntegerField (
406+ number = models .CharField (
407+ blank = True ,
408+ null = True ,
409+ max_length = 64 ,
410+ help_text = 'The chapter number eg. 7 or VII' ,
411+ )
412+ date_embargo = models .DateField (
413+ blank = True ,
414+ null = True ,
415+ )
416+ date_published = models .DateField (
379417 blank = True ,
380418 null = True ,
381- help_text = 'The chapter number eg. 1' ,
382419 )
383420 sequence = models .PositiveIntegerField (
384421 help_text = 'The order in which the chapters should appear.' ,
@@ -397,6 +434,24 @@ class Chapter(models.Model):
397434 help_text = "Add copyright and/or license information here. "
398435 "If left blank will display book version of this field." ,
399436 )
437+ keywords = M2MOrderedThroughField (
438+ 'submission.Keyword' ,
439+ blank = True , null = True , through = 'books.KeywordChapter' ,
440+ )
441+ publisher_notes = models .ManyToManyField (
442+ 'books.PublisherNote' ,
443+ null = True ,
444+ blank = True ,
445+ related_name = "chapter" ,
446+ help_text = 'Free-text public publisher notes regarding this book' ,
447+ )
448+
449+ custom_how_to_cite = models .TextField (
450+ blank = True , null = True ,
451+ help_text = "Custom 'how to cite' text. To be used only if the block"
452+ " generated by Janeway is not suitable." ,
453+ )
454+
400455
401456 class Meta :
402457 ordering = ('sequence' , 'number' ,)
@@ -445,3 +500,76 @@ def add_book_access(self, request, access_type='download'):
445500 country = country ,
446501 identifier = identifier ,
447502 )
503+
504+
505+ @property
506+ def citation (self ):
507+ return (
508+ self .custom_how_to_cite
509+ or "{authors} {year}. <em>{title}</em>. In {book}" .format (
510+ authors = self .contributors_citation (),
511+ year = self .date_published .year ,
512+ title = self .title ,
513+ book = self .book .citation ,
514+ )
515+ )
516+
517+ def contributors_citation (self ):
518+ contributors = self .contributors .all ()
519+
520+ if contributors .count () == 1 :
521+ return '{contributor} ' .format (
522+ contributor = contributors [0 ].citation_name ()
523+ )
524+ elif contributors .count () == 2 :
525+ return '{contributor_one} & {contributor_two} ' .format (
526+ contributor_one = contributors [0 ].citation_name (),
527+ contributor_two = contributors [1 ].citation_name (),
528+ )
529+ else :
530+ return '{contributor} et al. ' .format (contributor = contributors [0 ])
531+
532+
533+ class KeywordBook (models .Model ):
534+ keyword = models .ForeignKey (
535+ "submission.Keyword" ,
536+ on_delete = models .CASCADE ,
537+ )
538+ book = models .ForeignKey ("books.Book" )
539+ order = models .PositiveIntegerField (default = 1 )
540+
541+ class Meta :
542+ ordering = ["order" ]
543+ unique_together = ('keyword' , 'book' )
544+
545+ def __str__ (self ):
546+ return self .keyword .word
547+
548+ def __repr__ (self ):
549+ return "KeywordBook(%s, %d)" % (self .keyword .word , self .book .id )
550+
551+
552+ class KeywordChapter (models .Model ):
553+ keyword = models .ForeignKey (
554+ "submission.Keyword" ,
555+ on_delete = models .CASCADE ,
556+ )
557+ chapter = models .ForeignKey (
558+ "books.Chapter" ,
559+ on_delete = models .CASCADE ,
560+ )
561+ order = models .PositiveIntegerField (default = 1 )
562+
563+ class Meta :
564+ ordering = ["order" ]
565+ unique_together = ('keyword' , 'chapter' )
566+
567+ def __str__ (self ):
568+ return self .keyword .word
569+
570+ def __repr__ (self ):
571+ return "KeywordChapter(%s, %d)" % (self .keyword .word , self .chapter .id )
572+
573+
574+ class PublisherNote (models .Model ):
575+ note = models .TextField (blank = True , null = True )
0 commit comments