Source code for minsci.xmu.containers.bibliorecord

"""Subclass of XMuRecord with methods specific to emultimedia"""

import re

from dateparser import parse

from .xmurecord import XMuRecord
from ...helpers import oxford_comma


[docs]class BiblioRecord(XMuRecord): """Subclass of XMuRecord with methods specific to ebibliography""" def __init__(self, *args, **kwargs): super(BiblioRecord, self).__init__(*args, **kwargs) self.module = 'ebibliography' self.prefix = self.get_prefix() self.masks = { 'Art': (u'{authors}, {year}. "{title}." <i>{source}</i>,' ' {volume}({issue}): {pages}'), 'Boo': (u'{authors}, {year}. {title}. In <i>{source}</i> ' ' (v. {volume}), {pages}p.'), 'Oth': u'{title}', 'Web': u'{title} <<a href="{identifier}">{identifier}</a>>' } def __call__(self, *args, **kwargs): """Shorthand for XMuRecord.smart_pull(*args)""" args = [self.prefix + arg[3:] if arg.startswith('Art') else arg for arg in args] try: return self.smart_pull(*args) except KeyError: print 'Path not found:', args return '' def __getattribute__(self, key): val = object.__getattribute__(self, key) if key == 'prefix' and not val and self.is_biblio(): prefix = self.get_prefix() self.prefix = prefix return prefix return val
[docs] def get_prefix(self): """Get prefix based on record type or keys""" prefix = self('BibRecordType')[:3] if not prefix and self.is_biblio(): prefixes = {} for key in self: prefixes.setdefault(key[:3], 0) prefixes[key[:3]] += 1 prefix = [key for key, val in prefixes.iteritems() if val == max(prefixes.values())][0] return prefix
[docs] def is_biblio(self): """Checks if record is a reference""" prefixes = ('Art', 'Bib', 'Boo', 'Bos', 'Jou') return bool([key for key in self if key.startswith(prefixes)])
[docs] def format_reference(self): """Formats reference according to publication type""" authors = oxford_comma(self.get_authors()) title = self('ArtTitle') # Get publication date pub_date = parse(self('ArtPublicationDates')) if pub_date is not None: year = pub_date.year month = pub_date.month else: pub_date = self('ArtPublicationDates') try: year = re.search(r'\b\d{4}\b', pub_date).group() except AttributeError: year = None month = None # Get periodical/book info source = self.get_source() volume = self('ArtVolume') issue = self('ArtIssue') pages = self('ArtPages') # Get website info identifier = self('WebIdentifier') if not volume and month: try: volume = pub_date.strftime('%b. %Y') except ValueError: pass elif not volume and pub_date != year: volume = pub_date ref = self.masks[self.prefix].format(authors=authors, year=year, title=title, source=source, volume=volume, issue=issue, pages=pages, identifier=identifier) return self.clean_reference(ref)
[docs] def get_authors(self): """Formats a list of author names""" authors = [] for author in self('ArtAuthorsRef_tab'): authors.append(self.format_name(author('NamLast'), author('NamFirst'), author('NamMiddle'))) return authors
[docs] def get_source(self): """Determines the type of the source/parent publication""" sources = { 'Art': 'Jou', 'Boo': 'Bos', 'Cha': 'Boo' } try: return self('ArtParentRef', sources[self.prefix] + 'Title') except KeyError: return ''
[docs] @staticmethod def clean_reference(ref): """Cleans punctuation, etc. left behind when ref has empty fields FIXME: This is horrible """ characters = ['()', ' : ', ' :', ' ,', ' .', '""', '<i></i>', ', p.', '(v. )'] for char in characters: ref = ref.replace(char, ' ') while ' ' in ref: ref = ref.replace(' ', ' ') if ref.endswith('. In '): ref = ref[:-4] return ref
[docs] @staticmethod def format_name(last, first, middle, use_initials=True, mask='{last}, {first} {middle}'): """Formats a name according to the given mask""" if use_initials: first = first[0] + '.' if first else '' middle = middle[0] + '.' if middle else '' return mask.format(last=last, first=first, middle=middle).rstrip()