tool to check datagov resources
Former-commit-id: f406384c3ba09ba04f639abb5731511ddf02b88b
--- a/about.php
+++ b/about.php
@@ -4,19 +4,12 @@
?>
<div class="foundation-header">
<h1><a href="about.php">About/FAQ</a></h1>
- <h4 class="subheader">Lorem ipsum.</h4>
</div>
-<h2> What is this? </h2>
-Disclo.gs is a project to monitor Australian Federal Government agencies
-compliance with their <a href="http://www.oaic.gov.au/publications/other_operational/foi_policy_frequently_asked_questions.html#_Toc291837571">"proactive disclosure requirements" to make a transparency league table as suggested by gov2 taskforce http://gov2.net.au/blog/2009/09/19/a-league-ladder-of-psi-openness/</a>.
<h2> Attributions </h2>
National Archives of Australia, Australian Governments’ Interactive Functions Thesaurus, 2nd edition, September 2005, published at http://www.naa.gov.au/recordkeeping/thesaurus/index.htm <br/>
data.gov.au http://data.gov.au/dataset/directory-gov-au-full-data-export/ <br/>
directory.gov.au <br/>
australia.gov.au http://australia.gov.au/about/copyright <br/>
-<h2> Open everything </h2>
-All documents released CC-BY 3 AU
-Open source git @
<h2>Organisational Data Sources</h2>
@@ -25,17 +18,17 @@
http://www.finance.gov.au/publications/flipchart/docs/FMACACFlipchart.pdf summarises these. view-source:https://www.tenders.gov.au/?event=public.advancedsearch.home is great for the suspended/active status<br>
-Fraud in gov depts by Fairfax Media http://www.smh.com.au/national/public-service-keeps-fraud-cases-private-20110923-1kpdr.html
+Fraud in gov depts by Fairfax Media http://www.smh.com.au/national/public-service-keeps-fraud-cases-private-20110923-1kpdr.html <br>
When defining the hierachy, this system is designed towards monitoring accountablity. Thus large agencies that have registered their own ABN
-and have their own accountablity mechanisms/website receive a seperate record as a child of their department.
+and have their own accountablity mechanisms/website receive a seperate record as a child of their department.<br>
Some small agencies will choose to simply rely on their parent department's accountablity measures.<br>
-This flows through to organisation name and other/past names. A department that completely accounts for an agency will list that agency as an other child name.
-As agencies themselves shift between departments, there may be scope for providing time ranges but typically the newest hierarchy will be the one recorded.
+This flows through to organisation name and other/past names. A department that completely accounts for an agency will list that agency as an other child name.<br>
+As agencies themselves shift between departments, there may be scope for providing time ranges but typically the newest hierarchy will be the one recorded.<br>
A department/agency name will be the newest active name assigned to that ABN.<br>
-ABN information is derived from the ABR. This is the definitive umpire about which former name should be linked to which current name.
+ABN information is derived from the ABR. This is the definitive umpire about which former name should be linked to which current name. <br>
For example "Department of Transport and Regional Services" became "Department of Infrastructure, Transport, Regional Development and Local Government" (same ABN)
however it later split into "Department of Infrastructure and Transport" (same ABN)
and "Department of Regional Australia, Regional Development and Local Government" (new ABN).<br>
@@ -43,24 +36,7 @@
Statistical information from http://www.apsc.gov.au/stateoftheservice/1011/statsbulletin/section1.html#t2total https://www.apsedii.gov.au/apsedii/CustomQueryx33.shtml
and individual annual reports.<br>
-<h2>Webpage Assessment</h2>
-Much due care has been put into correctly recording disclosure URLs. Typically the "About", "Corporate", "Publications" and "Sitemap" sections are checked at the very least.
-Occasionally it is nessicary to use a site or Google search. In several rare cases, there is a secret "Disclosure" navigation menu you can find if you find one of the mandatory publishing obligations in that category (seriously).<br>
-Some rules about leniency:<br>
-<ul>
- <li>An empty FOI disclosure log counts, a page outlining what the FOI Act is does not.</li>
- <li>A disclosure log in PDF or Word format counts :(</li>
- <li>An empty File/Record list counts (although that's very minimalistic that you have no files, electronic or paper)</li>
- <li>Only a current information publication scheme page counts, not a s.9 FOI Act page or an organisation chart.</li>
- <li>If there isn't a page easily listing all current and past Annual Reports, the most current one (html, pdf) counts.</li>
- <li>Consultancy contracts might not need it's own webpage (if in Annual Report), grants/appointments might not apply to all organisations but Legal Services Expenditure (and all other obligations) does need a webpage. </li>
-
-<h2>Open Government Scoring</h2>
-+1 point for every true Has... attribute<br>
--1 point for every false Has... (ie. Has Not) attribute</br>
-
-Don't like this? Make your own score, suggest a better scoring mechanism.</br>
-
<?php
include_footer();
?>
+
--- a/admin/refreshDesignDoc.php
+++ b/admin/refreshDesignDoc.php
@@ -40,6 +40,9 @@
$obj->views->byURL->map = "function(doc) {\n emit(doc.url, doc);\n}";
$obj->views->agency->map = "function(doc) {\n emit(doc.agencyID, doc);\n}";
$obj->views->byWebServer->map = "function(doc) {\n emit(doc.web_server, doc);\n}";
+
+$obj->views->datasets->map = "function(doc) {\nif (doc.fieldName == \"data\") {\n emit(doc._id, doc);\n}\n}";
+$obj->views->datasetGroups->map = "function(doc) {\nif (doc.fieldName == \"data\") {\n doc.metadata[\"data.gov.au Category\"] && doc.metadata[\"data.gov.au Category\"].forEach(function(tag) {\n emit(tag, doc.url); \n });\n}\n}";
$obj->views->getValidationRequired->map = "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}";
$docdb->save($obj, true);
--- a/bubbletree.php
+++ /dev/null
@@ -1,126 +1,1 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta charset="UTF-8"/>
- <title>Minimal BubbleTree Demo</title>
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script>
- <script type="text/javascript" src="js/bubbletree/lib/jquery.history.js"></script>
- <script type="text/javascript" src="js/bubbletree/lib/raphael.js"></script>
- <script type="text/javascript" src="js/bubbletree/lib/vis4.js"></script>
- <script type="text/javascript" src="js/bubbletree/lib/Tween.js"></script>
- <script type="text/javascript" src="js/bubbletree/build/bubbletree.js"></script>
- <link rel="stylesheet" type="text/css" href="js/bubbletree/build/bubbletree.css" />
- <script type="text/javascript" src="js/bubbletree/styles/cofog.js"></script>
-
-
- <script type="text/javascript">
-
- $(function() {
-<?php
-include_once('include/common.inc.php');
-
-include("lib/Color.php");
-$color = new Lux_Color();
-
-$portfolios = Array();
-$total = 0;
-$db = $server->get_db('disclosr-agencies');
-try {
- $rows = $db->get_view("app", "byDeptStateName", null, true)->rows;
- foreach ($rows as $row) {
- $portfolios[trim(str_replace(Array("Department of", "Department", "the", "'", "`"), "", $row->key))] = $row->value;
- }
-} catch (SetteeRestClientException $e) {
- setteErrorHandler($e);
-}
-
-$agencies = Array();
-try {
- $rows = $db->get_view("app", "byCanonicalName", null, true)->rows;
-//print_r($rows);
- foreach ($rows as $row) {
- $employees = 0;
- $portfolioid = 0;
- if (isset($row->value->employees)) {
- $employees = $row->value->employees;
- }
- if (isset($row->value->statistics->employees)) {
- $agencyEmployeesArray = object_to_array($row->value->statistics->employees);
- if (isset($agencyEmployeesArray["2010-2011"]["value"])) {
- $employees = $agencyEmployeesArray["2010-2011"]["value"];
- } else {
- // bailout for agencies that are closed for business
- continue;
- }
- }
- if (!($employees > 0)) {
- $employees = 0;
- }
- if (isset($row->value->parentOrg)) {
- $portfolioid = $row->value->parentOrg;
- }
- if (isset($row->value->orgType) && $row->value->orgType == "FMA-DepartmentOfState") {
- $portfolioid = $row->id;
- }
- $agencies[$portfolioid][$row->value->name] = $employees;
- }
-} catch (SetteeRestClientException $e) {
- setteErrorHandler($e);
-}
-//print_r($portfolios);
-//print_r($agencies);
-
-// http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
-$golden_ratio_conjugate = 0.618033988749895;
-$h = 0.00+rand(0,10)/10; # use random start value
-foreach ($portfolios as $portfolioName => $portfolioID) {
- $h += $golden_ratio_conjugate;
-
- $h = fmod($h,1);
- $portfolioColor = $color->hsv2hex(Array($h, .3, .99));
- $subnodes = Array();
- $portfolioEmployees = 0;
- foreach ($agencies[$portfolioID] as $agencyName => $agencyEmployees) {
- $agencyColor = $color->hsv2hex(Array($h / 10, rand(1, 10) / 10, abs(($h * (1 / 10)) - .5) + .5));
- $subnodes[] = Array(
- "label" => str_replace(Array("'", "`"), "", $agencyName),
- "amount" => $agencyEmployees,
- //"color" => "#" . $agencyColor
- );
- $portfolioEmployees += $agencyEmployees;
- }
- $nodes[] = Array(
- "label" => $portfolioName,
- "amount" => $portfolioEmployees,
- //"color" => "#" . $portfolioColor,
- "children" => $subnodes
- );
- $total += $portfolioEmployees;
-}
-$data = Array(
- "label" => "Australian Federal Government",
- "amount" => $total,
- //"color" => "#000000",
- "children" => $nodes
-);
-echo "var data =eval('('+'" . json_encode($data) . "'+')');";
-?>
-
- new BubbleTree({
- data: data,
- container: '.bubbletree'
- });
-
-
- });
-
- </script>
- </head>
- <body>
- <div class="bubbletree-wrapper">
- <div class="bubbletree"></div>
- </div>
- </body>
-</html>
-
--- /dev/null
+++ b/budget.php
@@ -1,1 +1,124 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta charset="UTF-8"/>
+ <title>Minimal BubbleTree Demo</title>
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script>
+ <script type="text/javascript" src="js/bubbletree/lib/jquery.history.js"></script>
+ <script type="text/javascript" src="js/bubbletree/lib/raphael.js"></script>
+ <script type="text/javascript" src="js/bubbletree/lib/vis4.js"></script>
+ <script type="text/javascript" src="js/bubbletree/lib/Tween.js"></script>
+ <script type="text/javascript" src="js/bubbletree/build/bubbletree.js"></script>
+ <link rel="stylesheet" type="text/css" href="js/bubbletree/build/bubbletree.css" />
+ <script type="text/javascript" src="js/bubbletree/styles/cofog.js"></script>
+
+
+ <script type="text/javascript">
+
+ $(function() {
+<?php
+include_once('include/common.inc.php');
+
+include("lib/Color.php");
+$color = new Lux_Color();
+
+$portfolios = Array();
+$total = 0;
+$db = $server->get_db('disclosr-agencies');
+try {
+ $rows = $db->get_view("app", "byDeptStateName", null, true)->rows;
+ foreach ($rows as $row) {
+ $portfolios[trim(str_replace(Array("Department of", "Department", "the", "'", "`"), "", $row->key))] = $row->value;
+ }
+} catch (SetteeRestClientException $e) {
+ setteErrorHandler($e);
+}
+
+$agencies = Array();
+try {
+ $rows = $db->get_view("app", "byCanonicalName", null, true)->rows;
+//print_r($rows);
+ foreach ($rows as $row) {
+ $employees = 0;
+ $portfolioid = 0;
+ if (isset($row->value->statistics->budget)) {
+ $agencyEmployeesArray = object_to_array($row->value->statistics->budget);
+ //print_r($agencyEmployeesArray);
+ if (isset($agencyEmployeesArray["2011-2012"]["value"])) {
+ $employees = $agencyEmployeesArray["2011-2012"]["value"];
+ } else {
+ // bailout for agencies that are closed for business
+ continue;
+ }
+ }
+ if (!($employees > 0)) {
+ $employees = 0;
+ }
+ if (isset($row->value->parentOrg)) {
+ $portfolioid = $row->value->parentOrg;
+ }
+ if (isset($row->value->orgType) && $row->value->orgType == "FMA-DepartmentOfState") {
+ $portfolioid = $row->id;
+ }
+ $agencies[$portfolioid][$row->value->name] = $employees;
+ }
+} catch (SetteeRestClientException $e) {
+ setteErrorHandler($e);
+}
+//print_r($portfolios);
+//print_r($agencies);
+
+// http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
+$golden_ratio_conjugate = 0.618033988749895;
+$h = 0.00+rand(0,10)/10; # use random start value
+foreach ($portfolios as $portfolioName => $portfolioID) {
+ $h += $golden_ratio_conjugate;
+
+ $h = fmod($h,1);
+ $portfolioColor = $color->hsv2hex(Array($h, .3, .99));
+ $subnodes = Array();
+ $portfolioEmployees = 0;
+ foreach ($agencies[$portfolioID] as $agencyName => $agencyEmployees) {
+ $agencyColor = $color->hsv2hex(Array($h / 10, rand(1, 10) / 10, abs(($h * (1 / 10)) - .5) + .5));
+ $subnodes[] = Array(
+ "label" => str_replace(Array("'", "`"), "", $agencyName),
+ "amount" => $agencyEmployees,
+ //"color" => "#" . $agencyColor
+ );
+ $portfolioEmployees += $agencyEmployees;
+ }
+ $nodes[] = Array(
+ "label" => $portfolioName,
+ "amount" => $portfolioEmployees,
+ //"color" => "#" . $portfolioColor,
+ "children" => $subnodes
+ );
+ $total += $portfolioEmployees;
+}
+$data = Array(
+ "label" => "Australian Federal Government",
+ "amount" => $total,
+ //"color" => "#000000",
+ "children" => $nodes
+);
+echo "var data =eval('('+'" . json_encode($data) . "'+')');";
+?>
+
+ new BubbleTree({
+ data: data,
+ container: '.bubbletree'
+ });
+
+
+ });
+
+ </script>
+ </head>
+ <body>
+ <div class="bubbletree-wrapper">
+ <div class="bubbletree"></div>
+ </div>
+ </body>
+</html>
+
--- /dev/null
+++ b/disclosr.iml
@@ -1,1 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="Python" name="Python">
+ <configuration sdkName="" />
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
+
--- /dev/null
+++ b/documents/datagov-export-groups.py
@@ -1,1 +1,81 @@
+import ckanclient
+import couchdb
+from ckanclient import CkanApiError
+import re
+
+class LoaderError(Exception):
+ pass
+
+# Instantiate the CKAN client.
+#ckan = ckanclient.CkanClient(base_location='http://localhost:5000/api', api_key='b47b24cd-591d-40c1-8677-d73101d56d1b')
+api_key = 'ff34526e-f794-4068-8235-fcbba38cd8bc'
+ckan = ckanclient.CkanClient(base_location='http://data.disclosurelo.gs/api',
+ api_key=api_key)
+couch = couchdb.Server('http://127.0.0.1:5984/')
+#couch = couchdb.Server('http://192.168.1.113:5984/')
+
+# https://github.com/okfn/ckanext-importlib
+def munge(name):
+ # convert spaces to underscores
+ name = re.sub(' ', '_', name).lower()
+ # convert symbols to dashes
+ name = re.sub('[:]', '_-', name).lower()
+ name = re.sub('[/]', '-', name).lower()
+ # take out not-allowed characters
+ name = re.sub('[^a-zA-Z0-9-_]', '', name).lower()
+ # remove double underscores
+ name = re.sub('__', '_', name).lower()
+ return name
+
+
+def name_munge(input_name):
+ return munge(input_name.replace(' ', '').replace('.', '_').replace('&', 'and'))
+
+
+docsdb = couch['disclosr-documents']
+
+if __name__ == "__main__":
+ groups = {}
+ for doc in docsdb.view('app/datasetGroups'):
+ group_name = doc.key
+ if group_name != "Not specified":
+ pkg_name = filter(lambda x: x in '0123456789abcdefghijklmnopqrstuvwxyz-_',
+ doc.value.replace("http://data.gov.au/dataset/", '').replace('/', '')[:100]);
+ if group_name in groups.keys():
+ groups[group_name] = list(set(groups[group_name] + [pkg_name]))
+ else:
+ groups[group_name] = [pkg_name]
+
+ # add dataset to group(s)
+ for group_name in groups.keys():
+ if group_name != "Not specified":
+ group_url = name_munge(group_name[:100])
+ print group_name
+ print groups[group_name]
+ try:
+ # Update the group details
+ group_entity = ckan.group_entity_get(group_url)
+ print "group "+group_name+" exists"
+ if 'packages' in group_entity.keys():
+ group_entity['packages'] = list(set(group_entity['packages'] + groups[group_name]))
+ else:
+ group_entity['packages'] = groups[group_name]
+ ckan.group_entity_put(group_entity)
+ except CkanApiError, e:
+ if ckan.last_status == 404:
+ print "group "+group_name+" does not exist, creating"
+ group_entity = {
+ 'name': group_url,
+ 'title': group_name,
+ 'description': group_name,
+ 'packages': groups[group_name]
+ }
+ #print group_entity
+ ckan.group_register_post(group_entity)
+ elif ckan.last_status == 409:
+ print "group already exists"
+ else:
+ raise LoaderError('Unexpected status %s adding to group under \'%s\': %r' % (
+ ckan.last_status, pkg_name, e.args))
+
--- /dev/null
+++ b/documents/datagov-export.py
@@ -1,1 +1,276 @@
-
+import ckanclient
+import couchdb
+from ckanclient import CkanApiError
+import re
+import html2text # aaronsw :(
+import ckanapi # https://github.com/open-data/ckanapi
+
+
+class LoaderError(Exception):
+ pass
+
+# Instantiate the CKAN client.
+api_key = 'ff34526e-f794-4068-8235-fcbba38cd8bc'
+server = 'data.disclosurelo.gs'
+
+ckan = ckanclient.CkanClient(base_location='http://'+server+'api',
+ api_key=api_key)
+ckandirect = ckanapi.RemoteCKAN('http://'+server, api_key=api_key)
+couch = couchdb.Server('http://127.0.0.1:5984/')
+#couch = couchdb.Server('http://192.168.1.113:5984/')
+
+import urllib
+import urlparse
+
+def url_fix(s, charset='utf-8'):
+ """Sometimes you get an URL by a user that just isn't a real
+ URL because it contains unsafe characters like ' ' and so on. This
+ function can fix some of the problems in a similar way browsers
+ handle data entered by the user:
+
+ >>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
+ 'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
+
+ :param charset: The target charset for the URL if the url was
+ given as unicode string.
+ """
+ if isinstance(s, unicode):
+ s = s.encode(charset, 'ignore')
+ if not urlparse.urlparse(s).scheme:
+ s = "http://"+s
+ scheme, netloc, path, qs, anchor = urlparse.urlsplit(s)
+ path = urllib.quote(path, '/%')
+ qs = urllib.quote_plus(qs, ':&=')
+ return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))
+
+# http://code.activestate.com/recipes/578019-bytes-to-human-human-to-bytes-converter/
+SYMBOLS = {
+ 'customary': ('B', 'KB', 'MB', 'GB', 'T', 'P', 'E', 'Z', 'Y'),
+ 'customary_ext': ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa',
+ 'zetta', 'iotta'),
+ 'iec': ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'),
+ 'iec_ext': ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi',
+ 'zebi', 'yobi'),
+}
+
+
+def human2bytes(s):
+ """
+ Attempts to guess the string format based on default symbols
+ set and return the corresponding bytes as an integer.
+ When unable to recognize the format ValueError is raised.
+
+ >>> human2bytes('0 B')
+ 0
+ >>> human2bytes('1 K')
+ 1024
+ >>> human2bytes('1 M')
+ 1048576
+ >>> human2bytes('1 Gi')
+ 1073741824
+ >>> human2bytes('1 tera')
+ 1099511627776
+
+ >>> human2bytes('0.5kilo')
+ 512
+ >>> human2bytes('0.1 byte')
+ 0
+ >>> human2bytes('1 k') # k is an alias for K
+ 1024
+ >>> human2bytes('12 foo')
+ Traceback (most recent call last):
+ ...
+ ValueError: can't interpret '12 foo'
+ """
+ if s == None:
+ return 0
+ s = s.replace(',', '')
+ init = s
+ num = ""
+ while s and s[0:1].isdigit() or s[0:1] == '.':
+ num += s[0]
+ s = s[1:]
+ num = float(num)
+ letter = s.strip()
+ for name, sset in SYMBOLS.items():
+ if letter in sset:
+ break
+ else:
+ if letter == 'k':
+ # treat 'k' as an alias for 'K' as per: http://goo.gl/kTQMs
+ sset = SYMBOLS['customary']
+ letter = letter.upper()
+ else:
+ raise ValueError("can't interpret %r" % init)
+ prefix = {sset[0]: 1}
+ for i, s in enumerate(sset[1:]):
+ prefix[s] = 1 << (i + 1) * 10
+ return int(num * prefix[letter])
+
+# https://github.com/okfn/ckanext-importlib
+def munge(name):
+ # convert spaces to underscores
+ name = re.sub(' ', '_', name).lower()
+ # convert symbols to dashes
+ name = re.sub('[:]', '_-', name).lower()
+ name = re.sub('[/]', '-', name).lower()
+ # take out not-allowed characters
+ name = re.sub('[^a-zA-Z0-9-_]', '', name).lower()
+ # remove double underscores
+ name = re.sub('__', '_', name).lower()
+ return name
+
+
+def name_munge(input_name):
+ return munge(input_name.replace(' ', '').replace('.', '_').replace('&', 'and'))
+
+
+def get_licence_id(licencename):
+ map = {
+ "Creative Commons - Attribution-Share Alike 2.0 Australia (CC-SA)\nThe downloadable version of the database is licensed under CC-BY-SA Creative Commons Attribution Share Alike and contains only the database fields that are released under that license. These fields are object title, object number, object description as well as temporal, spatial and dimension details. It also contains a persistent URL for each record.": 'cc-by-sa',
+ "CreativeCommonsAttributionNonCommercial30AustraliaCCBYNC30": 'cc-nc',
+ 'Otherpleasespecify': 'notspecified',
+ '': 'notspecified',
+ "Publicly available data": 'notspecified',
+ "CreativeCommonsAttributionNoDerivativeWorks30AustraliaCCBYND30": "other-closed",
+ "CreativeCommonsAttributionNonCommercialNoDerivs30AustraliaCCBYNCND30": "other-closed",
+ 'CreativeCommonsAttribution30AustraliaCCBY30': 'cc-by',
+ "Creative Commons - Attribution 2.5 Australia (CC-BY)": 'cc-by',
+ 'CreativeCommonsAttributionCCBY25': 'cc-by',
+ "PublicDomain": 'other-pd',
+ }
+ if licencename not in map.keys():
+ raise Exception(licencename + " not found");
+ return map[licencename];
+
+
+docsdb = couch['disclosr-documents']
+
+if __name__ == "__main__":
+ orgs_list = []
+ orgs_ids = {}
+ for doc in docsdb.view('app/datasets'):
+ print " --- "
+ print doc.id
+
+ if doc.value['url'] != "http://data.gov.au/data/" and doc.value['agencyID'] != "qld":
+
+
+ # Collect the package metadata.
+ pkg_name = filter(lambda x: x in '0123456789abcdefghijklmnopqrstuvwxyz-_',
+ doc.value['url'].replace("http://data.gov.au/dataset/", '').replace('/', '')[:100]);
+ print pkg_name
+ #add to or create organization using direct API
+ agency = doc.value['metadata']["Agency"]
+ if agency == "APS":
+ agency = "Australian Public Service Commission"
+ if agency == "Shared Services, Treasury Directorate":
+ agency = "Shared Services Procurement, Treasury Directorate"
+ if agency == "Treasury - Shared Services":
+ agency = "Shared Services Procurement, Treasury Directorate"
+ if agency == "Territory and Municipal Services (TAMS)":
+ agency = "Territory and Municipal Services Directorate"
+ if agency == "State Library of NSW":
+ agency = "State Library of New South Wales"
+ org_name = name_munge(agency[:100])
+ if org_name not in orgs_list:
+ orgs_list = ckandirect.action.organization_list()['result']
+ #print orgs_list
+ if org_name not in orgs_list:
+ try:
+ print "org not found, creating " + org_name
+ ckandirect.action.organization_create(name=org_name, title=agency,
+ description=agency)
+ orgs_list.append(org_name)
+ except ckanapi.ValidationError, e:
+ print e
+ raise LoaderError('Unexpected status')
+ else:
+ print "org found, adding dataset to " + org_name
+
+ # cache org names -> id mapping
+ if org_name not in orgs_ids:
+ org = ckandirect.action.organization_show(id=org_name)
+ orgs_ids[org_name] = org["result"]["id"]
+ org_id = orgs_ids[org_name]
+ print "org id is "+org_id
+ tags = []
+ creator = doc.value['metadata']["DCTERMS.Creator"]
+ if doc.value['agencyID'] == "AGIMO":
+ if len(doc.value['metadata']["Keywords / Tags"]) > 0:
+ if hasattr(doc.value['metadata']["Keywords / Tags"], '__iter__'):
+ tags = tags + doc.value['metadata']["Keywords / Tags"]
+ else:
+ tags = tags + [doc.value['metadata']["Keywords / Tags"]]
+
+ tags = [re.sub('[^a-zA-Z0-9-_.]', '', tag.replace('&', 'and')).lower() for tag in tags if tag]
+ #print tags
+ extras = []
+
+ for extra_key in doc.value['metadata'].keys():
+ if extra_key not in ["Description","Content-Language","DCTERMS.Description", "Keywords / Tags" ,"data.gov.au Category", "Download", "Permalink","DCTERMS.Identifier"]:
+ if doc.value['metadata'][extra_key] != None and doc.value['metadata'][extra_key] != "":
+ extras.append([extra_key, doc.value['metadata'][extra_key]])
+
+ package_entity = {
+ 'name': pkg_name,
+ 'title': doc.value['metadata']['DCTERMS.Title'],
+ 'url': doc.value['metadata']['DCTERMS.Source.URI'],
+ 'tags': tags, #tags are mandatory?
+ 'author': creator,
+ 'maintainer': creator,
+ 'licence_id': get_licence_id(doc.value['metadata']['DCTERMS.License']),
+ 'notes': html2text.html2text(doc.value['metadata']['Description']),
+ 'owner_org': org_id,
+ 'extras': extras
+ }
+
+
+ try:
+ #print package_entity
+ ckan.package_register_post(package_entity)
+ except CkanApiError, e:
+ if ckan.last_message == "{\"name\": [\"That URL is already in use.\"]}":
+ print "package already exists"
+ else:
+ print ckan.last_message
+ raise LoaderError('Unexpected status %s checking for package under \'%s\': %r' % (
+ ckan.last_status, pkg_name, e.args))
+ pkg = ckan.package_entity_get(pkg_name)
+
+
+ # add resources (downloadable data files)
+ if 'Download' in doc.value['metadata'].keys():
+ try:
+
+ resources = pkg.get('resources', [])
+ if len(resources) < len(doc.value['metadata']['Download']):
+ for resource in doc.value['metadata']['Download']:
+
+ # http://docs.ckan.org/en/ckan-1.7/domain-model-resource.html
+ # (KML/KMZ) / (Shapefile) /(Other)
+ format = "plain"
+ if resource['format'] == '(XML)':
+ format = 'xml'
+ if resource['format'] == '(CSV/XLS)':
+ format = 'csv'
+ if resource['format'] == '(Shapefile)':
+ format = 'shp'
+ if resource['format'] == '(KML/KMZ)':
+ format = 'kml'
+