Initial commit
Initial commit

file:b/.gitignore (new)
  *.egg-info
  *.pyc
  *.swp
  *.swo
  *~
  #*
  .#*
  build/
  dist/
  distribute-*
file:b/README.rst (new)
  This CKAN Extension customises a CKAN instance for the hosting of data.gov.au.
 
  It comprises:
 
  * A path to local customisations of the core templates to include AGLS/Dublin Core minimum metadata
  * A custom n3/rdf output format
 
  Installation
  ============
 
  To install this package, from your CKAN virtualenv, run the following from your CKAN base folder (e.g. ``pyenv/``)::
 
  pip install -e git+https://github.com/okfn/ckanext-datagovau#egg=ckanext-datagovau
 
  Then activate it by setting ``ckan.plugins = datagovau`` in your main ``ini``-file.
 
 
  # this is a namespace package
  try:
  import pkg_resources
  pkg_resources.declare_namespace(__name__)
  except ImportError:
  import pkgutil
  __path__ = pkgutil.extend_path(__path__, __name__)
 
  import logging
 
  import ckan.plugins as plugins
  import ckan.lib as lib
  import ckan.lib.dictization.model_dictize as model_dictize
  import ckan.plugins.toolkit as tk
  import ckan.model as model
  from pylons import config
 
  from sqlalchemy import orm
  import ckan.model
 
  #parse the activity feed for last active non-system user
  def get_last_active_user(id):
  system_user = lib.helpers.get_action('user_show',{'id': config.get('ckan.site_id', 'ckan_site_user')})
  user_list = [x for x in lib.helpers.get_action('package_activity_list',{'id':id}) if x['user_id'] != system_user['id']]
  user = None
  if len(user_list) > 0:
  user = user_list[0].get('user_id', None)
  if user is None:
  return system_user
  else:
  return lib.helpers.get_action('user_show',{'id':user})
 
  class AGLSPlugin(plugins.SingletonPlugin,
  tk.DefaultDatasetForm):
  '''An example IDatasetForm CKAN plugin.
 
  Uses a tag vocabulary to add a custom metadata field to datasets.
 
  '''
  plugins.implements(plugins.IConfigurer, inherit=False)
  plugins.implements(plugins.IDatasetForm, inherit=False)
  plugins.implements(plugins.ITemplateHelpers, inherit=False)
 
  def update_config(self, config):
  # Add this plugin's templates dir to CKAN's extra_template_paths, so
  # that CKAN will use this plugin's custom templates.
  # here = os.path.dirname(__file__)
  # rootdir = os.path.dirname(os.path.dirname(here))
 
  tk.add_template_directory(config, 'templates')
  tk.add_public_directory(config, 'theme/public')
  tk.add_resource('theme/public', 'ckanext-agls')
  # config['licenses_group_url'] = 'http://%(ckan.site_url)/licenses.json'
 
  def get_helpers(self):
  return {'get_last_active_user': get_last_active_user}
 
  def is_fallback(self):
  # Return True to register this plugin as the default handler for
  # package types not handled by any other IDatasetForm plugin.
  return True
 
  def package_types(self):
  # This plugin doesn't handle any special package types, it just
  # registers itself as the default (above).
  return []
 
 
  def create_package_schema(self):
  schema = super(AGLSPlugin, self).create_package_schema()
  schema = self._modify_package_schema(schema)
  return schema
 
  def update_package_schema(self):
  schema = super(AGLSPlugin, self).update_package_schema()
  schema = self._modify_package_schema(schema)
  return schema
 
  def show_package_schema(self):
  schema = super(AGLSPlugin, self).show_package_schema()
 
  # Don't show vocab tags mixed in with normal 'free' tags
  # (e.g. on dataset pages, or on the search page)
  schema['tags']['__extras'].append(tk.get_converter('free_tags_only'))
 
  # Add our custom_text field to the dataset schema.
  # ignore_missing == optional
  # ignore_empty == mandatory but not for viewing
  # !!! always convert_from_extras first
  schema.update({
  'agency_program': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_missing')],
  'contact_point': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'spatial_coverage': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'granularity': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'jurisdiction': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'temporal_coverage': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'data_state': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')],
  'update_freq': [tk.get_converter('convert_from_extras'),
  tk.get_validator('ignore_empty')]
  })
  return schema
 
  def _modify_package_schema(self, schema):
  # Add our custom_test metadata field to the schema, this one will use
  # convert_to_extras instead of convert_to_tags.
  # ignore_missing == optional
  # not_empty == mandatory, enforced here while modifying
 
  schema.update({
  'agency_program': [tk.get_validator('ignore_missing'),
  tk.get_converter('convert_to_extras')],
  'contact_point': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'spatial_coverage': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'granularity': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'jurisdiction': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'temporal_coverage': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'data_state': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')],
  'update_freq': [tk.get_converter('convert_to_extras'),
  tk.get_validator('not_empty')]
  })
  return schema
 
 
  {% ckan_extends %}
  {% block package_additional_info %}
  <section class="additional-info" prefix="dc: http://purl.org/dc/elements/1.1/ dcat: http://www.w3.org/ns/dcat#
  dcam: http://purl.org/dc/dcam/
  aglsterms: http://www.agls.gov.au/agls/terms/
  agentterms: http://www.agls.gov.au/agls/agentterms/
  availterms: http://www.agls.gov.au/agls/availterms/
  adminterms: http://www.agls.gov.au/agls/adminterms/
  dct: http://purl.org/dc/terms/">
  <h3>{{ _('Additional Info') }}</h3>
  <table class="table table-striped table-bordered table-condensed">
  <thead>
  <tr>
  <th scope="col">{{ _('Field') }}</th>
  <th scope="col">{{ _('Value') }}</th>
  </tr>
  </thead>
  <tbody>
 
 
  {# Add our custom field to the dataset read page. #}
  {% if pkg.get('metadata_created') %}
  <tr>
  <th scope="row" class="dataset-label">Date Published</th>
  <td class="dataset-details" property="dct:issued">{{ pkg.metadata_created.split("T")[0] }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('metadata_updated') %}
  <tr>
  <th scope="row" class="dataset-label">Date Updated</th>
  <td class="dataset-details" property="dct:updated">{{ pkg.metadata_updated.split("T")[0] }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('agency_program') %}
  <tr>
  <th scope="row" class="dataset-label">Agency Program</th>
  <td class="dataset-details"> {{ pkg.agency_program }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('url') %}
  <tr>
  <th scope="row" class="dataset-label">{{ _('Source') }}</th>
  <td class="dataset-details" property="dct:source">{{ h.link_to(pkg.get('url'),
  pkg.get('url'), rel='dct:source', target='_blank') }}
  </td>
  </tr>
  {% endif %}
 
  {% if pkg.get('contact_point') %}
  <tr>
  <th scope="row" class="dataset-label">Contact Point</th>
  <td class="dataset-details" property="dcat:contactPoint"> {{ h.mail_to(email_address=pkg.contact_point,
  name=pkg.contact_point) }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('spatial_coverage') %}
 
  <tr>
  <th scope="row" class="dataset-label">Geospatial Coverage</th>
  <td class="dataset-details" property="dct:spatial"> {{ pkg.spatial_coverage }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('granularity') %}
 
  <tr>
  <th scope="row" class="dataset-label">Data Granularity</th>
  <td class="dataset-details"> {{ pkg.granularity }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('jurisdiction') %}
  <tr>
  <th scope="row" class="dataset-label">Government Jurisdiction</th>
  <td class="dataset-details" property="aglsterms:AglsJuri"> {{ pkg.jurisdiction }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('temporal_coverage') %}
  <tr>
  <th scope="row" class="dataset-label">Temporal Coverage</th>
  <td class="dataset-details" property="dct:temporal"> {{ pkg.temporal_coverage }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('data_state') %}
  <tr>
  <th scope="row" class="dataset-label">Data State</th>
  <td class="dataset-details"> {{ pkg.data_state }}</td>
  </tr>
  {% endif %}
  {% if pkg.get('update_freq') %}
 
  <tr>
  <th scope="row" class="dataset-label">Update Frequency</th>
  <td class="dataset-details"> {{ pkg.update_freq }}</td>
  </tr>
  {% endif %}
 
  {% set email =h.get_last_active_user(c.pkg_dict['id']).get('email','') %}
  <tr>
  <th scope="row" class="dataset-label">{{ _('Maintainer') }}</th>
  <td class="dataset-details" property="dc:contributor">{{
  h.mail_to(email_address=(email or ' '), name=h.get_last_active_user(c.pkg_dict['id']).get("display_name",'')) }}
  </td>
  </tr>
  <tr>
  <th scope="row" class="dataset-label">Publisher/Agency</th>
  <td class="dataset-details" property="dc:publisher">{{ c.pkg_dict['organization']['title']}}
  </td>
  </tr>
  <tr>
  <th scope="row" class="dataset-label">Type</th>
  <td class="dataset-details" property="dc:type">Dataset</td>
  </tr>
  <tr>
  <th scope="row" class="dataset-label">Language</th>
  <td class="dataset-details" property="dc:language">English</td>
  </tr>
 
  </tbody>
  </table>
  </section>
 
 
  {% endblock %}
 
 
  <?xml version="1.0" encoding="utf-8"?>
  <rdf:RDF
  xmlns:py="http://genshi.edgewall.org/"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:owl="http://www.w3.org/2002/07/owl#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dcat="http://www.w3.org/ns/dcat#"
  xmlns:dcam="http://purl.org/dc/dcam/"
  xmlns:aglsterms="http://www.agls.gov.au/agls/terms/"
  xmlns:agentterms="http://www.agls.gov.au/agls/agentterms/"
  xmlns:availterms="http://www.agls.gov.au/agls/availterms/"
  xmlns:adminterms="http://www.agls.gov.au/agls/adminterms/"
  xmlns:dct="http://purl.org/dc/terms/"
  >
  <dcat:Dataset rdf:about="${ h.url_for(controller='package',action='read',id=c.pkg_dict['name'], qualified=True)}">
  <dct:identifier>${c.pkg_dict['name']}</dct:identifier>
  <dct:title>${c.pkg_dict['title']}</dct:title>
  <dct:landingPage
  rdf:resource="${ h.url_for(controller='package',action='read',id=c.pkg_dict['name'], qualified=True) }"/>
  <owl:sameAs rdf:resource="urn:uuid:${c.pkg_dict['id']}"/>
  <dct:type>Dataset</dct:type>
  <dct:description>${c.pkg_dict['notes']}</dct:description>
  <dct:issued>${c.pkg_dict['metadata_created']}</dct:issued>
  <dct:modified>${c.pkg_dict['metadata_modified']}</dct:modified>
 
  <py:choose>
  <py:when test="c.pkg_dict.get('license_url',None)">
  <dct:license rdf:resource="${c.pkg_dict['license_url']}"/>
  <dct:rights rdf:resource="${c.pkg_dict['license_url']}"/>
  </py:when>
  <py:otherwise>
  <dct:license>${c.pkg_dict['license_id']}</dct:license>
  <dct:rights>"${c.pkg_dict['license_id']}"</dct:rights>
  </py:otherwise>
  </py:choose>
  <py:for each="tag_dict in c.pkg_dict.get('tags',[])">
  <dcat:keyword>${ tag_dict["name"] }</dcat:keyword>
  </py:for>
 
 
  <py:for each="rsc_dict in c.pkg_dict['resources']">
  <dcat:distribution>
  <dcat:Distribution>
  <dct:title>${rsc_dict.get('name')}</dct:title>
  <owl:sameAs rdf:resource="urn:uuid:${rsc_dict.get('id')}"/>
  <dct:description>${rsc_dict.get('description')}</dct:description>
  <dcat:accessURL rdf:resource="${ rsc_dict.get('url') }"/>
  <dct:created>${rsc_dict.get('created')}</dct:created>
  <dct:modified>${rsc_dict.get('revision_timestamp')}</dct:modified>
  <dcat:byteSize py:if="rsc_dict.get('size')">${rsc_dict.get('size')}</dcat:byteSize>
  <dcat:mediaType py:if="rsc_dict.get('mimetype')">${rsc_dict.get('mimetype')}</dcat:mediaType>
  <dct:extent py:if="rsc_dict.get('size')">${rsc_dict.get('size')} bytes</dct:extent>
  <dct:format py:if="rsc_dict.get('format')">
  <dct:IMT>
  <rdf:value>${rsc_dict.get('format')}</rdf:value>
  <rdfs:label>${rsc_dict.get('format')}</rdfs:label>
  </dct:IMT>
  </dct:format>
  <dct:title py:if="rsc_dict.get('name')">${rsc_dict.get('name')}</dct:title>
  </dcat:Distribution>
  </dcat:distribution>
  </py:for>
 
 
  <!-- data.gov.au specific stuff below this line -->
  <dct:publisher py:if="c.pkg_dict.get('organization', None)">
  <rdf:Description>
  <foaf:name>${ c.pkg_dict['organization']['title'] }</foaf:name>
  </rdf:Description>