예제 #1
0
    def openspending_report(self):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        self._set_openspending_reports_dir()
        c.content = open(c.openspending_report_dir + "/index.html").read()
        return render('data/openspending_report.html')
예제 #2
0
    def linked_data_admin(self):
        """

        """
        import git

        if not dgu_helpers.is_sysadmin() and not c.user in [
                'user_d24373', 'user_d102361'
        ]:
            abort(403)

        prefix = 'dgu.jekyll.ukgovld.'
        c.repo_url = pylons.config.get(prefix + "repo.url", None)
        c.repo_branch = pylons.config.get(prefix + "repo.branch", None)
        source_repo_path = pylons.config.get(prefix + "local.source", None)
        build_path = pylons.config.get(prefix + "local.build", None)
        deploy_path = pylons.config.get(prefix + "local.deploy", None)

        if not all([c.repo_url, c.repo_branch, source_repo_path, build_path,
                    deploy_path]) or \
                not os.path.exists(source_repo_path):
            c.error = "System not configured, please setup ckan.ini"
            if not os.path.exists(source_repo_path):
                c.error = "Repo path %s does not exist" % source_repo_path
            return render('data/ukgovld.html')

        # Ensure repo exists locally
        try:
            repo = git.Repo(source_repo_path)
        except git.InvalidGitRepositoryError, e:
            repo = git.Repo.init(source_repo_path)
            repo.create_remote('origin', c.repo_url)
예제 #3
0
    def report_abuse(self, id):
        """
        When a user reports something as offensive, this action will mark it
        ready for moderation.  If the user reporting is a system administrator
        it will be marked, but also made invisible so that it no longer shows up
        """
        import ckan.model as model
        from ckanext.dgu.model.feedback import Feedback

        fb = Feedback.get(id)
        if fb:
            fb.moderated = False
            fb.moderation_required = True
            if is_sysadmin():
                fb.visible = False
                flash_notice(
                    "Queued. As you are an administrator, this item has been hidden"
                )
            else:
                flash_notice(
                    "Thank you for your feedback, the item has been queued for moderation"
                )
            model.Session.add(fb)
            model.Session.commit()

        h.redirect_to(request.referer or '/data')
예제 #4
0
파일: data.py 프로젝트: pjm073/ckanext-dgu
    def linked_data_admin(self):
        """

        """
        import git

        if not dgu_helpers.is_sysadmin() and not c.user in ['user_d24373', 'user_d102361']:
            abort(403)

        prefix = 'dgu.jekyll.ukgovld.'
        c.repo_url = pylons.config.get(prefix + "repo.url", None)
        c.repo_branch = pylons.config.get(prefix + "repo.branch", None)
        source_repo_path = pylons.config.get(prefix + "local.source", None)
        build_path = pylons.config.get(prefix + "local.build", None)
        deploy_path = pylons.config.get(prefix + "local.deploy", None)

        if not all([c.repo_url, c.repo_branch, source_repo_path, build_path,
                    deploy_path]) or \
                not os.path.exists(source_repo_path):
            c.error = "System not configured, please setup ckan.ini"
            if not os.path.exists(source_repo_path):
                c.error = "Repo path %s does not exist" % source_repo_path
            return render('data/ukgovld.html')

        # Ensure repo exists locally
        try:
            repo = git.Repo(source_repo_path)
        except git.InvalidGitRepositoryError, e:
            repo = git.Repo.init(source_repo_path)
            repo.create_remote('origin', c.repo_url)
예제 #5
0
    def openspending_report(self):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        self._set_openspending_reports_dir()
        c.content = open (c.openspending_report_dir + "/index.html").read()
        return render('data/openspending_report.html')
예제 #6
0
    def linked_data_admin(self):
        """
        Instructions for installing Ruby via RVM:

            \curl -sSL https://get.rvm.io | bash -s stable
            # Comment out lines in .bashrc and .bash_profile
            source "$HOME/.rvm/scripts/rvm"
            rvm autolibs distable
            rvm install 1.9.3
            rvm use 1.9.3
            rvm gemset create ukgovld
            rvm alias create ukgovldwg 1.9.3@ukgovld
            cd /vagrant/src/ckanext-dgu/
            ~/.rvm/wrappers/ukgovldwg/bundle
            rvm wrapper ukgovldwg jekyll

        """
        import git

        if not dgu_helpers.is_sysadmin() and not c.user in [
                'user_d24373', 'user_d102361'
        ]:
            abort(401)

        prefix = 'dgu.jekyll.ukgovld.'
        c.repo_url = pylons.config.get(prefix + "repo.url", None)
        c.repo_branch = pylons.config.get(prefix + "repo.branch", None)
        source_repo_path = pylons.config.get(prefix + "local.source", None)
        build_path = pylons.config.get(prefix + "local.build", None)
        deploy_path = pylons.config.get(prefix + "local.deploy", None)

        if source_repo_path and (not os.path.exists(source_repo_path)
                                 and source_repo_path.startswith('/tmp/')):
            # Directories in /tmp won't survive a reboot
            os.makedirs(source_repo_path)

        if build_path and (not os.path.exists(build_path)
                           and build_path.startswith('/tmp/')):
            # Directories in /tmp won't survive a reboot
            os.makedirs(build_path)

        if not all([c.repo_url, c.repo_branch, source_repo_path, build_path,
                    deploy_path]) or \
                not os.path.exists(source_repo_path):
            c.error = "System not configured, please setup ckan.ini"
            if source_repo_path and not os.path.exists(source_repo_path):
                c.error = "Repo path %s does not exist" % source_repo_path
            return render('data/ukgovld.html')

        # Ensure repo exists locally
        try:
            repo = git.Repo(source_repo_path)
        except git.InvalidGitRepositoryError, e:
            repo = git.Repo.init(source_repo_path)
            repo.create_remote('origin', c.repo_url)
예제 #7
0
    def linked_data_admin(self):
        """
        Instructions for installing Ruby via RVM:

            \curl -sSL https://get.rvm.io | bash -s stable
            # Comment out lines in .bashrc and .bash_profile
            source "$HOME/.rvm/scripts/rvm"
            rvm autolibs distable
            rvm install 1.9.3
            rvm use 1.9.3
            rvm gemset create ukgovld
            rvm alias create ukgovldwg 1.9.3@ukgovld
            cd /vagrant/src/ckanext-dgu/
            ~/.rvm/wrappers/ukgovldwg/bundle
            rvm wrapper ukgovldwg jekyll

        """
        import git

        if not dgu_helpers.is_sysadmin() and not c.user in ['user_d24373', 'user_d102361']:
            abort(401)

        prefix = 'dgu.jekyll.ukgovld.'
        c.repo_url = pylons.config.get(prefix + "repo.url", None)
        c.repo_branch = pylons.config.get(prefix + "repo.branch", None)
        source_repo_path = pylons.config.get(prefix + "local.source", None)
        build_path = pylons.config.get(prefix + "local.build", None)
        deploy_path = pylons.config.get(prefix + "local.deploy", None)

        if source_repo_path and (not os.path.exists(source_repo_path) and
                source_repo_path.startswith('/tmp/')):
            # Directories in /tmp won't survive a reboot
            os.makedirs(source_repo_path)

        if build_path and (not os.path.exists(build_path) and build_path.startswith('/tmp/')):
            # Directories in /tmp won't survive a reboot
            os.makedirs(build_path)

        if not all([c.repo_url, c.repo_branch, source_repo_path, build_path,
                    deploy_path]) or \
                not os.path.exists(source_repo_path):
            c.error = "System not configured, please setup ckan.ini"
            if source_repo_path and not os.path.exists(source_repo_path):
                c.error = "Repo path %s does not exist" % source_repo_path
            return render('data/ukgovld.html')

        # Ensure repo exists locally
        try:
            repo = git.Repo(source_repo_path)
        except git.InvalidGitRepositoryError, e:
            repo = git.Repo.init(source_repo_path)
            repo.create_remote('origin', c.repo_url)
예제 #8
0
    def edit(self, id):
        """
        Allows editing of commitments for a specific publisher
        """
        from ckanext.dgu.model.commitment import Commitment
        from ckanext.dgu.lib import helpers as dgu_helpers

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'extras_as_string': True,
                   'save': 'save' in request.params}

        if not dgu_helpers.is_sysadmin():
            abort(401, "You are not allowed to edit the commitments for this publisher")

        try:
            c.publisher_dict = get_action('organization_show')(context, {'id': id})
        except NotAuthorized:
            abort(401, _('Unauthorized to read commitments'))
        except ObjectNotFound:
            abort(404, _('Publisher not found'))

        c.publisher = context.get('group')
        c.publishers = model.Session.query(model.Group).filter(model.Group.state=='active')\
            .order_by(model.Group.title).all()

        c.errors = {}

        if request.method == "POST":
            # need to flatten the request into some commitments, if there is an ID then
            # we should update them, if there isn't then add them.
            # TODO: Work out how to remove them. Perhaps get the current IDs and do a diff
            # If successful redirect to read()

            h.redirect_to(h.url_for(controller='ckanext.dgu.controllers.commitment:CommitmentController',
                action='commitments', id=c.publisher.name))


        c.commitments = Commitment.get_for_publisher(c.publisher.name).order_by('commitment.commitment_text')

        return render('commitment/edit.html')
예제 #9
0
    def openspending_publisher_report(self, id):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        id = id.replace('.html', '')
        if id.startswith('publisher-'):
            publisher_name = id.replace('publisher-', '')
            # Check the publisher actually exists, for security
            publisher = model.Group.by_name(publisher_name)
            if publisher:
                c.report_name = id
            else:
                abort(404, 'Publisher not found')
            self._set_openspending_reports_dir()

            path = c.openspending_report_dir + "/" + c.report_name + ".html"
            c.content = open(path).read()
            # Jinja needs it as unicode
            c.content = c.content.decode('utf8')
            return render('data/openspending_publisher_report.html')
        else:
            abort(404)
예제 #10
0
    def report_abuse(self, id):
        """
        When a user reports something as offensive, this action will mark it
        ready for moderation.  If the user reporting is a system administrator
        it will be marked, but also made invisible so that it no longer shows up
        """
        import ckan.model as model
        from ckanext.dgu.model.feedback import Feedback

        fb = Feedback.get(id)
        if fb:
            fb.moderated = False
            fb.moderation_required = True
            if is_sysadmin():
                fb.visible = False
                flash_notice("Queued. As you are an administrator, this item has been hidden")
            else:
                flash_notice("Thank you for your feedback, the item has been queued for moderation")
            model.Session.add(fb)
            model.Session.commit()

        h.redirect_to(request.referer or '/data')
예제 #11
0
    def openspending_publisher_report(self, id):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        id = id.replace('.html', '')
        if id.startswith('publisher-'):
            publisher_name = id.replace('publisher-', '')
            # Check the publisher actually exists, for security
            publisher = model.Group.by_name(publisher_name)
            if publisher:
                c.report_name = id
            else:
                abort(404, 'Publisher not found')
            self._set_openspending_reports_dir()

            path = c.openspending_report_dir + "/" + c.report_name + ".html"
            c.content = open(path).read()
            # Jinja needs it as unicode
            c.content = c.content.decode('utf8')
            return render('data/openspending_publisher_report.html')
        else:
            abort(404)
예제 #12
0
    def get_publishers(self):
        from ckan.model.group import Group

        if dgu_helpers.is_sysadmin():
            groups = Group.all(group_type='organization')
        elif c.userobj:
            # need to get c.userobj again as it may be detached from the
            # session since the last time we called get_groups (it caches)
            c.userobj = model.User.by_name(c.user)

            # For each group where the user is an admin, we should also include
            # all of the child publishers.
            admin_groups = set()
            for g in c.userobj.get_groups('organization', 'admin'):
                for pub in publib.go_down_tree(g):
                    admin_groups.add(pub)

            editor_groups = c.userobj.get_groups('organization', 'editor')
            groups = list(admin_groups) + editor_groups
        else:  # anonymous user shouldn't have access to this page anyway.
            groups = []

        # Be explicit about which fields we make available in the template
        groups = [{
            'name': g.name,
            'id': g.id,
            'title': g.title,
            'contact-name': g.extras.get('contact-name', ''),
            'contact-email': g.extras.get('contact-email', ''),
            'contact-phone': g.extras.get('contact-phone', ''),
            'foi-name': g.extras.get('foi-name', ''),
            'foi-email': g.extras.get('foi-email', ''),
            'foi-phone': g.extras.get('foi-phone', ''),
            'foi-web': g.extras.get('foi-web', ''),
        } for g in groups]

        return dict((g['name'], g) for g in groups)
예제 #13
0
    def get_publishers(self):
        from ckan.model.group import Group

        if dgu_helpers.is_sysadmin():
            groups = Group.all(group_type='organization')
        elif c.userobj:
            # need to get c.userobj again as it may be detached from the
            # session since the last time we called get_groups (it caches)
            c.userobj = model.User.by_name(c.user)

            # For each group where the user is an admin, we should also include
            # all of the child publishers.
            admin_groups = set()
            for g in c.userobj.get_groups('organization', 'admin'):
                for pub in publib.go_down_tree(g):
                    admin_groups.add(pub)

            editor_groups = c.userobj.get_groups('organization', 'editor')
            groups = list(admin_groups) + editor_groups
        else:  # anonymous user shouldn't have access to this page anyway.
            groups = []

        # Be explicit about which fields we make available in the template
        groups = [{
            'name': g.name,
            'id': g.id,
            'title': g.title,
            'contact-name': g.extras.get('contact-name', ''),
            'contact-email': g.extras.get('contact-email', ''),
            'contact-phone': g.extras.get('contact-phone', ''),
            'foi-name': g.extras.get('foi-name', ''),
            'foi-email': g.extras.get('foi-email', ''),
            'foi-phone': g.extras.get('foi-phone', ''),
            'foi-web': g.extras.get('foi-web', ''),
        } for g in groups]

        return dict((g['name'], g) for g in groups)
예제 #14
0
    def nii(self, format=None):
        import ckan.model as model
        from ckanext.dgu.lib.reports import nii_report

        if 'regenerate' in request.GET and dguhelpers.is_sysadmin():
            from ckan.lib.helpers import flash_notice
            from ckanext.dgu.lib.reports import cached_reports
            cached_reports(['nii_report'])
            flash_notice("Report regenerated")
            h.redirect_to('/data/reports/nii')

        tmpdata = nii_report(use_cache=True)
        c.data = {}

        # Get the date time the report was generated, or now if it doesn't
        # appear in the cache
        cache_data = model.Session.query(model.DataCache.created)\
            .filter(model.DataCache.object_id=='__all__')\
            .filter(model.DataCache.key == 'nii-report').first()
        c.generated_date = cache_data[0] if cache_data else datetime.datetime.now()

        c.total_broken_packages = 0
        c.total_broken_resources = 0
        # Convert the lists of IDs into something usable in the template,
        # this could be faster if we did a bulk-fetch of groupname->obj for
        # instance.
        for k,list_of_dicts in tmpdata.iteritems():
            g = model.Group.get(k)
            c.data[g] = []
            for dct in list_of_dicts:
                for pkgname,results in dct.iteritems():
                    c.total_broken_resources += len(results)
                    if len(results):
                        c.total_broken_packages += 1
                    c.data[g].append({model.Package.get(pkgname): results})

        def _stringify(s, encoding, errors):
            if s is None:
                return ''
            if isinstance(s, unicode):
                return s.encode(encoding, errors)
            elif isinstance(s, (int , float)):
                pass #let csv.QUOTE_NONNUMERIC do its thing.
            elif not isinstance(s, str):
                s=str(s)
            return s

        if format == 'csv':
            import csv

            # Set the content-disposition so that it downloads the file
            response.headers['Content-Type'] = "text/csv; charset=utf-8"
            response.headers['Content-Disposition'] = str('attachment; filename=nii-broken-resources.csv')

            writer = csv.writer(response)
            writer.writerow(['Publisher', 'Parent publisher', 'Dataset name', 'Resource title', 'Resource link', 'Data link'])
            for publisher in c.data.keys():
                parent_groups = publisher.get_parent_groups(type='organization')
                parent_publisher = parent_groups[0].title if len(parent_groups) > 0 else ''

                for items in c.data[publisher]:
                    for dataset, resources in items.iteritems():
                        if len(resources) == 0:
                            continue
                        for resid,resdesc in resources:
                            resource = model.Resource.get(resid)
                            row = [
                                publisher.title,
                                parent_publisher,
                                _stringify(dataset.title, 'utf-8', 'ignore'),
                                _stringify(resource.description, 'utf-8', 'ignore') or 'No name',
                                'http://data.gov.uk/dataset/%s/resource/%s' % (dataset.name,resource.id,),
                                _stringify(resource.url, 'utf-8', 'ignore'),
                                'Yes' if dataset.extras.get('external_reference','') == 'ONSHUB' else 'No'
                            ]
                            writer.writerow(row)

            return ''

        return t.render('reports/nii.html')
예제 #15
0
    def nii(self, format=None):
        import ckan.model as model
        from ckanext.dgu.lib.reports import nii_report

        if 'regenerate' in request.GET and dguhelpers.is_sysadmin():
            from ckan.lib.helpers import flash_notice
            from ckanext.dgu.lib.reports import cached_reports
            cached_reports(['nii_report'])
            flash_notice("Report regenerated")
            h.redirect_to('/data/reports/nii')

        tmpdata = nii_report(use_cache=True)
        c.data = {}

        # Get the date time the report was generated, or now if it doesn't
        # appear in the cache
        cache_data = model.Session.query(model.DataCache.created)\
            .filter(model.DataCache.object_id=='__all__')\
            .filter(model.DataCache.key == 'nii-report').first()
        c.generated_date = cache_data[
            0] if cache_data else datetime.datetime.now()

        c.total_broken_packages = 0
        c.total_broken_resources = 0
        # Convert the lists of IDs into something usable in the template,
        # this could be faster if we did a bulk-fetch of groupname->obj for
        # instance.
        for k, list_of_dicts in tmpdata.iteritems():
            g = model.Group.get(k)
            c.data[g] = []
            for dct in list_of_dicts:
                for pkgname, results in dct.iteritems():
                    c.total_broken_resources += len(results)
                    if len(results):
                        c.total_broken_packages += 1
                    c.data[g].append({model.Package.get(pkgname): results})

        def _stringify(s, encoding, errors):
            if s is None:
                return ''
            if isinstance(s, unicode):
                return s.encode(encoding, errors)
            elif isinstance(s, (int, float)):
                pass  #let csv.QUOTE_NONNUMERIC do its thing.
            elif not isinstance(s, str):
                s = str(s)
            return s

        if format == 'csv':
            import csv

            # Set the content-disposition so that it downloads the file
            response.headers['Content-Type'] = "text/csv; charset=utf-8"
            response.headers['Content-Disposition'] = str(
                'attachment; filename=nii-broken-resources.csv')

            writer = csv.writer(response)
            writer.writerow([
                'Publisher', 'Parent publisher', 'Dataset name',
                'Resource title', 'Resource link', 'Data link'
            ])
            for publisher in c.data.keys():
                parent_groups = publisher.get_parent_groups(
                    type='organization')
                parent_publisher = parent_groups[0].title if len(
                    parent_groups) > 0 else ''

                for items in c.data[publisher]:
                    for dataset, resources in items.iteritems():
                        if len(resources) == 0:
                            continue
                        for resid, resdesc in resources:
                            resource = model.Resource.get(resid)
                            row = [
                                publisher.title, parent_publisher,
                                _stringify(dataset.title, 'utf-8', 'ignore'),
                                _stringify(resource.description, 'utf-8',
                                           'ignore') or 'No name',
                                'http://data.gov.uk/dataset/%s/resource/%s' % (
                                    dataset.name,
                                    resource.id,
                                ),
                                _stringify(resource.url, 'utf-8', 'ignore'),
                                'Yes' if dataset.extras.get(
                                    'external_reference',
                                    '') == 'ONSHUB' else 'No'
                            ]
                            writer.writerow(row)

            return ''

        return t.render('reports/nii.html')
예제 #16
0
    def viz_upload(self):
        """
        Provides direct upload to DGU for users in specific publishers.
        This is specifically for the social investment publishers so that
        they can host their files somewhere.
        """
        import ckan.model as model

        ALLOWED_PUBLISHERS = set([
            'seedbed'
            'health-social-ventures',
            'big-issue-cooperate',
            'social-incubator-east',
            'young-academy',
            'dotforge-social-ventures',
            'wayra-unltd',
            'social-incubator-north',
            'bethnal-green-ventures',
            'hub-launchpad',
            'the-social-investment-business-group',
        ])

        # Check auth .. user must be in one of selected groups.
        context = {"model": model, "session": model.Session, "user": c.user}

        if dgu_helpers.is_sysadmin():
            user_orgs = ALLOWED_PUBLISHERS
        else:
            res = get_action("organization_list_for_user")(
                context, {
                    "permission": "create_dataset"
                })
            user_orgs = set([o['name'] for o in res]) & ALLOWED_PUBLISHERS

        if not user_orgs:
            abort(401)

        publisher_q = " OR ".join(
            ["publisher:{}".format(o) for o in user_orgs])
        res = get_action("package_search")(context, {
            "fq": "({})".format(publisher_q),
            'rows': 100
        })

        c.package_names = [(
            p['name'],
            u"{} ({})".format(p['title'], p['organization']['title']),
        ) for p in res['results']]
        if not c.package_names:
            flash_error(
                "There are no datasets available in your organisation. You will be unable to upload."
            )
            return render('viz/upload.html')

        c.package_names = sorted(c.package_names)

        if request.method == 'POST':
            success, errors = self._validate_viz_upload(request.POST)
            c.title = request.POST.get('title', '')
            c.format = request.POST.get('format', '')
            c.dataset = request.POST.get('dataset', '')

            if not success:
                error_list = "<li>" + "</li><li>".join(errors) + "</li>"
                flash_error(
                    'There was a problem with your submission<br/><ul>{}</ul>'.
                    format(error_list),
                    allow_html=True)
                return render('viz/upload.html')

            extension, url = self._store_file(request.POST['upload'],
                                              c.dataset)
            if not c.format:
                c.format = extension[1:].upper()

            # Create resource
            resource = {
                u'description': c.title,
                u'url': url,
                u'format': c.format
            }

            # Show and update package
            pkg = get_action('package_show')(context, {'id': c.dataset})
            pkg['resources'].append(resource)
            res = get_action('package_update')(context, pkg)
            log.info('Added viz to dataset %s: %s', pkg['name'], resource)

            flash_success(
                'The file has been uploaded and added to the dataset. <a href="/dataset/{}" style="text-decoration:underline;">View dataset</a>'
                .format(c.dataset),
                allow_html=True)
            return redirect('/data/viz/upload')

        return render('viz/upload.html')
예제 #17
0
 def system_dashboard(self):
     if not dgu_helpers.is_sysadmin():
         abort(401, 'User must be a sysadmin to view this page.')
     return render('data/system_dashboard.html')
예제 #18
0
                since_timestamp = date_str_to_datetime(since_timestamp)
            except (ValueError, TypeError), inst:
                example = now.strftime('%Y-%m-%d%%20%H:%M') # e.g. 2013-11-30%2023:15
                abort(400, 'Could not parse timestamp "%s": %s. Must be UTC. Example: since-time=%s' % (since_timestamp, inst, example))
        elif in_the_last_x_minutes is not None:
            try:
                in_the_last_x_minutes = int(in_the_last_x_minutes)
            except ValueError, inst:
                abort(400, 'Could not parse number of minutes "%s"' % in_the_last_x_minutes)
            since_timestamp = now - \
                         datetime.timedelta(minutes=in_the_last_x_minutes)
        else:
            abort(400, 'Must specify revisions parameter. It must be one from: since-revision-id since-timestamp in-the-last-x-minutes')

        # limit is higher if sysadmin
        if is_sysadmin():
            max_limit = 1000
        else:
            max_limit = 50

        # Get the revisions in the requested time frame
        revs = model.Session.query(model.Revision) \
               .filter(model.Revision.timestamp >= since_timestamp) \
               .order_by(model.Revision.timestamp.asc()) \
               .limit(max_limit) \
               .all()
        result = OrderedDict((
            ('number_of_revisions', len(revs)),
            ('since_timestamp', since_timestamp.strftime('%Y-%m-%d %H:%M')),
            ('current_timestamp', now.strftime('%Y-%m-%d %H:%M')),
            ('since_revision_id', revs[0].id if revs else None),
예제 #19
0
 def system_dashboard(self):
     if not dgu_helpers.is_sysadmin():
         abort(401, 'User must be a sysadmin to view this page.')
     return render('data/system_dashboard.html')
예제 #20
0
    def viz_upload(self):
        """
        Provides direct upload to DGU for users in specific publishers.
        This is specifically for the social investment publishers so that
        they can host their files somewhere.
        """
        import ckan.model as model

        ALLOWED_PUBLISHERS = set([
            'seedbed'
            'health-social-ventures',
            'big-issue-cooperate',
            'social-incubator-east',
            'young-academy',
            'dotforge-social-ventures',
            'wayra-unltd',
            'social-incubator-north',
            'bethnal-green-ventures',
            'hub-launchpad',
            'the-social-investment-business-group',
        ])

        # Check auth .. user must be in one of selected groups.
        context = {"model": model, "session": model.Session, "user": c.user}

        if dgu_helpers.is_sysadmin():
            user_orgs = ALLOWED_PUBLISHERS
        else:
            res = get_action("organization_list_for_user")(context, {"permission": "create_dataset"})
            user_orgs = set([o['name'] for o in res]) & ALLOWED_PUBLISHERS

        if not user_orgs:
            abort(401)

        publisher_q = " OR ".join(["publisher:{}".format(o) for o in user_orgs])
        res = get_action("package_search")(context, {"fq": "({})".format(publisher_q), 'rows': 100})

        c.package_names = [(p['name'],u"{} ({})".format(p['title'], p['organization']['title']),) for p in res['results']]
        if not c.package_names:
            flash_error("There are no datasets available in your organisation. You will be unable to upload.")
            return render('viz/upload.html')

        c.package_names = sorted(c.package_names)

        if request.method == 'POST':
            success, errors = self._validate_viz_upload(request.POST)
            c.title = request.POST.get('title', '')
            c.format = request.POST.get('format', '')
            c.dataset = request.POST.get('dataset', '')

            if not success:
                error_list = "<li>" + "</li><li>".join(errors) + "</li>"
                flash_error('There was a problem with your submission<br/><ul>{}</ul>'.format(error_list), allow_html=True)
                return render('viz/upload.html')

            extension, url = self._store_file(request.POST['upload'], c.dataset)
            if not c.format:
                c.format = extension[1:].upper()

            # Create resource
            resource = {
                u'description': c.title,
                u'url': url,
                u'format': c.format
            }

            # Show and update package
            pkg = get_action('package_show')(context, {'id': c.dataset})
            pkg['resources'].append(resource)
            res = get_action('package_update')(context, pkg)
            log.info('Added viz to dataset %s: %s', pkg['name'], resource)

            flash_success('The file has been uploaded and added to the dataset. <a href="/dataset/{}" style="text-decoration:underline;">View dataset</a>'.format(c.dataset), allow_html=True)
            return redirect('/data/viz/upload')

        return render('viz/upload.html')
예제 #21
0
                since_timestamp = date_str_to_datetime(since_timestamp)
            except (ValueError, TypeError), inst:
                example = now.strftime('%Y-%m-%d%%20%H:%M') # e.g. 2013-11-30%2023:15
                abort(400, 'Could not parse timestamp "%s": %s. Must be UTC. Example: since-time=%s' % (since_timestamp, inst, example))
        elif in_the_last_x_minutes is not None:
            try:
                in_the_last_x_minutes = int(in_the_last_x_minutes)
            except ValueError, inst:
                abort(400, 'Could not parse number of minutes "%s"' % in_the_last_x_minutes)
            since_timestamp = now - \
                         datetime.timedelta(minutes=in_the_last_x_minutes)
        else:
            abort(400, 'Must specify revisions parameter. It must be one from: since-revision-id since-timestamp in-the-last-x-minutes')

        # limit is higher if sysadmin
        if is_sysadmin():
            max_limit = 1000
        else:
            max_limit = 50

        # Get the revisions in the requested time frame
        revs = model.Session.query(model.Revision) \
               .filter(model.Revision.timestamp >= since_timestamp) \
               .order_by(model.Revision.timestamp.asc()) \
               .limit(max_limit) \
               .all()
        result = OrderedDict((
            ('number_of_revisions', len(revs)),
            ('since_timestamp', since_timestamp.strftime('%Y-%m-%d %H:%M')),
            ('current_timestamp', now.strftime('%Y-%m-%d %H:%M')),
            ('since_revision_id', revs[0].id if revs else None),