예제 #1
0
    def type_redirect(self, resource_name):
        orgs = h.organizations_available('read')

        if not orgs:
            abort(404, _('No organizations found'))
        try:
            chromo = get_chromo(resource_name)
        except RecombinantException:
            abort(404, _('Recombinant resource_name not found'))

        # custom business logic
        if is_sysadmin(c.user):
            return redirect(h.url_for('recombinant_resource',
                                      resource_name=resource_name, owner_org='tbs-sct'))
        return redirect(h.url_for('recombinant_resource',
                                  resource_name=resource_name, owner_org=orgs[0]['name']))
예제 #2
0
    def datatable(self, resource_name, resource_id):
        draw = int(request.params['draw'])
        search_text = unicode(request.params['search[value]'])
        offset = int(request.params['start'])
        limit = int(request.params['length'])
        sort_by_num = int(request.params['order[0][column]'])
        sort_order = ('desc' if request.params['order[0][dir]'] == 'desc'
                      else 'asc'
                      )

        chromo = h.recombinant_get_chromo(resource_name)
        lc = LocalCKAN(username=c.user)
        unfiltered_response = lc.action.datastore_search(
            resource_id=resource_id,
            limit=1,
        )

        cols = [f['datastore_id'] for f in chromo['fields']]
        sort_str = cols[sort_by_num] + ' ' + sort_order
        sort_str += ' NULLS LAST'

        response = lc.action.datastore_search(
            q=search_text,
            resource_id=resource_id,
            offset=offset,
            limit=limit,
            sort=sort_str
        )

        aadata = [
            [datatablify(row.get(colname, u''), colname) for colname in cols]
            for row in response['records']]

        if chromo.get('edit_form', False):
            res = lc.action.resource_show(id=resource_id)
            pkg = lc.action.package_show(id=res['package_id'])
            fids = [f['datastore_id'] for f in chromo['fields']]
            pkids = [fids.index(k) for k in aslist(chromo['datastore_primary_key'])]
            for row in aadata:
                row.insert(0, (
                        u'<a href="{0}" aria-label"' + _("Edit") + '">'
                        u'<i class="fa fa-lg fa-edit" aria-hidden="true"></i></a>').format(
                        h.url_for(
                            controller='ckanext.canada.controller:PDUpdateController',
                            action='update_pd_record',
                            owner_org=pkg['organization']['name'],
                            resource_name=resource_name,
                            pk=','.join(url_part_escape(row[i]) for i in pkids)
                        )
                    )
                )

        return json.dumps({
            'draw': draw,
            'iTotalRecords': unfiltered_response.get('total', 0),
            'iTotalDisplayRecords': response.get('total', 0),
            'aaData': aadata,
        })
예제 #3
0
    def datatable(self, resource_name, resource_id):
        draw = int(request.params['draw'])
        search_text = unicode(request.params['search[value]'])
        offset = int(request.params['start'])
        limit = int(request.params['length'])
        sort_by_num = int(request.params['order[0][column]'])
        sort_order = ('desc' if request.params['order[0][dir]'] == 'desc'
                      else 'asc'
                      )

        chromo = h.recombinant_get_chromo(resource_name)
        lc = LocalCKAN(username=c.user)
        unfiltered_response = lc.action.datastore_search(
            resource_id=resource_id,
            limit=1,
        )

        cols = [f['datastore_id'] for f in chromo['fields']]
        sort_str = cols[sort_by_num] + ' ' + sort_order
        sort_str += ' NULLS LAST'

        response = lc.action.datastore_search(
            q=search_text,
            resource_id=resource_id,
            offset=offset,
            limit=limit,
            sort=sort_str
        )

        aadata = [
            [datatablify(row.get(colname, u''), colname) for colname in cols]
            for row in response['records']]

        # XXX custom business logic hack
        if resource_name == 'consultations':
            res = lc.action.resource_show(id=resource_id)
            pkg = lc.action.package_show(id=res['package_id'])
            for row in aadata:
                row[0] = u'<a href="{0}">{1}</a>'.format(
                    h.url_for(
                        controller='ckanext.canada.controller:PDUpdateController',
                        action='update_pd_record',
                        owner_org=pkg['organization']['name'],
                        resource_name=resource_name,
                        pk=url_part_escape(row[0])),
                    row[0])

        return json.dumps({
            'draw': draw,
            'iTotalRecords': unfiltered_response.get('total', 0),
            'iTotalDisplayRecords': response.get('total', 0),
            'aaData': aadata,
        })
예제 #4
0
    def datatable(self, resource_name, resource_id):
        draw = int(request.params['draw'])
        search_text = unicode(request.params['search[value]'])
        offset = int(request.params['start'])
        limit = int(request.params['length'])
        sort_by_num = int(request.params['order[0][column]'])
        sort_order = ('desc'
                      if request.params['order[0][dir]'] == 'desc' else 'asc')

        chromo = h.recombinant_get_chromo(resource_name)
        lc = LocalCKAN(username=c.user)
        unfiltered_response = lc.action.datastore_search(
            resource_id=resource_id,
            limit=1,
        )

        cols = [f['datastore_id'] for f in chromo['fields']]
        sort_str = cols[sort_by_num] + ' ' + sort_order
        sort_str += ' NULLS LAST'

        response = lc.action.datastore_search(q=search_text,
                                              resource_id=resource_id,
                                              offset=offset,
                                              limit=limit,
                                              sort=sort_str)

        aadata = [[
            datatablify(row.get(colname, u''), colname) for colname in cols
        ] for row in response['records']]

        # XXX custom business logic hack
        if resource_name == 'consultations':
            res = lc.action.resource_show(id=resource_id)
            pkg = lc.action.package_show(id=res['package_id'])
            for row in aadata:
                row[0] = u'<a href="{0}">{1}</a>'.format(
                    h.url_for(controller=
                              'ckanext.canada.controller:PDUpdateController',
                              action='update_pd_record',
                              owner_org=pkg['organization']['name'],
                              resource_name=resource_name,
                              pk=url_part_escape(row[0])), row[0])

        return json.dumps({
            'draw': draw,
            'iTotalRecords': unfiltered_response.get('total', 0),
            'iTotalDisplayRecords': response.get('total', 0),
            'aaData': aadata,
        })
예제 #5
0
    def publish(self):
        lc = LocalCKAN(username=c.user)

        publish_date = date_str_to_datetime(
            request.str_POST['publish_date']).strftime("%Y-%m-%d %H:%M:%S")

        # get a list of package id's from the for POST data
        for key, package_id in request.str_POST.iteritems():
            if key == 'publish':
                lc.action.package_patch(
                    id=package_id,
                    portal_release_date=publish_date,
                )

        # return us to the publishing interface
        redirect(h.url_for('ckanadmin_publish'))
예제 #6
0
    def publish(self):
        lc = LocalCKAN(username=c.user)

        publish_date = date_str_to_datetime(
            request.str_POST['publish_date']
        ).strftime("%Y-%m-%d %H:%M:%S")

        # get a list of package id's from the for POST data
        for key, package_id in request.str_POST.iteritems():
            if key == 'publish':
                lc.action.package_patch(
                    id=package_id,
                    portal_release_date=publish_date,
                )

        # return us to the publishing interface
        redirect(h.url_for('ckanadmin_publish'))
예제 #7
0
def linked_user(user, maxlength=0, avatar=20):
    '''Brute force disable gravatar, mostly copied from ckan/lib/helpers'''
    from ckan import model
    if not isinstance(user, model.User):
        user_name = unicode(user)
        user = model.User.get(user_name)
        if not user:
            return user_name
    if user:
        name = user.name if model.User.VALID_NAME.match(user.name) else user.id
        displayname = user.display_name

        if maxlength and len(user.display_name) > maxlength:
            displayname = displayname[:maxlength] + '...'

        return h.literal(
            h.link_to(displayname,
                      h.url_for(controller='user', action='read', id=name)))
예제 #8
0
    def output_feed(self, results, feed_title, feed_description,
                    feed_link, feed_url, navigation_urls, feed_guid):

        author_name = config.get('ckan.feeds.author_name', '').strip() or \
            config.get('ckan.site_id', '').strip()
        author_link = config.get('ckan.feeds.author_link', '').strip() or \
            config.get('ckan.site_url', '').strip()

        feed = _FixedAtom1Feed(
            title=feed_title,
            link=feed_link,
            description=feed_description,
            language=u'en',
            author_name=author_name,
            author_link=author_link,
            feed_guid=feed_guid,
            feed_url=feed_url,
            previous_page=navigation_urls['previous'],
            next_page=navigation_urls['next'],
            first_page=navigation_urls['first'],
            last_page=navigation_urls['last'],
        )

        for pkg in results:
            feed.add_item(
                title= h.get_translated(pkg, 'title'),
                link=h.url_for(controller='package', action='read', id=pkg['id']),
                description= h.get_translated(pkg, 'notes'),
                updated=date_str_to_datetime(pkg.get('metadata_modified')),
                published=date_str_to_datetime(pkg.get('metadata_created')),
                unique_id=_create_atom_id(u'/dataset/%s' % pkg['id']),
                author_name=pkg.get('author', ''),
                author_email=pkg.get('author_email', ''),
                categories=''.join(e['value']
                                   for e in pkg.get('extras', [])
                                   if e['key'] == lx('keywords')).split(','),
                enclosure=webhelpers.feedgenerator.Enclosure(
                    self.base_url + url(str(
                        '/api/action/package_show?id=%s' % pkg['name'])),
                    unicode(len(json.dumps(pkg))),   # TODO fix this
                    u'application/json')
            )
        response.content_type = feed.mime_type
        return feed.writeString('utf-8')
예제 #9
0
    def output_feed(self, results, feed_title, feed_description, feed_link,
                    feed_url, navigation_urls, feed_guid):

        author_name = config.get('ckan.feeds.author_name', '').strip() or \
            config.get('ckan.site_id', '').strip()
        author_link = config.get('ckan.feeds.author_link', '').strip() or \
            config.get('ckan.site_url', '').strip()

        feed = _FixedAtom1Feed(
            title=feed_title,
            link=feed_link,
            description=feed_description,
            language=u'en',
            author_name=author_name,
            author_link=author_link,
            feed_guid=feed_guid,
            feed_url=feed_url,
            previous_page=navigation_urls['previous'],
            next_page=navigation_urls['next'],
            first_page=navigation_urls['first'],
            last_page=navigation_urls['last'],
        )

        for pkg in results:
            feed.add_item(
                title=h.get_translated(pkg, 'title'),
                link=h.url_for(controller='package',
                               action='read',
                               id=pkg['id']),
                description=h.get_translated(pkg, 'notes'),
                updated=date_str_to_datetime(pkg.get('metadata_modified')),
                published=date_str_to_datetime(pkg.get('metadata_created')),
                unique_id=_create_atom_id(u'/dataset/%s' % pkg['id']),
                author_name=pkg.get('author', ''),
                author_email=pkg.get('author_email', ''),
                categories=''.join(e['value'] for e in pkg.get('extras', [])
                                   if e['key'] == lx('keywords')).split(','),
                enclosure=webhelpers.feedgenerator.Enclosure(
                    self.base_url +
                    url(str('/api/action/package_show?id=%s' % pkg['name'])),
                    unicode(len(json.dumps(pkg))),  # TODO fix this
                    u'application/json'))
        response.content_type = feed.mime_type
        return feed.writeString('utf-8')
예제 #10
0
def link_to_user(user, maxlength=0):
    """ Return the HTML snippet that returns a link to a user.  """

    # Do not link to pseudo accounts
    if user in [model.PSEUDO_USER__LOGGED_IN, model.PSEUDO_USER__VISITOR]:
        return user
    if not isinstance(user, model.User):
        user_name = unicode(user)
        user = model.User.get(user_name)
        if not user:
            return user_name

    if user:
        _name = user.name if model.User.VALID_NAME.match(user.name) else user.id
        displayname = user.display_name
        if maxlength and len(user.display_name) > maxlength:
            displayname = displayname[:maxlength] + '...'
        return html.tags.link_to(displayname,
                       h.url_for(controller='user', action='read', id=_name))
예제 #11
0
    def publish(self):
        lc = LocalCKAN(username=c.user)

        publish_date = date_str_to_datetime(
            request.str_POST['publish_date']).strftime("%Y-%m-%d %H:%M:%S")

        # get a list of package id's from the for POST data
        count = 0
        for key, package_id in request.str_POST.iteritems():
            if key == 'publish':
                lc.action.package_patch(
                    id=package_id,
                    portal_release_date=publish_date,
                )
                count += 1

        # flash notice that records are published
        h.flash_notice(str(count) + _(u' record(s) published.'))

        # return us to the publishing interface
        redirect(h.url_for('ckanadmin_publish'))
예제 #12
0
def send_email_dataset_notification(datasets_by_contacts, action_type):
    for contact in datasets_by_contacts:
        try:
            log.info("Preparing email data for {0} notification to {1}".format(
                action_type, contact.get('email')))
            datasets = []
            for contact_dataset in contact.get('datasets', {}):
                date = datetime.strptime(
                    contact_dataset.get('next_update_due'), '%Y-%m-%d')

                datasets.append({
                    'url':
                    h.url_for('dataset_read',
                              id=contact_dataset.get('name'),
                              _external=True),
                    'next_due_date':
                    date.strftime('%d/%m/%Y')
                })

            extra_vars = {'datasets': datasets}
            subject = render_jinja2(
                'emails/subjects/{0}.txt'.format(action_type), extra_vars)
            body = render_jinja2('emails/bodies/{0}.txt'.format(action_type),
                                 extra_vars)

            site_title = 'Data | Queensland Government'
            site_url = config.get('ckan.site_url')
            enqueue_job(mailer._mail_recipient, [
                contact.get('email'),
                contact.get('email'), site_title, site_url, subject, body
            ],
                        title=action_type)
            log.info(
                "Added email to job worker default queue for {0} notification to {1}"
                .format(action_type, contact.get('email')))
        except Exception as e:
            log.error("Error sending {0} notification to {1}".format(
                action_type, contact.get('email')))
            log.error(str(e))
예제 #13
0
def linked_user(user, maxlength=0, avatar=20):
    '''Brute force disable gravatar, mostly copied from ckan/lib/helpers'''
    from ckan import model
    if not isinstance(user, model.User):
        user_name = unicode(user)
        user = model.User.get(user_name)
        if not user:
            return user_name
    if user:
        name = user.name if model.User.VALID_NAME.match(user.name) else user.id
        displayname = user.display_name
        if displayname==config.get('ckan.site_id', '').strip():
            displayname = _('A system administrator')

        if maxlength and len(user.display_name) > maxlength:
            displayname = displayname[:maxlength] + '...'

        return h.literal(h.link_to(
                displayname,
                h.url_for(controller='user', action='read', id=name)
            )
        )
예제 #14
0
    def update_pd_record(self, owner_org, resource_name, pk):
        pk = [url_part_unescape(p) for p in pk.split(',')]

        lc = LocalCKAN(username=c.user)

        try:
            chromo = h.recombinant_get_chromo(resource_name)
            rcomb = lc.action.recombinant_show(
                owner_org=owner_org, dataset_type=chromo['dataset_type'])
            [res
             ] = [r for r in rcomb['resources'] if r['name'] == resource_name]

            check_access('datastore_upsert', {
                'user': c.user,
                'auth_user_obj': c.userobj
            }, {'resource_id': res['id']})
        except NotAuthorized:
            abort(403, _('Unauthorized'))

        choice_fields = {
            f['datastore_id']: [{
                'value': k,
                'label': v
            } for (k, v) in f['choices']]
            for f in h.recombinant_choice_fields(resource_name)
        }
        pk_fields = aslist(chromo['datastore_primary_key'])
        pk_filter = dict(zip(pk_fields, pk))

        records = lc.action.datastore_search(resource_id=res['id'],
                                             filters=pk_filter)['records']
        if len(records) == 0:
            abort(404, _('Not found'))
        if len(records) > 1:
            abort(400, _('Multiple records found'))
        record = records[0]

        if request.method == 'POST':
            post_data = parse_params(request.POST,
                                     ignore_keys=['save'] + pk_fields)

            if 'cancel' in post_data:
                return redirect(
                    h.url_for(
                        controller=
                        'ckanext.recombinant.controller:UploadController',
                        action='preview_table',
                        resource_name=resource_name,
                        owner_org=rcomb['owner_org'],
                    ))

            data, err = clean_check_type_errors(post_data, chromo['fields'],
                                                pk_fields, choice_fields)
            # can't change pk fields
            for f_id in data:
                if f_id in pk_fields:
                    data[f_id] = record[f_id]
            try:
                lc.action.datastore_upsert(
                    resource_id=res['id'],
                    #method='update',    FIXME not raising ValidationErrors
                    records=[{
                        k: None if k in err else v
                        for (k, v) in data.items()
                    }],
                    dry_run=bool(err))
            except ValidationError as ve:
                err = dict(
                    {
                        k: [_(e) for e in v]
                        for (k, v) in ve.error_dict['records'][0].items()
                    }, **err)

            if err:
                return render('recombinant/update_pd_record.html',
                              extra_vars={
                                  'data': data,
                                  'resource_name': resource_name,
                                  'chromo_title': chromo['title'],
                                  'choice_fields': choice_fields,
                                  'pk_fields': pk_fields,
                                  'owner_org': rcomb['owner_org'],
                                  'errors': err,
                              })

            h.flash_notice(_(u'Record %s Updated') % u','.join(pk))

            return redirect(
                h.url_for(
                    controller=
                    'ckanext.recombinant.controller:UploadController',
                    action='preview_table',
                    resource_name=resource_name,
                    owner_org=rcomb['owner_org'],
                ))

        data = {}
        for f in chromo['fields']:
            if not f.get('import_template_include', True):
                continue
            val = record[f['datastore_id']]
            data[f['datastore_id']] = val

        return render('recombinant/update_pd_record.html',
                      extra_vars={
                          'data': data,
                          'resource_name': resource_name,
                          'chromo_title': chromo['title'],
                          'choice_fields': choice_fields,
                          'pk_fields': pk_fields,
                          'owner_org': rcomb['owner_org'],
                          'errors': {},
                      })
예제 #15
0
    def create_pd_record(self, owner_org, resource_name):
        lc = LocalCKAN(username=c.user)

        try:
            chromo = h.recombinant_get_chromo(resource_name)
            rcomb = lc.action.recombinant_show(
                owner_org=owner_org, dataset_type=chromo['dataset_type'])
            [res
             ] = [r for r in rcomb['resources'] if r['name'] == resource_name]

            check_access('datastore_upsert', {
                'user': c.user,
                'auth_user_obj': c.userobj
            }, {'resource_id': res['id']})
        except NotAuthorized:
            return abort(403, _('Unauthorized'))

        choice_fields = {
            f['datastore_id']: [{
                'value': k,
                'label': v
            } for (k, v) in f['choices']]
            for f in h.recombinant_choice_fields(resource_name)
        }
        pk_fields = aslist(chromo['datastore_primary_key'])

        if request.method == 'POST':
            post_data = parse_params(request.POST, ignore_keys=['save'])

            if 'cancel' in post_data:
                return redirect(
                    h.url_for(
                        controller=
                        'ckanext.recombinant.controller:UploadController',
                        action='preview_table',
                        resource_name=resource_name,
                        owner_org=rcomb['owner_org'],
                    ))

            data, err = clean_check_type_errors(post_data, chromo['fields'],
                                                pk_fields, choice_fields)
            try:
                lc.action.datastore_upsert(resource_id=res['id'],
                                           method='insert',
                                           records=[{
                                               k: None if k in err else v
                                               for (k, v) in data.items()
                                           }],
                                           dry_run=bool(err))
            except ValidationError as ve:
                if 'records' in ve.error_dict:
                    err = dict(
                        {
                            k: [_(e) for e in v]
                            for (k, v) in ve.error_dict['records'][0].items()
                        }, **err)
                elif ve.error_dict.get('info', {}).get('pgcode',
                                                       '') == '23505':
                    err = dict(
                        {
                            k: [_("This record already exists")]
                            for k in pk_fields
                        }, **err)

            if err:
                return render('recombinant/create_pd_record.html',
                              extra_vars={
                                  'data': data,
                                  'resource_name': resource_name,
                                  'chromo_title': chromo['title'],
                                  'choice_fields': choice_fields,
                                  'owner_org': rcomb['owner_org'],
                                  'errors': err,
                              })

            h.flash_notice(_(u'Record Created'))

            return redirect(
                h.url_for(
                    controller=
                    'ckanext.recombinant.controller:UploadController',
                    action='preview_table',
                    resource_name=resource_name,
                    owner_org=rcomb['owner_org'],
                ))

        return render('recombinant/create_pd_record.html',
                      extra_vars={
                          'data': {},
                          'resource_name': resource_name,
                          'chromo_title': chromo['title'],
                          'choice_fields': choice_fields,
                          'owner_org': rcomb['owner_org'],
                          'errors': {},
                      })
예제 #16
0
    def datatable(self, resource_name, resource_id):
        draw = int(request.params['draw'])
        search_text = unicode(request.params['search[value]'])
        offset = int(request.params['start'])
        limit = int(request.params['length'])

        chromo = h.recombinant_get_chromo(resource_name)
        lc = LocalCKAN(username=c.user)
        try:
            unfiltered_response = lc.action.datastore_search(
                resource_id=resource_id,
                limit=1,
            )
        except NotAuthorized:
            # datatables js can't handle any sort of error response
            # return no records instead
            return json.dumps({
                'draw': draw,
                'iTotalRecords': -1,  # with a hint that something is wrong
                'iTotalDisplayRecords': -1,
                'aaData': [],
            })

        cols = [f['datastore_id'] for f in chromo['fields']]
        prefix_cols = 1 if chromo.get('edit_form', False) else 0

        sort_list = []
        i = 0
        while True:
            if u'order[%d][column]' % i not in request.params:
                break
            sort_by_num = int(request.params[u'order[%d][column]' % i])
            sort_order = (u'desc NULLS LAST' if
                          request.params[u'order[%d][dir]' %
                                         i] == u'desc' else u'asc NULLS LAST')
            sort_list.append(cols[sort_by_num - prefix_cols] + u' ' +
                             sort_order)
            i += 1

        response = lc.action.datastore_search(
            q=search_text,
            resource_id=resource_id,
            offset=offset,
            limit=limit,
            sort=u', '.join(sort_list),
        )

        aadata = [[
            datatablify(row.get(colname, u''), colname) for colname in cols
        ] for row in response['records']]

        if chromo.get('edit_form', False):
            res = lc.action.resource_show(id=resource_id)
            pkg = lc.action.package_show(id=res['package_id'])
            fids = [f['datastore_id'] for f in chromo['fields']]
            pkids = [
                fids.index(k) for k in aslist(chromo['datastore_primary_key'])
            ]
            for row in aadata:
                row.insert(
                    0,
                    (u'<a href="{0}" aria-label"' + _("Edit") + '">'
                     u'<i class="fa fa-lg fa-edit" aria-hidden="true"></i></a>'
                     ).format(
                         h.url_for(
                             controller=
                             'ckanext.canada.controller:PDUpdateController',
                             action='update_pd_record',
                             owner_org=pkg['organization']['name'],
                             resource_name=resource_name,
                             pk=','.join(
                                 url_part_escape(row[i]) for i in pkids))))

        return json.dumps({
            'draw': draw,
            'iTotalRecords': unfiltered_response.get('total', 0),
            'iTotalDisplayRecords': response.get('total', 0),
            'aaData': aadata,
        })
예제 #17
0
    def update_pd_record(self, owner_org, resource_name, pk):
        pk = [url_part_unescape(p) for p in pk.split(',')]

        lc = LocalCKAN(username=c.user)

        try:
            chromo = h.recombinant_get_chromo(resource_name)
            rcomb = lc.action.recombinant_show(
                owner_org=owner_org,
                dataset_type=chromo['dataset_type'])
            [res] = [r for r in rcomb['resources'] if r['name'] == resource_name]

            check_access(
                'datastore_upsert',
                {'user': c.user, 'auth_user_obj': c.userobj},
                {'resource_id': res['id']})
        except NotAuthorized:
            abort(403, _('Unauthorized'))

        choice_fields = {
            f['datastore_id']: [
                {'value': k, 'label': v} for (k, v) in f['choices']]
            for f in h.recombinant_choice_fields(resource_name)}
        pk_fields = aslist(chromo['datastore_primary_key'])
        pk_filter = dict(zip(pk_fields, pk))

        records = lc.action.datastore_search(
            resource_id=res['id'],
            filters=pk_filter)['records']
        if len(records) == 0:
            abort(404, _('Not found'))
        if len(records) > 1:
            abort(400, _('Multiple records found'))
        record = records[0]

        if request.method == 'POST':
            post_data = parse_params(request.POST, ignore_keys=['save'] + pk_fields)

            if 'cancel' in post_data:
                return redirect(h.url_for(
                    controller='ckanext.recombinant.controller:UploadController',
                    action='preview_table',
                    resource_name=resource_name,
                    owner_org=rcomb['owner_org'],
                    ))

            data = {}
            for f in chromo['fields']:
                f_id = f['datastore_id']
                if not f.get('import_template_include', True):
                    continue
                if f_id in pk_fields:
                    data[f_id] = record[f_id]
                else:
                    val = post_data.get(f['datastore_id'], '')
                    if isinstance(val, list):
                        val = u','.join(val)
                    val = canonicalize(
                        val,
                        f['datastore_type'],
                        primary_key=False,
                        choice_field=f_id in choice_fields)
                    data[f['datastore_id']] = val
            try:
                lc.action.datastore_upsert(
                    resource_id=res['id'],
                    #method='update',    FIXME not raising ValidationErrors
                    records=[data])
            except ValidationError as ve:
                err = {
                    k: [_(e) for e in v]
                    for (k, v) in ve.error_dict['records'][0].items()}
                return render('recombinant/update_pd_record.html',
                    extra_vars={
                        'data': data,
                        'resource_name': resource_name,
                        'chromo_title': chromo['title'],
                        'choice_fields': choice_fields,
                        'pk_fields': pk_fields,
                        'owner_org': rcomb['owner_org'],
                        'errors': err,
                        })

            h.flash_notice(_(u'Record %s Updated') % u','.join(pk) )

            return redirect(h.url_for(
                controller='ckanext.recombinant.controller:UploadController',
                action='preview_table',
                resource_name=resource_name,
                owner_org=rcomb['owner_org'],
                ))

        data = {}
        for f in chromo['fields']:
            if not f.get('import_template_include', True):
                continue
            val = record[f['datastore_id']]
            data[f['datastore_id']] = val

        return render('recombinant/update_pd_record.html',
            extra_vars={
                'data': data,
                'resource_name': resource_name,
                'chromo_title': chromo['title'],
                'choice_fields': choice_fields,
                'pk_fields': pk_fields,
                'owner_org': rcomb['owner_org'],
                'errors': {},
                })
예제 #18
0
    def create_travela(self, id, resource_id):
        lc = LocalCKAN(username=c.user)
        pkg = lc.action.package_show(id=id)
        res = lc.action.resource_show(id=resource_id)
        org = lc.action.organization_show(id=pkg['owner_org'])
        dataset = lc.action.recombinant_show(dataset_type='travela',
                                             owner_org=org['name'])

        chromo = h.recombinant_get_chromo('travela')
        data = {}
        data_prev = {}
        form_data = {}
        for f in chromo['fields']:
            dirty = request.params.getone(f['datastore_id'])
            data[f['datastore_id']] = canonicalize(dirty, f['datastore_type'],
                                                   False)
            if f['datastore_id'] + '_prev' in request.params:
                data_prev[f['datastore_id']] = request.params.getone(
                    f['datastore_id'] + '_prev')
                form_data[f['datastore_id'] +
                          '_prev'] = data_prev[f['datastore_id']]

        form_data.update(data)

        def error(errors):
            return render('recombinant/resource_edit.html',
                          extra_vars={
                              'create_errors': errors,
                              'create_data': form_data,
                              'delete_errors': [],
                              'dataset': dataset,
                              'resource': res,
                              'organization': org,
                              'filters': {},
                              'action': 'edit'
                          })

        try:
            year = int_validator(data['year'], None)
        except Invalid:
            year = None

        if not year:
            return error({'year': [_(u'Invalid year')]})

        response = lc.action.datastore_search(resource_id=resource_id,
                                              filters={'year': data['year']})
        if response['records']:
            return error(
                {'year': [_(u'Data for this year has already been entered')]})

        response = lc.action.datastore_search(resource_id=resource_id,
                                              filters={'year': year - 1})
        if response['records']:
            prev = response['records'][0]
            errors = {}
            for p in data_prev:
                if prev[p] != data_prev[p]:
                    errors[p + '_prev'] = [
                        _(u'Does not match previous data "%s"') % prev[p]
                    ]
            if errors:
                return error(errors)
        else:
            lc.action.datastore_upsert(
                resource_id=resource_id,
                method='insert',
                records=[dict(data_prev, year=year - 1)])
            h.flash_success(_("Record for %d added.") % (year - 1))

        lc.action.datastore_upsert(resource_id=resource_id,
                                   method='insert',
                                   records=[data])

        h.flash_success(_("Record for %d added.") % year)

        redirect(
            h.url_for(
                controller='ckanext.recombinant.controller:UploadController',
                action='preview_table',
                resource_name=res['name'],
                owner_org=org['name'],
            ))
예제 #19
0
    def create_travela(self, id, resource_id):
        lc = LocalCKAN(username=c.user)
        pkg = lc.action.package_show(id=id)
        res = lc.action.resource_show(id=resource_id)
        org = lc.action.organization_show(id=pkg['owner_org'])
        dataset = lc.action.recombinant_show(
            dataset_type='travela', owner_org=org['name'])

        chromo = h.recombinant_get_chromo('travela')
        data = {}
        data_prev = {}
        form_data = {}
        for f in chromo['fields']:
            dirty = request.params.getone(f['datastore_id'])
            data[f['datastore_id']] = canonicalize(dirty, f['datastore_type'], False)
            if f['datastore_id'] + '_prev' in request.params:
                 data_prev[f['datastore_id']] = request.params.getone(f['datastore_id'] + '_prev')
                 form_data[f['datastore_id'] + '_prev'] = data_prev[f['datastore_id']]

        form_data.update(data)

        def error(errors):
            return render('recombinant/resource_edit.html',
                extra_vars={
                    'create_errors': errors,
                    'create_data': form_data,
                    'delete_errors': [],
                    'dataset': dataset,
                    'resource': res,
                    'organization': org,
                    'filters': {},
                    'action': 'edit'})

        try:
            year = int_validator(data['year'], None)
        except Invalid:
            year = None

        if not year:
            return error({'year': [_(u'Invalid year')]})

        response = lc.action.datastore_search(resource_id=resource_id,
            filters={'year': data['year']})
        if response['records']:
            return error({'year': [_(u'Data for this year has already been entered')]})

        response = lc.action.datastore_search(resource_id=resource_id,
            filters={'year': year - 1})
        if response['records']:
            prev = response['records'][0]
            errors = {}
            for p in data_prev:
                if prev[p] != data_prev[p] and prev[p]:
                    errors[p + '_prev'] = [_(u'Does not match previous data "%s"') % prev[p]]
            if errors:
                return error(errors)
        else:
            lc.action.datastore_upsert(resource_id=resource_id,
                method='insert',
                records=[dict(data_prev, year=year - 1)])
            h.flash_success(_("Record for %d added.") % (year - 1))

        lc.action.datastore_upsert(resource_id=resource_id,
            method='insert',
            records=[data])

        h.flash_success(_("Record for %d added.") % year)

        redirect(h.url_for(
            controller='ckanext.recombinant.controller:UploadController',
            action='preview_table',
            resource_name=res['name'],
            owner_org=org['name'],
            ))