Merge pull request #211 from Gluejar/b2u_marc

B2u marc
pull/1/head
Raymond Yee 2013-09-24 06:20:39 -07:00
commit b46ebbdd4a
7 changed files with 471 additions and 166 deletions

View File

@ -0,0 +1,326 @@
# -*- 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):
# Deleting field 'MARCRecord.xml_record'
db.delete_column('core_marcrecord', 'xml_record')
# Deleting field 'MARCRecord.mrc_record'
db.delete_column('core_marcrecord', 'mrc_record')
def backwards(self, orm):
# Adding field 'MARCRecord.xml_record'
db.add_column('core_marcrecord', 'xml_record',
self.gf('django.db.models.fields.URLField')(default='', max_length=200, blank=True),
keep_default=False)
# Adding field 'MARCRecord.mrc_record'
db.add_column('core_marcrecord', 'mrc_record',
self.gf('django.db.models.fields.URLField')(default='', max_length=200, blank=True),
keep_default=False)
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'})
},
'booxtream.boox': {
'Meta': {'object_name': 'Boox'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'download_link_epub': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'download_link_mobi': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'downloads_remaining': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
'expirydays': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'referenceid': ('django.db.models.fields.CharField', [], {'max_length': '32'})
},
'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'})
},
'core.acq': {
'Meta': {'object_name': 'Acq'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'nonce': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': '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']"})
},
'core.author': {
'Meta': {'object_name': 'Author'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.badge': {
'Meta': {'object_name': 'Badge'},
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '72', 'blank': 'True'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'cc_date_initial': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
'dollar_per_day': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Publisher']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'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, 9, 22, 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'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'download_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
},
'core.ebookfile': {
'Meta': {'object_name': 'EbookFile'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebook_files'", 'to': "orm['core.Edition']"}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'core.edition': {
'Meta': {'object_name': 'Edition'},
'cover_image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'publisher_name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.PublisherName']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'unglued': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.identifier': {
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"})
},
'core.key': {
'Meta': {'object_name': 'Key'},
'encrypted_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'core.libpref': {
'Meta': {'object_name': 'Libpref'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'marc_link_target': ('django.db.models.fields.CharField', [], {'default': "'UNGLUE'", 'max_length': '6'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'libpref'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.marcrecord': {
'Meta': {'object_name': 'MARCRecord'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'MARCrecords'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'link_target': ('django.db.models.fields.CharField', [], {'default': "'DIRECT'", 'max_length': '6'})
},
'core.offer': {
'Meta': {'object_name': 'Offer'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'offers'", 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.press': {
'Meta': {'object_name': 'Press'},
'date': ('django.db.models.fields.DateField', [], {}),
'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'note': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'core.publisher': {
'Meta': {'object_name': 'Publisher'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'key_publisher'", 'to': "orm['core.PublisherName']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
},
'core.publishername': {
'Meta': {'object_name': 'PublisherName'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternate_names'", 'null': 'True', 'to': "orm['core.Publisher']"})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'can_sell': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'core.subject': {
'Meta': {'ordering': "['name']", 'object_name': 'Subject'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'avatar_source': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1', 'null': 'True'}),
'badges': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'holders'", 'symmetrical': 'False', 'to': "orm['core.Badge']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kindle_email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'blank': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.waswork': {
'Meta': {'object_name': 'WasWork'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'moved': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'was': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Work']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
},
'core.wishlist': {
'Meta': {'object_name': 'Wishlist'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
}
}
complete_apps = ['core']

View File

@ -1346,7 +1346,7 @@ class Libpref(models.Model):
marc_link_target = models.CharField( marc_link_target = models.CharField(
max_length=6, max_length=6,
default = 'UNGLUE', default = 'UNGLUE',
choices = settings.MARC_CHOICES, choices = settings.MARC_PREF_OPTIONS,
verbose_name="MARC record link targets" verbose_name="MARC record link targets"
) )
@ -1505,17 +1505,33 @@ class Press(models.Model):
note = models.CharField(max_length=140, blank=True) note = models.CharField(max_length=140, blank=True)
class MARCRecord(models.Model): class MARCRecord(models.Model):
xml_record = models.URLField(blank=True)
mrc_record = models.URLField(blank=True)
edition = models.ForeignKey("Edition", related_name="MARCrecords", null=True) edition = models.ForeignKey("Edition", related_name="MARCrecords", null=True)
# this is where the download link points to, direct link or via Unglue.it. # this is where the download link points to, direct link or via Unglue.it.
link_target = models.CharField(max_length=6,choices = settings.MARC_CHOICES, default='DIRECT') link_target = models.CharField(max_length=6,choices = settings.MARC_CHOICES, default='DIRECT')
@property
def accession(self):
zeroes = 9 - len(str(self.id))
return 'ung' + zeroes*'0' + str(self.id)
@property
def xml_record(self):
return self._record('xml')
@property
def mrc_record(self):
return self._record('mrc')
def _record(self, filetype):
test = '' if '/unglue.it' in settings.BASE_URL else '_test'
if self.link_target == 'DIRECT':
fn = '_unglued.'
elif self.link_target == 'UNGLUE':
fn = '_via_unglueit.'
else:
fn = '_ungluing.'
return 'marc' + test + '/' + self.accession + fn + filetype
def clean(self):
from django.core.exceptions import ValidationError
super(MARCRecord, self).clean()
if not self.xml_record and not self.mrc_record:
raise ValidationError('You must have at least one of xml_record and mrc_record')
# this was causing a circular import problem and we do not seem to be using # this was causing a circular import problem and we do not seem to be using
# anything from regluit.core.signals after this line # anything from regluit.core.signals after this line
# from regluit.core import signals # from regluit.core import signals

View File

@ -18,19 +18,16 @@ from django.core.urlresolvers import reverse
from regluit.core import models from regluit.core import models
def makemarc(marcfile, edition): def makemarc(marcfile, edition):
"""
fyi if we're going to suck down LOC records directly:
parse_xml_to_array takes a file, so we need to faff about with file writes
would be nice to have a suitable z39.50
can use LCCN to grab record with urllib, but file writes are inconsistent
"""
license = edition.ebooks.all()[0].rights
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.info("Making MARC records for edition %s and license %s" % (edition, license))
if '/unglue.it' in settings.BASE_URL: try:
directory = 'marc' license = edition.ebooks.all()[0].rights
else: ebf = None
directory = 'marc_test' except IndexError:
license = None
ebf = edition.ebook_files.all()[0]
logger.info("Making MARC records for edition %s " % edition)
record = pymarc.parse_xml_to_array(marcfile)[0] record = pymarc.parse_xml_to_array(marcfile)[0]
@ -50,11 +47,11 @@ def makemarc(marcfile, edition):
# create accession number and write 001 field # create accession number and write 001 field
# (control field syntax is special) # (control field syntax is special)
(marc_record, created) = models.MARCRecord.objects.get_or_create(edition=edition,link_target='DIRECT') if ebf:
marc_id = marc_record.id (marc_record, created) = models.MARCRecord.objects.get_or_create(edition=edition,link_target='B2U')
zeroes = 9 - len(str(marc_id)) else:
accession = 'ung' + zeroes*'0' + str(marc_id) (marc_record, created) = models.MARCRecord.objects.get_or_create(edition=edition,link_target='UNGLUE')
field001 = pymarc.Field(tag='001', data=accession) field001 = pymarc.Field(tag='001', data=marc_record.accession)
record.add_ordered_field(field001) record.add_ordered_field(field001)
# add field indicating record originator # add field indicating record originator
@ -142,34 +139,35 @@ def makemarc(marcfile, edition):
field300.delete_subfield('a') field300.delete_subfield('a')
field300.add_subfield('a', new300a) field300.add_subfield('a', new300a)
field300.delete_subfield('c') field300.delete_subfield('c')
# add 536 field (funding information)
if edition.unglued:
funding_info = 'The book is available as a free download thanks to the generous support of interested readers and organizations, who made donations using the crowd-funding website Unglue.it.'
else:
if edition.ebooks.all()[0].rights in ['CC BY', 'CC BY-NC-SA', 'CC BY-NC-ND', 'CC BY-NC', 'CC BY-ND', 'CC BY-SA']:
funding_info = 'The book is available as a free download thanks to a Creative Commons license.'
else:
funding_info = 'The book is available as a free download because it is in the Public Domain.'
field536 = pymarc.Field(
tag='536',
indicators = [' ', ' '],
subfields = [
'a', funding_info,
]
)
record.add_ordered_field(field536)
# add 540 field (terms governing use) if license:
field540 = pymarc.Field( # add 536 field (funding information)
tag='540', if edition.unglued:
indicators = [' ', ' '], funding_info = 'The book is available as a free download thanks to the generous support of interested readers and organizations, who made donations using the crowd-funding website Unglue.it.'
subfields = [ else:
'a', dict(settings.CHOICES)[license], if edition.ebooks.all()[0].rights in ['CC BY', 'CC BY-NC-SA', 'CC BY-NC-ND', 'CC BY-NC', 'CC BY-ND', 'CC BY-SA']:
'u', dict(settings.GRANTS)[license], funding_info = 'The book is available as a free download thanks to a Creative Commons license.'
] else:
) funding_info = 'The book is available as a free download because it is in the Public Domain.'
record.add_ordered_field(field540) field536 = pymarc.Field(
tag='536',
indicators = [' ', ' '],
subfields = [
'a', funding_info,
]
)
record.add_ordered_field(field536)
# add 540 field (terms governing use)
field540 = pymarc.Field(
tag='540',
indicators = [' ', ' '],
subfields = [
'a', dict(settings.CHOICES)[license],
'u', dict(settings.GRANTS)[license],
]
)
record.add_ordered_field(field540)
# add 588 field (source of description) - credit where credit is due # add 588 field (source of description) - credit where credit is due
field588 = pymarc.Field( field588 = pymarc.Field(
@ -185,7 +183,7 @@ def makemarc(marcfile, edition):
title = record.get_fields('245')[0].get_subfields('a')[0] title = record.get_fields('245')[0].get_subfields('a')[0]
title = title.split('/')[0] title = title.split('/')[0]
try: try:
oclcnum = edition.identifiers.filter(type='oclc') oclcnum = edition.identifiers.filter(type='oclc')[0].value
except IndexError: except IndexError:
oclcnum = None oclcnum = None
@ -227,25 +225,25 @@ def makemarc(marcfile, edition):
# add 856 fields with links for each available file # add 856 fields with links for each available file
# doing this out of order as it's the only thing that differs # doing this out of order as it's the only thing that differs
# between direct-link and via-unglue.it versions # between direct-link and via-unglue.it versions
# need deepcopy() because omg referential transparency! if not ebf:
record_via_unglueit = deepcopy(record) # need deepcopy() because omg referential transparency!
record_direct = deepcopy(record) # 2 records for unglued stuff
content_types = settings.CONTENT_TYPES for format_tuple in settings.FORMATS:
for format_tuple in settings.FORMATS: format = format_tuple[0]
format = format_tuple[0] ebooks = edition.ebooks.filter(format=format)
ebooks = edition.ebooks.filter(format=format) if ebooks:
if ebooks: for book in ebooks:
for book in ebooks: field856 = pymarc.Field(
field856 = pymarc.Field( tag='856',
tag='856', indicators = ['4', '0'],
indicators = ['4', '0'], subfields = [
subfields = [ '3', format + ' version',
'3', format + ' version', 'q', settings.CONTENT_TYPES[format],
'q', content_types[format], 'u', book.url,
'u', book.url, ]
] )
) record_direct.add_ordered_field(field856)
record.add_ordered_field(field856)
unglued_url = settings.BASE_URL_SECURE + reverse('download', args=[edition.work.id]) unglued_url = settings.BASE_URL_SECURE + reverse('download', args=[edition.work.id])
field856_via = pymarc.Field( field856_via = pymarc.Field(
@ -255,58 +253,35 @@ def makemarc(marcfile, edition):
'u', unglued_url, 'u', unglued_url,
] ]
) )
record_via_unglueit.add_ordered_field(field856_via) record.add_ordered_field(field856_via)
# this via_unglueit record needs its own accession number if not ebf:
field001 = record_via_unglueit.get_fields('001')[0] # this via_unglueit record needs its own accession number
record_via_unglueit.remove_field(field001) field001 = record_direct.get_fields('001')[0]
(marc_record_via, created) = models.MARCRecord.objects.get_or_create(edition=edition,link_target='UNGLUE') record_direct.remove_field(field001)
marc_id_via = marc_record_via.id (marc_record_direct, created) = models.MARCRecord.objects.get_or_create(edition=edition,link_target='DIRECT')
zeroes = 9 - len(str(marc_id_via)) field001 = pymarc.Field(tag='001', data=marc_record_direct.accession)
accession_via = 'ung' + zeroes*'0' + str(marc_id_via) marc_record_direct.add_ordered_field(field001)
field001 = pymarc.Field(tag='001', data=accession_via)
record_via_unglueit.add_ordered_field(field001)
# write the unglued MARCxml records # write the unglued MARCxml records
xml_filename = directory + '/' + accession + '_unglued.xml' xmlrecord = pymarc.record_to_xml(record_direct)
xmlrecord = pymarc.record_to_xml(record) xml_file = default_storage.open(marc_record_direct.xml_record, 'w')
xml_file = default_storage.open(xml_filename, 'w') xml_file.write(xmlrecord)
xml_file.write(xmlrecord) xml_file.close()
xml_file.close()
logger.info("MARCXML record for edition %s written to S3" % edition)
xml_filename_via = directory + '/' + accession_via + '_via_unglueit.xml' # write the unglued .mrc records, then save to s3
xmlrecord = pymarc.record_to_xml(record_via_unglueit) mrc_file = default_storage.open(marc_record_direct.mrc_record, 'w')
xml_file = default_storage.open(xml_filename_via, 'w') writer = pymarc.MARCWriter(mrc_file)
writer.write(record_direct)
mrc_file.close()
xmlrecord = pymarc.record_to_xml(record)
xml_file = default_storage.open(marc_record.xml_record, 'w')
xml_file.write(xmlrecord) xml_file.write(xmlrecord)
xml_file.close() xml_file.close()
logger.info("MARCXML record for edition %s via unglue.it written to S3" % edition)
# write the unglued .mrc records, then save to s3 mrc_file = default_storage.open(marc_record.mrc_record, 'w')
string = StringIO() writer = pymarc.MARCWriter(mrc_file)
mrc_filename = directory + '/' + accession + '_unglued.mrc'
writer = pymarc.MARCWriter(string)
writer.write(record) writer.write(record)
mrc_file = default_storage.open(mrc_filename, 'w')
mrc_file.write(string.getvalue())
mrc_file.close() mrc_file.close()
logger.info(".mrc record for edition %s written to S3" % edition)
string = StringIO()
mrc_filename_via = directory + '/' + accession_via + '_via_unglueit.mrc'
writer = pymarc.MARCWriter(string)
writer.write(record_via_unglueit)
mrc_file = default_storage.open(mrc_filename_via, 'w')
mrc_file.write(string.getvalue())
mrc_file.close()
logger.info(".mrc record for edition %s via unglue.it written to S3" % edition)
marc_record.xml_record = default_storage.url(xml_filename)
marc_record.mrc_record = default_storage.url(mrc_filename)
marc_record.link_target = 'DIRECT'
marc_record.save()
marc_record_via.xml_record = default_storage.url(xml_filename_via)
marc_record_via.mrc_record = default_storage.url(mrc_filename_via)
marc_record_via.link_target = 'UNGLUE'
marc_record_via.save()
logger.info("MARCRecord instances complete for edition %s with accession numbers %s and %s" % (edition, accession, accession_via))

View File

@ -97,8 +97,8 @@ ul.local li {
<p>The options are:</p> <p>The options are:</p>
<ul class="local"> <ul class="local">
<li> Raw link. MARC records link direct to provider (one click, no help) </li> <li> Raw link if available. MARC records link direct to provider (one click, no help, not available for "Buy-to-unglue" titles) </li>
<li> Unglue.it link. MARC records link through Unglue.it download page (extra click, context sensitive help for getting files onto user's device)</li> <li> Unglue.it link. MARC records link through Unglue.it download page (extra click, library user authentication, context sensitive help for getting files onto user's device)</li>
</ul> </ul>
<p>You can <a href="{% url marc_config %}">change your preferences here</a>.</p> <p>You can <a href="{% url marc_config %}">change your preferences here</a>.</p>

View File

@ -405,9 +405,9 @@
{% for record in edition.MARCrecords.all %} {% for record in edition.MARCrecords.all %}
Download {{record.link_target}} MARC record for this edition: (<a href="{% url marc_concatenate %}?record_{{ record.id }}=on&amp;format=xml">XML</a>) (<a href="{% url marc_concatenate %}?record_{{ record.id }}=on&amp;format=mrc">mrc</a>)<br /> Download {{record.link_target}} MARC record for this edition: (<a href="{% url marc_concatenate %}?record_{{ record.id }}=on&amp;format=xml">XML</a>) (<a href="{% url marc_concatenate %}?record_{{ record.id }}=on&amp;format=mrc">mrc</a>)<br />
{% endfor %} {% endfor %}
{% if user.is_staff and edition.ebooks.count %} {% if user.is_staff %}{% if edition.ebooks.count or edition.ebook_files.count %}
<a href="{% url MARCUngluify %}?edition={{ edition.id }}">Upload</a> a MARC record for this edition. <br /> <a href="{% url MARCUngluify %}?edition={{ edition.id }}">Upload</a> a MARC record for this edition. <br />
{% endif %} {% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -2803,13 +2803,15 @@ def marc(request, userlist=None):
except: except:
if not request.user.is_anonymous(): if not request.user.is_anonymous():
libpref = models.Libpref(user=request.user) libpref = models.Libpref(user=request.user)
unwanted = 'UNGLUE' if link_target == 'DIRECT' else 'DIRECT'
if userlist: if userlist:
records = [] records = []
user = get_object_or_404(User,username=userlist) user = get_object_or_404(User,username=userlist)
for work in user.wishlist.works.all(): for work in user.wishlist.works.all():
records.extend(models.MARCRecord.objects.filter(edition__work=work,link_target=link_target)) records.extend(models.MARCRecord.objects.filter(edition__work=work,link_target=link_target))
records.extend(models.MARCRecord.objects.filter(edition__work=work,link_target='B2U'))
else: else:
records = models.MARCRecord.objects.filter(link_target=link_target) records = models.MARCRecord.objects.exclude(link_target=unwanted)
return render( return render(
request, request,
'marc.html', 'marc.html',
@ -2827,7 +2829,7 @@ class MARCUngluifyView(FormView):
edition = self.request.GET.get('edition',None) edition = self.request.GET.get('edition',None)
if models.Edition.objects.filter(id=edition).count(): if models.Edition.objects.filter(id=edition).count():
edition = models.Edition.objects.filter(id=edition)[0] edition = models.Edition.objects.filter(id=edition)[0]
if edition.ebooks.count(): if edition.ebooks.count() or edition.ebook_files.count():
return {'edition':edition.id} return {'edition':edition.id}
return {} return {}
@ -2873,15 +2875,6 @@ class MARCConfigView(FormView):
return super(MARCConfigView, self).form_valid(form) return super(MARCConfigView, self).form_valid(form)
def marc_concatenate(request): def marc_concatenate(request):
"""
options for future work...
cache files: keep records of each combo created, check before building anew?
dispatch as background process, email when done?
if not caching, delete files on s3 after a while?
make the control flow suck less during file write
Can be used as a GET URL
"""
if request.method == 'POST': if request.method == 'POST':
params=request.POST params=request.POST
elif request.method == 'GET': elif request.method == 'GET':
@ -2901,45 +2894,35 @@ def marc_concatenate(request):
) )
return HttpResponseRedirect(reverse('marc', args=[])) return HttpResponseRedirect(reverse('marc', args=[]))
# keep test files from stepping on production files preamble = ('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
if '/unglue.it' in settings.BASE_URL:
directory = 'marc/'
else:
directory = 'marc_test/'
# write the concatenated file
datestamp = now().strftime('%Y%m%d%H%M%S')
filename = directory + datestamp + '.' + format
with default_storage.open(filename, 'w') as outfile:
if format == 'xml':
string = ('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
'<collection ' '<collection '
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
'xmlns="http://www.loc.gov/MARC21/slim" ' 'xmlns="http://www.loc.gov/MARC21/slim" '
'xsi:schemaLocation="http://www.loc.gov/MARC21/slim ' 'xsi:schemaLocation="http://www.loc.gov/MARC21/slim '
'http://www.loc.gov/standards/marcxml/schema/' 'http://www.loc.gov/standards/marcxml/schema/'
'MARC21slim.xsd">') 'MARC21slim.xsd">')
outfile.write(string) outfile = HttpResponse('', content_type='application/marc')
for record in selected_records: outfile['Content-Disposition'] = 'attachment; filename='+ now().strftime('%Y%m%d%H%M%S') + '.' + format
record_id = long(record[7:])
if format == 'xml': if format == 'xml':
record_url = models.MARCRecord.objects.get( outfile.write(preamble)
pk=record_id for record in selected_records:
).xml_record record_id = long(record[7:])
logger.info(record_url)
elif format == 'mrc':
record_url = models.MARCRecord.objects.get(
pk=record_id
).mrc_record
logger.info(record_url)
try:
record_file = urllib.urlopen(record_url).read()
outfile.write(record_file)
except IOError:
logger.warning('MARC record with id number %s has a problem with its URL' % record_id)
if format == 'xml': if format == 'xml':
string = ('</collection>') record_url = models.MARCRecord.objects.get(
outfile.write(string) pk=record_id
download_url = default_storage.url(filename) ).xml_record
return HttpResponseRedirect(download_url) elif format == 'mrc':
record_url = models.MARCRecord.objects.get(
pk=record_id
).mrc_record
try:
record_file = default_storage.open(record_url).read()
outfile.write(record_file)
except IOError:
logger.warning('MARC record with id number %s has a problem with its URL' % record_id)
if format == 'xml':
outfile.write('</collection>')
return outfile

View File

@ -407,6 +407,11 @@ CONTENT_TYPES = {
MARC_CHOICES = ( MARC_CHOICES = (
('DIRECT', 'Raw link'), ('DIRECT', 'Raw link'),
('UNGLUE', 'Unglue.it link'), ('UNGLUE', 'Unglue.it link'),
('B2U', 'Library link'),
)
MARC_PREF_OPTIONS =(
('DIRECT', 'Raw link'),
('UNGLUE', 'Unglue.it link'),
) )
BOOXTREAM_API_KEY = '7ynRCsx4q21zEY67it7yk8u5rc6EXY' BOOXTREAM_API_KEY = '7ynRCsx4q21zEY67it7yk8u5rc6EXY'