[ckan-changes] commit/ckanextiati: 6 new changesets

Bitbucket commits-noreply at bitbucket.org
Thu Oct 20 16:49:48 UTC 2011


6 new changesets in ckanextiati:

http://bitbucket.org/okfn/ckanextiati/changeset/0a3ef324b882/
changeset:   0a3ef324b882
user:        amercader
date:        2011-10-19 17:44:43
summary:     Remove unneeded plugin iati_theme (use iati_forms to load the custom theme)
affected #:  3 files (-1 bytes)

--- a/README.txt	Wed Oct 19 15:44:39 2011 +0100
+++ b/README.txt	Wed Oct 19 16:44:43 2011 +0100
@@ -52,7 +52,7 @@
 ckan.site_url = http://iati.test.ckan.net
 
 # Add any other plugins you want to use:
-ckan.plugins = iati_theme iati_forms iati_approval iati_group_authz iati_package_authz wordpresser synchronous_search
+ckan.plugins = iati_forms iati_approval iati_group_authz iati_package_authz wordpresser synchronous_search
 
 # Use a proxy wordpress to provide help & about pages (etc)
 wordpresser.proxy_host = http://iatiregistry.wordpress.org/


--- a/ckanext/iati/plugin.py	Wed Oct 19 15:44:39 2011 +0100
+++ b/ckanext/iati/plugin.py	Wed Oct 19 16:44:43 2011 +0100
@@ -52,6 +52,7 @@
 
     def update_config(self, config):
         configure_template_directory(config, 'templates')
+        configure_public_directory(config, 'public')
 
 class IatiActions(SingletonPlugin):
 


--- a/setup.py	Wed Oct 19 15:44:39 2011 +0100
+++ b/setup.py	Wed Oct 19 16:44:43 2011 +0100
@@ -26,7 +26,6 @@
       # -*- Entry points: -*-
       
       [ckan.plugins]
-      iati_theme = ckanext.iati.theme:IatiThemeExtension
       iati_preview = ckanext.iati.preview:IatiPackagePreviewExtension
       iati_approval = ckanext.iati.approval:IatiGroupApprovalExtension
       iati_group_authz = ckanext.iati.authz:IatiGroupAuthzExtension


http://bitbucket.org/okfn/ckanextiati/changeset/ceb801b77c54/
changeset:   ceb801b77c54
user:        amercader
date:        2011-10-19 19:55:20
summary:     Add missing file to latest commit
affected #:  1 file (-1 bytes)

--- a/ckanext/iati/theme.py	Wed Oct 19 16:44:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-import os
-
-from ckan.plugins import implements, SingletonPlugin
-from ckan.plugins import IConfigurer,IRoutes
-
-class IatiThemeExtension(SingletonPlugin):
-    implements(IConfigurer, inherit=True)
-    implements(IRoutes, inherit=True)
-    def before_map(self, map):
-        map.connect('/package/new', controller='package_formalchemy', action='new')
-        map.connect('/package/edit/{id}', controller='package_formalchemy', action='edit')
-        map.connect('/group/new', controller='group_formalchemy', action='new')
-        map.connect('/group/edit/{id}', controller='group_formalchemy', action='edit')
-
-        return map
-
-    def update_config(self, config):
-        here = os.path.dirname(__file__)
-        rootdir = os.path.dirname(os.path.dirname(here))
-        our_public_dir = os.path.join(rootdir, 'ckanext', 'iati', '', 'public')
-        template_dir = os.path.join(rootdir, 'ckanext', 'iati', 'templates')
-        config['extra_public_paths'] = ','.join([our_public_dir,
-                config.get('extra_public_paths', '')])
-        config['extra_template_paths'] = ','.join([template_dir,
-                config.get('extra_template_paths', '')])
-
-


http://bitbucket.org/okfn/ckanextiati/changeset/94913a8c1181/
changeset:   94913a8c1181
branch:      spreadsheet-support
user:        amercader
date:        2011-10-19 19:58:37
summary:     Links and controller for the csv export and import and first version of the export function
affected #:  4 files (-1 bytes)

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ckanext/iati/controllers/spreadsheet.py	Wed Oct 19 18:58:37 2011 +0100
@@ -0,0 +1,114 @@
+import csv
+import StringIO
+
+from ckan import model
+from ckan.lib.base import c, request, response, config, h, redirect, render, abort,  BaseController
+from ckan.lib.helpers import json
+from ckan.authz import Authorizer
+from ckan.logic import get_action, NotFound
+from ckanext.iati.patch import my_group
+
+class CSVController(BaseController):
+
+    csv_fieldnames = (
+            'registry-publisher-id',
+            'registry-file-id',
+            'title',
+            'contact-email',
+            'source-url',
+            'format',
+            'file-type',
+            'recipient-country',
+            'activity-period-start',
+            'activity-period-end',
+            'last-updated-datetime',
+            'generated-datetime',
+            'activity-count',
+            'verification-status',
+            'default-language')
+
+    def download(self,publisher=None):
+        context = {'model':model,'user': c.user or c.author}
+        is_sysadmin = Authorizer().is_sysadmin(c.user)
+        user_group = my_group()
+
+        if publisher:
+            try:
+                group = get_action('group_show')(context, {'id':publisher})
+            except NotFound:
+                abort(404, 'Group not found')
+       
+        if not user_group and not is_sysadmin:
+            abort(403,'User does not belong to a publisher group')
+
+        if is_sysadmin:
+            if publisher:
+                output = self.write_csv_file(publisher)
+            else:
+                c.groups = get_action('group_list')(context, {'all_fields':True})
+                return render('csv/index.html')
+        else:
+            if publisher:
+                if publisher == user_group.name:
+                    output = self.write_csv_file(publisher)
+                    return "COOL LETS DO IT with the provided publisher: %s" % publisher
+                else:
+                    abort(403,'Permission denied for this group')
+            else:
+                output = self.write_csv_file(user_group.name)                
+        
+
+        file_name = publisher if publisher else user_group.name
+        response.headers['Content-type'] = 'text/csv'
+        response.headers['Content-disposition'] = 'attachment;filename=%s.csv' % file_name
+        return output
+
+    def upload(self):
+        return "UPLOAD CSV"
+
+    def write_csv_file(self,publisher):
+        context = {'model':model,'user': c.user or c.author}
+        try:
+            group = get_action('group_show')(context, {'id':publisher})
+        except NotFound:
+            abort(404, 'Group not found')
+
+        f = StringIO.StringIO()
+        
+        output = ''
+        try:
+            writer = csv.DictWriter(f, fieldnames=self.csv_fieldnames, quoting=csv.QUOTE_ALL)
+            headers = dict( (n,n) for n in self.csv_fieldnames )
+            writer.writerow(headers)
+            for pkg in group['packages']:
+                
+                package = get_action('package_show_rest')(context,{'id':pkg['id']})
+                
+                extras = package['extras']
+                writer.writerow({ 
+                    'registry-publisher-id': group['name'],
+                    'registry-file-id': package['name'],
+                    'title': package['title'],
+                    'contact-email': package['author_email'],
+                    'source-url': package['resources'][0]['url'] if len(package['resources']) else None,
+                    'format': package['resources'][0]['format'] if len(package['resources']) else None,
+                    'file-type': extras['filetype'],
+                    'recipient-country': extras['country'],
+                    'activity-period-start': extras['activity_period-from'],
+                    'activity-period-end': extras['activity_period-to'],
+                    'last-updated-datetime': extras['data_updated'],
+                    'generated-datetime': extras['record_updated'],
+                    'activity-count': extras['activity_count'] if 'activity_count' in extras else None,
+                    'verification-status': extras['verified'],
+                    'default-language': extras['language']
+                    })
+            output = f.getvalue()
+        finally:
+            f.close()
+
+        return output
+
+
+
+
+


--- a/ckanext/iati/plugin.py	Wed Oct 19 18:55:20 2011 +0100
+++ b/ckanext/iati/plugin.py	Wed Oct 19 18:58:37 2011 +0100
@@ -45,6 +45,11 @@
         map.connect('/group/new', controller=group_controller, action='new')
         map.connect('/group/edit/{id}', controller=group_controller, action='edit')
 
+        csv_controller = 'ckanext.iati.controllers.spreadsheet:CSVController'
+        map.connect('/csv/download', controller=csv_controller, action='download')
+        map.connect('/csv/download/{publisher}', controller=csv_controller, action='download')
+        map.connect('/csv/upload', controller=csv_controller, action='upload')
+
         return map
 
     def after_map(self, map):


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ckanext/iati/templates/csv/index.html	Wed Oct 19 18:58:37 2011 +0100
@@ -0,0 +1,22 @@
+<html xmlns:py="http://genshi.edgewall.org/"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  xmlns:xi="http://www.w3.org/2001/XInclude"
+  py:strip="">
+
+  <py:def function="page_title">CSV Export</py:def>
+  <div py:match="content">
+
+    <h2 class="head">CSV Export</h2>
+
+    <div>Select a Publisher to download all its records in CSV format.</div>
+    <hr class="cleared" />
+    <ul>
+    <py:for each="group in c.groups">
+        <li><a href="/csv/download/${group['name']}" >${group['title']}</a></li>
+    </py:for>
+    </ul>
+  </div>
+
+
+  <xi:include href="../layout.html" />
+</html>


--- a/ckanext/iati/templates/layout_base.html	Wed Oct 19 18:55:20 2011 +0100
+++ b/ckanext/iati/templates/layout_base.html	Wed Oct 19 18:58:37 2011 +0100
@@ -116,7 +116,14 @@
             <li class="page_item" py:if="h.am_authorized_with_publisher(c, actions.PACKAGE_CREATE)">
               ${h.subnav_link(c, _('Register'), controller='package', action='new', id=None)}
             </li>
-          </ul>
+            <li class="page_item" py:if="h.am_authorized_with_publisher(c, actions.PACKAGE_CREATE)">
+              ${h.subnav_link(c, _('Download current records'), controller='ckanext.iati.controllers.spreadsheet:CSVController', action='download', id=None)}
+            </li>
+            <li class="page_item" py:if="h.am_authorized_with_publisher(c, actions.PACKAGE_CREATE)">
+              ${h.subnav_link(c, _('Upload CSV file'), controller='ckanext.iati.controllers.spreadsheet:CSVController', action='upload', id=None)}
+            </li>
+
+            </ul></li><li>${h.nav_link(c, _('Groups'), controller='group', action='index', id=None)}
           <ul class="children">


http://bitbucket.org/okfn/ckanextiati/changeset/3848bf04afab/
changeset:   3848bf04afab
branch:      spreadsheet-support
user:        amercader
date:        2011-10-20 13:44:00
summary:     More robust export function and user authorization management
affected #:  2 files (-1 bytes)

--- a/ckanext/iati/authz.py	Wed Oct 19 18:58:37 2011 +0100
+++ b/ckanext/iati/authz.py	Thu Oct 20 12:44:00 2011 +0100
@@ -7,6 +7,20 @@
 log = logging.getLogger(__name__)
 
 
+def get_user_administered_groups(user_name):
+    user = model.User.get(user_name)
+    if not user:
+        raise ValueError(user)
+
+    q = model.Session.query(model.GroupRole).filter_by(user=user,role=model.Role.ADMIN)
+
+    groups = []
+    for group_role in q.all():
+        if group_role.group.state == 'active':
+            groups.append(group_role.group.id)
+
+    return groups
+
 def _get_group_authz_group(group):
     """ For each group, we're adding an authorization group with the same settings 
         that can then be set as the owner for new packages. """


--- a/ckanext/iati/controllers/spreadsheet.py	Wed Oct 19 18:58:37 2011 +0100
+++ b/ckanext/iati/controllers/spreadsheet.py	Thu Oct 20 12:44:00 2011 +0100
@@ -6,59 +6,78 @@
 from ckan.lib.helpers import json
 from ckan.authz import Authorizer
 from ckan.logic import get_action, NotFound
-from ckanext.iati.patch import my_group
+from ckanext.iati.authz import get_user_administered_groups
 
 class CSVController(BaseController):
 
-    csv_fieldnames = (
-            'registry-publisher-id',
-            'registry-file-id',
-            'title',
-            'contact-email',
-            'source-url',
-            'format',
-            'file-type',
-            'recipient-country',
-            'activity-period-start',
-            'activity-period-end',
-            'last-updated-datetime',
-            'generated-datetime',
-            'activity-count',
-            'verification-status',
-            'default-language')
+    csv_mapping = [
+            ('registry-publisher-id', 'groups', 'name'),
+            ('registry-file-id', 'package', 'name'),
+            ('title', 'package', 'title'),
+            ('contact-email', 'package', 'author_email'),
+            ('source-url', 'resources', 'url'),
+            ('format', 'resources', 'format'),
+            ('file-type','extras', 'filetype'),
+            ('recipient-country','extras', 'country'),
+            ('activity-period-start','extras', 'activity_period-from'),
+            ('activity-period-end','extras', 'activity_period-to'),
+            ('last-updated-datetime','extras', 'data_updated'),
+            ('generated-datetime','extras', 'record_updated'),
+            ('activity-count','extras', 'activity_count'),
+            ('verification-status','extras', 'verified'),
+            ('default-language','extras', 'language')
+            ]
 
     def download(self,publisher=None):
+        if not c.user:
+            abort(403,'Permission denied')
+
         context = {'model':model,'user': c.user or c.author}
+
         is_sysadmin = Authorizer().is_sysadmin(c.user)
-        user_group = my_group()
 
-        if publisher:
+        # Groups of which the logged user is admin
+        authz_groups = get_user_administered_groups(c.user)
+
+        if publisher and publisher != 'all':
             try:
                 group = get_action('group_show')(context, {'id':publisher})
             except NotFound:
-                abort(404, 'Group not found')
-       
-        if not user_group and not is_sysadmin:
-            abort(403,'User does not belong to a publisher group')
+                abort(404, 'Publisher not found')
+
+            if not group['id'] in authz_groups and not is_sysadmin:
+                abort(403,'Permission denied for this publisher group')
 
         if is_sysadmin:
             if publisher:
+                # Return CSV for provided publisher
                 output = self.write_csv_file(publisher)
             else:
+                # Show list of all available publishers
                 c.groups = get_action('group_list')(context, {'all_fields':True})
                 return render('csv/index.html')
         else:
-            if publisher:
-                if publisher == user_group.name:
-                    output = self.write_csv_file(publisher)
-                    return "COOL LETS DO IT with the provided publisher: %s" % publisher
-                else:
-                    abort(403,'Permission denied for this group')
+            if publisher and publisher != 'all':
+                # Return CSV for provided publisher (we already checked the permissions)
+                output = self.write_csv_file(publisher)
+            elif len(authz_groups) == 1:
+                # Return directly CSV for publisher
+                output = self.write_csv_file(authz_groups[0])
+            elif len(authz_groups) > 1:
+                # Show list of available publishers for this user
+                groups = get_action('group_list')(context, {'all_fields':True})
+                c.groups = []
+                for group in groups:
+                    if group['id'] in authz_groups:
+                        c.groups.append(group)
+
+                return render('csv/index.html')
             else:
-                output = self.write_csv_file(user_group.name)                
-        
+                # User does not have permissions on any publisher
+                abort(403,'Permission denied')
 
-        file_name = publisher if publisher else user_group.name
+
+        file_name = publisher if publisher else authz_groups[0]
         response.headers['Content-type'] = 'text/csv'
         response.headers['Content-disposition'] = 'attachment;filename=%s.csv' % file_name
         return output
@@ -69,39 +88,45 @@
     def write_csv_file(self,publisher):
         context = {'model':model,'user': c.user or c.author}
         try:
-            group = get_action('group_show')(context, {'id':publisher})
+            if publisher == 'all':
+                packages = get_action('package_list')(context, {})
+            else:
+                group = get_action('group_show')(context, {'id':publisher})
+                packages = [pkg['id'] for pkg in group['packages']]
         except NotFound:
             abort(404, 'Group not found')
 
         f = StringIO.StringIO()
-        
+
         output = ''
         try:
-            writer = csv.DictWriter(f, fieldnames=self.csv_fieldnames, quoting=csv.QUOTE_ALL)
-            headers = dict( (n,n) for n in self.csv_fieldnames )
+            fieldnames = [n[0] for n in self.csv_mapping]
+            writer = csv.DictWriter(f, fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
+            headers = dict( (n[0],n[0]) for n in self.csv_mapping )
             writer.writerow(headers)
-            for pkg in group['packages']:
-                
-                package = get_action('package_show_rest')(context,{'id':pkg['id']})
-                
-                extras = package['extras']
-                writer.writerow({ 
-                    'registry-publisher-id': group['name'],
-                    'registry-file-id': package['name'],
-                    'title': package['title'],
-                    'contact-email': package['author_email'],
-                    'source-url': package['resources'][0]['url'] if len(package['resources']) else None,
-                    'format': package['resources'][0]['format'] if len(package['resources']) else None,
-                    'file-type': extras['filetype'],
-                    'recipient-country': extras['country'],
-                    'activity-period-start': extras['activity_period-from'],
-                    'activity-period-end': extras['activity_period-to'],
-                    'last-updated-datetime': extras['data_updated'],
-                    'generated-datetime': extras['record_updated'],
-                    'activity-count': extras['activity_count'] if 'activity_count' in extras else None,
-                    'verification-status': extras['verified'],
-                    'default-language': extras['language']
-                    })
+
+            packages.sort()
+            for pkg in packages:
+
+                package = get_action('package_show_rest')(context,{'id':pkg})
+                if package:
+                    row = {}
+                    for fieldname, entity, key in self.csv_mapping:
+                        value = None
+                        if entity == 'groups':
+                            if len(package['groups']):
+                                value = package['groups'][0]
+                        elif entity == 'resources':
+                            if len(package['resources']) and key in package['resources'][0]:
+                                value = package['resources'][0][key]
+                        elif entity == 'extras':
+                            if key in package['extras']:
+                                value = package['extras'][key]
+                        else:
+                            if key in package:
+                                value = package[key]
+                        row[fieldname] = value
+                    writer.writerow(row)
             output = f.getvalue()
         finally:
             f.close()


http://bitbucket.org/okfn/ckanextiati/changeset/eb45fb69da61/
changeset:   eb45fb69da61
branch:      spreadsheet-support
user:        amercader
date:        2011-10-20 13:58:33
summary:     Nicer download page
affected #:  1 file (-1 bytes)

--- a/ckanext/iati/templates/csv/index.html	Thu Oct 20 12:44:00 2011 +0100
+++ b/ckanext/iati/templates/csv/index.html	Thu Oct 20 12:58:33 2011 +0100
@@ -9,12 +9,18 @@
     <h2 class="head">CSV Export</h2><div>Select a Publisher to download all its records in CSV format.</div>
+    <div><strong>Warning:</strong>For publishers with a large number of datasets it may take a while to generate the CSV file. Please be patient.</div><hr class="cleared" />
-    <ul>
-    <py:for each="group in c.groups">
-        <li><a href="/csv/download/${group['name']}" >${group['title']}</a></li>
-    </py:for>
-    </ul>
+    <table class="groups">
+        <tr><th>Title</th><th>Number of datasets</th><th></th></tr>
+        <py:for each="group in c.groups">
+            <tr>
+                <td>${group['display_name']}</td>
+                <td>${group['packages']}</td>
+                <td><a href="${h.url_for(controller='ckanext.iati.controllers.spreadsheet:CSVController', action='download', publisher=group['name'])}">Download</a></td>
+            </tr>
+        </py:for>
+    </table></div>
 
 


http://bitbucket.org/okfn/ckanextiati/changeset/a6a2bf03cf40/
changeset:   a6a2bf03cf40
branch:      spreadsheet-support
user:        amercader
date:        2011-10-20 18:49:02
summary:     First draft of the import CSV functionality. Not functional.
affected #:  2 files (-1 bytes)

--- a/ckanext/iati/controllers/spreadsheet.py	Thu Oct 20 12:58:33 2011 +0100
+++ b/ckanext/iati/controllers/spreadsheet.py	Thu Oct 20 17:49:02 2011 +0100
@@ -1,3 +1,4 @@
+import logging
 import csv
 import StringIO
 
@@ -5,9 +6,12 @@
 from ckan.lib.base import c, request, response, config, h, redirect, render, abort,  BaseController
 from ckan.lib.helpers import json
 from ckan.authz import Authorizer
-from ckan.logic import get_action, NotFound
+from ckan.logic import get_action, NotFound, ValidationError, NotAuthorized
 from ckanext.iati.authz import get_user_administered_groups
 
+log = logging.getLogger(__name__)
+
+
 class CSVController(BaseController):
 
     csv_mapping = [
@@ -27,28 +31,32 @@
             ('verification-status','extras', 'verified'),
             ('default-language','extras', 'language')
             ]
+    
+    def __before__(self, action, **params):
+        super(CSVController,self).__before__(action, **params)
 
-    def download(self,publisher=None):
         if not c.user:
             abort(403,'Permission denied')
 
-        context = {'model':model,'user': c.user or c.author}
-
-        is_sysadmin = Authorizer().is_sysadmin(c.user)
+        self.is_sysadmin = Authorizer().is_sysadmin(c.user)
 
         # Groups of which the logged user is admin
-        authz_groups = get_user_administered_groups(c.user)
+        self.authz_groups = get_user_administered_groups(c.user)
 
+    def download(self,publisher=None):
+
+        context = {'model':model,'user': c.user or c.author}
+        
         if publisher and publisher != 'all':
             try:
                 group = get_action('group_show')(context, {'id':publisher})
             except NotFound:
                 abort(404, 'Publisher not found')
 
-            if not group['id'] in authz_groups and not is_sysadmin:
+            if not group['id'] in self.authz_groups and not self.is_sysadmin:
                 abort(403,'Permission denied for this publisher group')
 
-        if is_sysadmin:
+        if self.is_sysadmin:
             if publisher:
                 # Return CSV for provided publisher
                 output = self.write_csv_file(publisher)
@@ -60,15 +68,15 @@
             if publisher and publisher != 'all':
                 # Return CSV for provided publisher (we already checked the permissions)
                 output = self.write_csv_file(publisher)
-            elif len(authz_groups) == 1:
+            elif len(self.authz_groups) == 1:
                 # Return directly CSV for publisher
-                output = self.write_csv_file(authz_groups[0])
-            elif len(authz_groups) > 1:
+                output = self.write_csv_file(self.authz_groups[0])
+            elif len(self.authz_groups) > 1:
                 # Show list of available publishers for this user
                 groups = get_action('group_list')(context, {'all_fields':True})
                 c.groups = []
                 for group in groups:
-                    if group['id'] in authz_groups:
+                    if group['id'] in self.authz_groups:
                         c.groups.append(group)
 
                 return render('csv/index.html')
@@ -77,13 +85,23 @@
                 abort(403,'Permission denied')
 
 
-        file_name = publisher if publisher else authz_groups[0]
+        file_name = publisher if publisher else self.authz_groups[0]
         response.headers['Content-type'] = 'text/csv'
         response.headers['Content-disposition'] = 'attachment;filename=%s.csv' % file_name
         return output
 
     def upload(self):
-        return "UPLOAD CSV"
+        if request.method == 'GET':
+            return render('csv/upload.html')
+        elif request.method == 'POST':
+            csv_file = request.POST['file']
+            
+            added, updated, errors = self.read_csv_file(csv_file)
+            c.added = added
+            c.updated = updated
+            c.errors = errors
+            return 'Packages added: %i, Packages updated: %i, Errors: %s'  % \
+                (added,updated,', '.join(errors))
 
     def write_csv_file(self,publisher):
         context = {'model':model,'user': c.user or c.author}
@@ -133,7 +151,87 @@
 
         return output
 
+    def read_csv_file(self,csv_file):
+        fieldnames = [n[0] for n in self.csv_mapping]
+        #reader = csv.DictReader(csv_file.file,fieldnames=fieldnames)
+        #TODO: separator
+        reader = csv.DictReader(csv_file.file)
 
+        counts = {'added': 0, 'updated': 0}
+        errors = []
+        for i,row in enumerate(reader):
+            try:
+                # Check mandatory fields
+                if not row['registry-publisher-id']:
+                     raise ValueError('Publisher not defined')
+                
+                # TODO: Check permissions on group
+                     
+                if not row['registry-file-id']:
+                    raise ValueError('File id not defined')
+                # TODO: Check name convention
 
+                package_dict = self.get_package_dict_from_row(row)
+                self.create_or_update_package(package_dict,counts)
+            except ValueError,e:
+                errors.append('Error in row %i: %s' % (i+1,str(e)))
+            except NotAuthorized,e:
+                errors.append('Error in row %i: Not authorized to publish to this group (%s)' % (i+1,row['registry-publisher-id']))
 
+        return counts['added'], counts['updated'], errors
 
+    def get_package_dict_from_row(self,row):
+        package = {}
+        for fieldname, entity, key in self.csv_mapping:
+            value = row[fieldname]
+            if value:
+                if entity == 'groups':
+                    package['groups'] = [value]
+                elif entity == 'resources':
+                    if not 'resources' in package:
+                       package['resources'] = [{}]
+                    package['resources'][0][key] = value
+                elif entity == 'extras':
+                    if not 'extras' in package:
+                       package['extras'] = {}
+                    package['extras'][key] = value
+                else:
+                    package[key] = value
+        return package
+
+    def create_or_update_package(self, package_dict, counts = None):
+        try:
+
+            context = {
+                'model': model,
+                'session': model.Session,
+                'user': c.user,
+                'api_version':'1'
+            }
+
+            # Check if package exists
+            data_dict = {}
+            data_dict['id'] = package_dict['name']
+            try:
+                existing_package_dict = get_action('package_show')(context, data_dict)
+                # Update package
+
+                log.info('Package with name "%s" exists and will be updated' % package_dict['name'])
+                context.update({'id':existing_package_dict['id']})
+                package_dict.update({'id':existing_package_dict['id']})
+                updated_package = get_action('package_update_rest')(context, package_dict)
+                if counts:
+                    counts['updated'] += 1
+            except NotFound:
+                # Package needs to be created
+                log.info('Package with name "%s" does not exist and will be created' % package_dict['name'])
+                new_package = get_action('package_create_rest')(context, package_dict)
+                if counts:
+                    counts['added'] += 1
+
+        except ValidationError,e:
+            raise ValueError(str(e))
+
+
+
+


--- a/ckanext/iati/plugin.py	Thu Oct 20 12:58:33 2011 +0100
+++ b/ckanext/iati/plugin.py	Thu Oct 20 17:49:02 2011 +0100
@@ -48,7 +48,10 @@
         csv_controller = 'ckanext.iati.controllers.spreadsheet:CSVController'
         map.connect('/csv/download', controller=csv_controller, action='download')
         map.connect('/csv/download/{publisher}', controller=csv_controller, action='download')
-        map.connect('/csv/upload', controller=csv_controller, action='upload')
+        map.connect('/csv/upload', controller=csv_controller, action='upload',
+                    conditions=dict(method=['GET']))
+        map.connect('/csv/upload', controller=csv_controller, action='upload',
+                    conditions=dict(method=['POST']))
 
         return map

Repository URL: https://bitbucket.org/okfn/ckanextiati/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list