Overview
========

The Publication Product can be used to organise printed publications that are
available online for download. Publications usually have a publication date,
order and ISBN numbers, an author and exist in several language versions.
Once stored in the Publication Product, they can be displayed using
autogenerated overviews. 

Note: You can run the tests in this file by typing

    zopectl test -m slc.publications


Adding Publications
===================

    >>> self.loginAsPortalOwner()

We will add publications with LinguaPlone support, so we need to setup some languages:

    >>> portal_languages = self.portal.portal_languages
    >>> portal_languages.addSupportedLanguage('en')
    >>> portal_languages.addSupportedLanguage('de')
    >>> portal_languages.getSupportedLanguages()
    ['en', 'de']
    
It depends on your portal settings whether a new object is language neutral or gets the 
default language. 

    >>> default_language = portal_languages.start_neutral and '' or portal_languages.getDefaultLanguage()

Publications are File objects. What makes them Publications are certain 
additional metadata which characterise the File closer. By enhancing the 
default File object, we stay updatable using the core Plone mechanisms and 
do not introduce yet another content type.

    >>> _ = self.portal.invokeFactory('File', 'mypub')
    >>> mypub = self.portal.mypub
    >>> mypub.Language() == default_language
    True
    >>> mypub.setTitle('My english File')
    >>> mypub.setDescription('My english File description')
    >>> mypub.Title()
    'My english File'
    >>> mypub.Language()
    'en'
    
Now we use subtyping to make this file a publication.

    >>> from p4a.subtyper.interfaces import ISubtyper
    >>> from zope.component import getUtility
    >>> subtyper = getUtility(ISubtyper)
    >>> possible_types = [x.name for x in subtyper.possible_types(mypub)]
    >>> 'slc.publications.Publication' in possible_types
    True
    >>> subtyper.existing_type(mypub) is None
    True
    >>> subtyper.change_type(mypub, 'slc.publications.Publication')
    >>> subtyper.existing_type(mypub).name
    'slc.publications.Publication'
    
    

Now we load a demonstration pdf file from doc/UsingthePublicationProduct.pdf which has the following metadata set within the pdf file:

    - Title: Using the Publication Product
    - Description: The Publication Product can be used ...
    - Keywords: documentation, tutorial
    - Language: en

    >>> docpdf = self.loadfile('doc/UsingthePublicationProduct.pdf')
    >>> mypub.setFile(docpdf)

# Finish the object creation. If we don't do that, processForm in combination with blobs will 
# throw the "DemoStorage instance has no attribute 'temporaryDirectory'" error. Apparently because 
# the test doesn't use Blobstorage with Plone3.1
    >>> mypub.unmarkCreationFlag() 
    

Once we parse the uploaded file, we will get the file properties as a metadata map.

    >>> from slc.publications.pdf.interfaces import IPDFParser
    >>> pdfparser = getUtility(IPDFParser)
    >>> metadata = pdfparser.parse(docpdf)
    >>> metadata is not False
    True
    
We can now set these metadata onto the object by using the IPublication adapter.

    >>> from slc.publications.interfaces import IPublication
    >>> IPublication(mypub).setMetadataMap(metadata)
    >>> mypub.Title()
    'Using the Publication Product \xe2\x80\x94 Portal'
    >>> mypub.Description()
    'The Publication Product can be used to organise printed publications that are available online for download. Publications usually have a publication date, order and ISBN numbers, an author and exist in several language versions. Once stored in the Publication Product, they can be displayed using autogenerated overviews. Support is built in for easy upload and parsing of metadata.'
    >>> mypub.Subject()
    ('documentation', 'tutorial')



There is a template called publication_listing which shows all contained
publications or the results of a topic with image and quicklinks to download 
the language versions. 
XXX: Todo


Uploading Metadata
==================

If you cannot set your metadata on your pdf files directly but want to use an automated way of uploading them, you can use an ini style config file to specify and upload them. You can find an example in the directory tests/data/metadata.ini.
Such metadata files are uploaded for a Publication object and will try to set metadata for the Publication and its Translations, depending on the ini sections in the file. 

    >>> _ = self.folder.invokeFactory('File', 'metadatapub')
    >>> MetadataPub = self.folder.metadatapub
    >>> MetadataPub.setFile(docpdf)
    >>> MetadataPub.unmarkCreationFlag()
    >>> MetadataPub.Language()
    'en'

We now have an english document (and reused the english pdf file loaded already above).
We add a translation for this.

    >>> MetadataPub.addTranslation('de')
    <ATBlob at /plone/Members/test_user_1_/metadatapub-de>
    >>> MetadataPub_de = MetadataPub.getTranslation('de')
    >>> german_de_pdf = self.loadfile('tests/data/GermanOSHA_de.pdf')
    >>> MetadataPub_de.setFile(german_de_pdf)
    >>> MetadataPub_de.unmarkCreationFlag()
    >>> MetadataPub_de.Language()
    'de'

Now we have two language versions. We upload the metadata file to the main version, and now
the properties on both versions should be set.

    >>> metadataini = self.loadfile('ini/data/metadata.ini')
    
We need to subtype the translated publication as well (this can made much easier...)

    >>> subtyper.change_type(MetadataPub, 'slc.publications.Publication')
    >>> IPublication(MetadataPub).metadata_upload = metadataini
    >>> from slc.publications.ini.interfaces import IINIParser
    >>> iniparser = getUtility(IINIParser)
    >>> metadata = iniparser.parse(metadataini)    
    >>> IPublication(MetadataPub).setMetadataIniMap(metadata)

    >>> ENFile = MetadataPub.getTranslation('en')
    >>> DEFile = MetadataPub.getTranslation('de')
    >>> ENFile.Title()
    'Memorandum of Understanding'

    >>> DEFile.Title()
    'Vereinbarung'

    >>> ENFile.getField('isbn').getAccessor(ENFile)()
    '87-418-5901-5'

    >>> DEFile.getField('isbn').getAccessor(DEFile)()
    '87-418-5901-6'



