<commit_before># -*- coding: utf-8 -*-
from logging import getLogger
from openprocurement.api.utils import (
    get_file,
    save_tender,
    upload_file,
    apply_patch,
    update_file_content_type,
    opresource,
    json_view,
    context_unpack,
)
from openprocurement.api.validation import (
    validate_file_update,
    validate_file_upload,
    validate_patch_document_data,
)
from openprocurement.api.views.contract_document import TenderAwardContractDocumentResource as BaseTenderAwardContractDocumentResource

LOGGER = getLogger(__name__)

@opresource(name='Tender Limited Contract Documents',
            collection_path='/tenders/{tender_id}/contracts/{contract_id}/documents',
            path='/tenders/{tender_id}/contracts/{contract_id}/documents/{document_id}',
            procurementMethodType='reporting',
            description="Tender contract documents")
class TenderAwardContractDocumentResource(BaseTenderAwardContractDocumentResource):

    def __init__(self, request, context):
        self.request = request
        self.db = request.registry.db

    @json_view(permission='view_tender')
    def collection_get(self):
        """Tender Contract Documents List"""
        contract = self.request.validated['contract']
        if self.request.params.get('all', ''):
            collection_data = [i.serialize("view") for i in contract['documents']]
        else:
            collection_data = sorted(dict([
                (i.id, i.serialize("view"))
                for i in contract['documents']
            ]).values(), key=lambda i: i['dateModified'])
        return {'data': collection_data}

    @json_view(permission='edit_tender', validators=(validate_file_upload,))
    def collection_post(self):
        """Tender Contract Document Upload
        """
        if self.request.validated['tender_status'] not in ['active', 'complete']:
            self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        contract = self.request.validated['contract']
        if contract.status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t add document in current contract status')
            self.request.errors.status = 403
            return
        document = upload_file(self.request)
        self.request.validated['contract'].documents.append(document)
        if save_tender(self.request):
            LOGGER.info('Created tender contract document {}'.format(document.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_create'}, {'document_id': document.id}))
            self.request.response.status = 201
            document_route = self.request.matched_route.name.replace("collection_", "")
            self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={})
            return {'data': document.serialize("view")}

    @json_view(validators=(validate_file_update,), permission='edit_tender')
    def put(self):
        """Tender Contract Document Update"""
        if self.request.validated['tender_status'] not in ['active', 'complete']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        contract = self.request.validated['contract']
        if contract.status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current contract status')
            self.request.errors.status = 403
            return
        document = upload_file(self.request)
        self.request.validated['contract'].documents.append(document)
        if save_tender(self.request):
            LOGGER.info('Created tender contract document {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_put'}))
            return {'data': document.serialize("view")}

    @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_tender')
    def patch(self):
        """Tender Contract Document Update"""
        if self.request.validated['tender_status'] not in ['active', 'complete']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        if self.request.validated['contract'].status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current contract status')
            self.request.errors.status = 403
            return
        if apply_patch(self.request, src=self.request.context.serialize()):
            update_file_content_type(self.request)
            LOGGER.info('Created tender contract document {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_patch'}))
            return {'data': self.request.context.serialize("view")}

<commit_msg>update tender status for contract_document<commit_after># -*- coding: utf-8 -*-
from logging import getLogger
from openprocurement.api.utils import (
    get_file,
    save_tender,
    upload_file,
    apply_patch,
    update_file_content_type,
    opresource,
    json_view,
    context_unpack,
)
from openprocurement.api.validation import (
    validate_file_update,
    validate_file_upload,
    validate_patch_document_data,
)
from openprocurement.api.views.contract_document import TenderAwardContractDocumentResource as BaseTenderAwardContractDocumentResource

LOGGER = getLogger(__name__)

@opresource(name='Tender Limited Contract Documents',
            collection_path='/tenders/{tender_id}/contracts/{contract_id}/documents',
            path='/tenders/{tender_id}/contracts/{contract_id}/documents/{document_id}',
            procurementMethodType='reporting',
            description="Tender contract documents")
class TenderAwardContractDocumentResource(BaseTenderAwardContractDocumentResource):

    def __init__(self, request, context):
        self.request = request
        self.db = request.registry.db

    @json_view(permission='view_tender')
    def collection_get(self):
        """Tender Contract Documents List"""
        contract = self.request.validated['contract']
        if self.request.params.get('all', ''):
            collection_data = [i.serialize("view") for i in contract['documents']]
        else:
            collection_data = sorted(dict([
                (i.id, i.serialize("view"))
                for i in contract['documents']
            ]).values(), key=lambda i: i['dateModified'])
        return {'data': collection_data}

    @json_view(permission='edit_tender', validators=(validate_file_upload,))
    def collection_post(self):
        """Tender Contract Document Upload
        """
        if self.request.validated['tender_status'] not in ['active']:
            self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        contract = self.request.validated['contract']
        if contract.status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t add document in current contract status')
            self.request.errors.status = 403
            return
        document = upload_file(self.request)
        self.request.validated['contract'].documents.append(document)
        if save_tender(self.request):
            LOGGER.info('Created tender contract document {}'.format(document.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_create'}, {'document_id': document.id}))
            self.request.response.status = 201
            document_route = self.request.matched_route.name.replace("collection_", "")
            self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={})
            return {'data': document.serialize("view")}

    @json_view(validators=(validate_file_update,), permission='edit_tender')
    def put(self):
        """Tender Contract Document Update"""
        if self.request.validated['tender_status'] not in ['active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        contract = self.request.validated['contract']
        if contract.status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current contract status')
            self.request.errors.status = 403
            return
        document = upload_file(self.request)
        self.request.validated['contract'].documents.append(document)
        if save_tender(self.request):
            LOGGER.info('Created tender contract document {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_put'}))
            return {'data': document.serialize("view")}

    @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_tender')
    def patch(self):
        """Tender Contract Document Update"""
        if self.request.validated['tender_status'] not in ['active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        if self.request.validated['contract'].status not in ['pending', 'active']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current contract status')
            self.request.errors.status = 403
            return
        if apply_patch(self.request, src=self.request.context.serialize()):
            update_file_content_type(self.request)
            LOGGER.info('Created tender contract document {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_patch'}))
            return {'data': self.request.context.serialize("view")}

<|endoftext|>


<commit_before># Copyright (C) 2014 Universidad Politecnica de Madrid
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import os
import logging

from django import shortcuts
from django.conf import settings
from django import forms
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _

from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon.utils import functions as utils
from openstack_dashboard import api
from openstack_dashboard import fiware_api
from openstack_dashboard.local import local_settings
from openstack_dashboard.dashboards.idm import forms as idm_forms

LOG = logging.getLogger('idm_logger')
AVATAR_SMALL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/small/"
AVATAR_MEDIUM = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/medium/"
AVATAR_ORIGINAL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/original/"

class CreateOrganizationForm(forms.SelfHandlingForm):
    name = forms.CharField(label=_("Name"), max_length=64, required=True)
    description = forms.CharField(label=_("Description"),
                                widget=forms.widgets.Textarea(attrs={'rows':4,'cols':40}),
                                required=True)

    def handle(self, request, data):
        #create organization
        default_domain = api.keystone.get_default_domain(request)
        try:
            city = ""
            email = ""
            website = ""
            self.object = api.keystone.tenant_create(request,
                                                     name=data['name'],
                                                     description=data['description'],
                                                     enabled=True,
                                                     domain=default_domain,
                                                     city=city,
                                                     email=email,
                                                     website=website)

        except Exception:
            exceptions.handle(request, ignore=True)
            return False

        #Set organization and user id
        organization_id = self.object.id
        user_id = request.user.id

        LOG.debug('Organization {0} created'.format(organization_id))

        #Find owner role id
        try:
            owner_role = fiware_api.keystone.get_owner_role(self.request)
            LOG.debug(owner_role)
            if owner_role is None:
                owner = getattr(local_settings,
                                    "KEYSTONE_OWNER_ROLE", None)
                msg = _('Could not find default role "%s" in Keystone') % \
                        default
                LOG.debug(msg)
                raise exceptions.NotFound(msg)
        except Exception as e:
            exceptions.handle(self.request,
                                redirect=reverse('horizon:idm:organizations:index'))
            return False
        try:
            api.keystone.add_tenant_user_role(request,
                                            project=organization_id,
                                            user=user_id,
                                            role=owner_role.id)
            LOG.debug('Added user {0} and organization {1} to role {2}'.format(user_id, organization_id, owner_role.id))
        except Exception:
            exceptions.handle(request,
                                    _('Failed to add %s organization to list')
                                    % data['name'])
            return False

        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response

class InfoForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    name = forms.CharField(label=_("Name"), max_length=64, required=True)
    description = forms.CharField(label=_("Description"),
                                widget=forms.widgets.Textarea(attrs={'rows':4,'cols':40}),
                                required=True)
    city = forms.CharField(label=_("City"), max_length=64, required=False)
    title = 'Information'

    def handle(self, request, data):
        try:
            api.keystone.tenant_update(request,
                                    data['orgID'],
                                    name=data['name'],
                                    description=data['description'],
                                    city=data['city'])

            LOG.debug('Organization {0} updated'.format(data['orgID']))
            messages.success(request, _("Organization updated successfully."))
            response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
            return response
        except Exception:
            response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
            return response

class ContactForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    email = forms.EmailField(label=_("E-mail"), required=False)
    website = forms.URLField(label=_("Website"), required=False)
    title = 'Contact Information'

    def handle(self, request, data):
        api.keystone.tenant_update(request,
                                data['orgID'],
                                email=data['email'],
                                website=data['website'])
        LOG.debug('Organization {0} updated'.format(data['orgID']))
        messages.success(request, _("Organization updated successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class AvatarForm(forms.SelfHandlingForm, idm_forms.ImageCropMixin):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    image = forms.ImageField(required=False)
    title = 'Avatar Update'

    def handle(self, request, data):
        if request.FILES:
            image = request.FILES['image']
            output_img = self.crop(image)

            small = 25, 25, 'small'
            medium = 36, 36, 'medium'
            original = 100, 100, 'original'
            meta = [original, medium, small]
            for meta in meta:
                size = meta[0], meta[1]
                img_type = meta[2]
                output_img.thumbnail(size)
                img = 'OrganizationAvatar/' + img_type + "/" + self.data['orgID']
                output_img.save(settings.MEDIA_ROOT + "/" + img, 'JPEG')

                if img_type == 'small':
                    api.keystone.tenant_update(request, data['orgID'], img_small=img)
                elif img_type == 'medium':
                    api.keystone.tenant_update(request, data['orgID'], img_medium=img)
                else:
                    api.keystone.tenant_update(request, data['orgID'], img_original=img)

            LOG.debug('Organization {0} image updated'.format(data['orgID']))
            messages.success(request, _("Organization updated successfully."))

        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CancelForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    title = 'Cancel'

    def handle(self, request, data, organization):
        image = getattr(organization,'img_original','')
        if "OrganizationAvatar" in image:
            os.remove(AVATAR_SMALL + organization.id)
            os.remove(AVATAR_MEDIUM + organization.id)
            os.remove(AVATAR_ORIGINAL + organization.id)
            LOG.debug('{0} deleted'.format(image))
        api.keystone.tenant_delete(request, organization)
        LOG.info('Organization {0} deleted'.format(organization.id))
        messages.success(request, _("Organization deleted successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response
<commit_msg>error message for duplicate entry in orgs<commit_after># Copyright (C) 2014 Universidad Politecnica de Madrid
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import os
import logging

from django import shortcuts
from django.conf import settings
from django import forms
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _

from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon.utils import functions as utils
from openstack_dashboard import api
from openstack_dashboard import fiware_api
from openstack_dashboard.local import local_settings
from openstack_dashboard.dashboards.idm import forms as idm_forms

LOG = logging.getLogger('idm_logger')
AVATAR_SMALL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/small/"
AVATAR_MEDIUM = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/medium/"
AVATAR_ORIGINAL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/original/"

class CreateOrganizationForm(forms.SelfHandlingForm):
    name = forms.CharField(label=_("Name"), max_length=64, required=True)
    description = forms.CharField(label=_("Description"),
                                widget=forms.widgets.Textarea(attrs={'rows':4,'cols':40}),
                                required=True)

    def handle(self, request, data):
        #create organization
        default_domain = api.keystone.get_default_domain(request)
        try:
            city = ""
            email = ""
            website = ""
            self.object = api.keystone.tenant_create(request,
                                                     name=data['name'],
                                                     description=data['description'],
                                                     enabled=True,
                                                     domain=default_domain,
                                                     city=city,
                                                     email=email,
                                                     website=website)

        except Exception:
            msg = 'This name is already taken by another organization'
            exceptions.handle(request, ignore=True)
            messages.error(request,msg)
            return False

        #Set organization and user id
        organization_id = self.object.id
        user_id = request.user.id

        LOG.debug('Organization {0} created'.format(organization_id))

        #Find owner role id
        try:
            owner_role = fiware_api.keystone.get_owner_role(self.request)
            LOG.debug(owner_role)
            if owner_role is None:
                owner = getattr(local_settings,
                                    "KEYSTONE_OWNER_ROLE", None)
                msg = _('Could not find default role "%s" in Keystone') % \
                        default
                LOG.debug(msg)
                raise exceptions.NotFound(msg)
        except Exception as e:
            exceptions.handle(self.request,
                                redirect=reverse('horizon:idm:organizations:index'))
            return False
        try:
            api.keystone.add_tenant_user_role(request,
                                            project=organization_id,
                                            user=user_id,
                                            role=owner_role.id)
            LOG.debug('Added user {0} and organization {1} to role {2}'.format(user_id, organization_id, owner_role.id))
        except Exception:
            exceptions.handle(request,
                                    _('Failed to add %s organization to list')
                                    % data['name'])
            return False

        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response

class InfoForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    name = forms.CharField(label=_("Name"), max_length=64, required=True)
    description = forms.CharField(label=_("Description"),
                                widget=forms.widgets.Textarea(attrs={'rows':4,'cols':40}),
                                required=True)
    city = forms.CharField(label=_("City"), max_length=64, required=False)
    title = 'Information'

    def handle(self, request, data):
        try:
            api.keystone.tenant_update(request,
                                    data['orgID'],
                                    name=data['name'],
                                    description=data['description'],
                                    city=data['city'])

            LOG.debug('Organization {0} updated'.format(data['orgID']))
            messages.success(request, _("Organization updated successfully."))
            response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
            return response
        except Exception:
            response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
            return response

class ContactForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    email = forms.EmailField(label=_("E-mail"), required=False)
    website = forms.URLField(label=_("Website"), required=False)
    title = 'Contact Information'

    def handle(self, request, data):
        api.keystone.tenant_update(request,
                                data['orgID'],
                                email=data['email'],
                                website=data['website'])
        LOG.debug('Organization {0} updated'.format(data['orgID']))
        messages.success(request, _("Organization updated successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class AvatarForm(forms.SelfHandlingForm, idm_forms.ImageCropMixin):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    image = forms.ImageField(required=False)
    title = 'Avatar Update'

    def handle(self, request, data):
        if request.FILES:
            image = request.FILES['image']
            output_img = self.crop(image)

            small = 25, 25, 'small'
            medium = 36, 36, 'medium'
            original = 100, 100, 'original'
            meta = [original, medium, small]
            for meta in meta:
                size = meta[0], meta[1]
                img_type = meta[2]
                output_img.thumbnail(size)
                img = 'OrganizationAvatar/' + img_type + "/" + self.data['orgID']
                output_img.save(settings.MEDIA_ROOT + "/" + img, 'JPEG')

                if img_type == 'small':
                    api.keystone.tenant_update(request, data['orgID'], img_small=img)
                elif img_type == 'medium':
                    api.keystone.tenant_update(request, data['orgID'], img_medium=img)
                else:
                    api.keystone.tenant_update(request, data['orgID'], img_original=img)

            LOG.debug('Organization {0} image updated'.format(data['orgID']))
            messages.success(request, _("Organization updated successfully."))

        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CancelForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=_("ID"), widget=forms.HiddenInput())
    title = 'Cancel'

    def handle(self, request, data, organization):
        image = getattr(organization,'img_original','')
        if "OrganizationAvatar" in image:
            os.remove(AVATAR_SMALL + organization.id)
            os.remove(AVATAR_MEDIUM + organization.id)
            os.remove(AVATAR_ORIGINAL + organization.id)
            LOG.debug('{0} deleted'.format(image))
        api.keystone.tenant_delete(request, organization)
        LOG.info('Organization {0} deleted'.format(organization.id))
        messages.success(request, _("Organization deleted successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response
<|endoftext|>


<commit_before># Copyright 2021 UW-IT, University of Washington
# SPDX-License-Identifier: Apache-2.0

""" Copyright 2013, 2014 UW Information Technology, University of Washington

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

"""

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from oauth_provider.models import Token
from spotseeker_server.models import TrustedOAuthClient

def authorize(request, token, callback, params):
    consumer = token.consumer

    bypasses_auth = False
    trusted_client = TrustedOAuthClient.objects.filter(consumer=consumer)
    if len(trusted_client) and trusted_client[0].bypasses_user_authorization:
        bypasses_auth = True

    request.session['oauth'] = token.key
    return render_to_response("oauth/authorize.html", {
        "consumer": consumer.name,
        "token": request.GET["oauth_token"],
        "bypass_auth": bypasses_auth,
    }, RequestContext(request))

def callback(request, **kwargs):
    if "oauth_token" not in kwargs:
        return render_to_response("oauth/declined.html")

    token = Token.objects.get(key=kwargs["oauth_token"])

    return render_to_response("oauth/oob.html", {
        "verifier": token.verifier,
    }, RequestContext(request))
<commit_msg>Reformat and update copyright.<commit_after># Copyright 2021 UW-IT, University of Washington
# SPDX-License-Identifier: Apache-2.0

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from oauth_provider.models import Token
from spotseeker_server.models import TrustedOAuthClient

def authorize(request, token, callback, params):
    consumer = token.consumer

    bypasses_auth = False
    trusted_client = TrustedOAuthClient.objects.filter(consumer=consumer)
    if len(trusted_client) and trusted_client[0].bypasses_user_authorization:
        bypasses_auth = True

    request.session["oauth"] = token.key
    return render_to_response(
        "oauth/authorize.html",
        {
            "consumer": consumer.name,
            "token": request.GET["oauth_token"],
            "bypass_auth": bypasses_auth,
        },
        RequestContext(request),
    )

def callback(request, **kwargs):
    if "oauth_token" not in kwargs:
        return render_to_response("oauth/declined.html")

    token = Token.objects.get(key=kwargs["oauth_token"])

    return render_to_response(
        "oauth/oob.html",
        {
            "verifier": token.verifier,
        },
        RequestContext(request),
    )
<|endoftext|>


<commit_before>"""
There are two ways to authenticate a request:
* Present the session cookie returned after logging in
* Send a Google access token as the access_token query parameter
"""
from flask import (abort, Blueprint, current_app, flash, redirect,
                   render_template, request, session, url_for, jsonify)
from flask_oauthlib.client import OAuth, OAuthException
from flask_oauthlib.contrib.oauth2 import bind_sqlalchemy

from flask_login import (LoginManager, login_user, logout_user, login_required,
                         current_user)

import datetime as dt
import logging

from server import utils
from server.models import db, User, Enrollment, Client, Token, Grant
from server.extensions import csrf, oauth_provider

logger = logging.getLogger(__name__)

auth = Blueprint('auth', __name__)

auth.config = {}

@auth.record
def record_params(setup_state):
    """ Load used app configs into local config on registration from
    server/__init__.py """
    app = setup_state.app
    oauth.init_app(app)

oauth = OAuth()
google_auth = oauth.remote_app(
    'google',
    app_key='GOOGLE',
    request_token_params={
        'scope': 'email',
        'prompt': 'select_account'
    },
    base_url='https://www.googleapis.com/oauth2/v1/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url='https://accounts.google.com/o/oauth2/token',
    authorize_url='https://accounts.google.com/o/oauth2/auth',
)

@google_auth.tokengetter
def google_oauth_token(token=None):
    return session.get('google_token')

###########
# Helpers #
###########

def check_oauth_token(scopes=[]):
    """ Check the request for OAuth creds.
    Requires: Flask Request and access_token in request.args
    Return Token or None
    """
    # Check with local OAuth Provider for user
    valid, req = oauth_provider.verify_request(scopes)
    if valid:
        return req

def get_token_if_valid(treshold_min=2):
    """ Get the current google token if it will continue to be valid for the
    next TRESHOLD_MIN minutes. Otherwise, return None.
    """
    future_usage = dt.datetime.now() + dt.timedelta(minutes=treshold_min)
    expiry_time = session.get('token_expiry')
    if expiry_time and expiry_time >= future_usage:
        return session.get('google_token')
    return None

def user_from_email(email):
    """Get a User with the given email, or create one."""
    user = User.lookup(email)
    if not user:
        user = User(email=email)
        db.session.add(user)
        db.session.commit()
    return user

def user_from_google_token(token):
    """
    Get a User with the given Google access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("okstaff@okpy.org")
    resp = google_auth.get('userinfo', token=(token, ''))
    if resp.status != 200:
        return None
    return user_from_email(resp.data['email'])

login_manager = LoginManager()

@login_manager.user_loader
def load_user(userid):
    return User.get_by_id(userid)

@login_manager.request_loader
def load_user_from_request(request):
    """ For the API routes to allow login via access_token.
    """
    if request.blueprint != "api":
        return None
    # Checks for bearer token in header authentication
    oauth_token = check_oauth_token()
    if oauth_token:
        oauth_token.user.scopes = oauth_token.access_token.scopes
        return oauth_token.user
    # Fallback to Google Auth
    token = request.args.get('access_token')
    return user_from_google_token(token)

@login_manager.unauthorized_handler
def unauthorized():
    session['after_login'] = request.url
    return redirect(url_for('auth.login'))

def authorize_user(user):
    login_user(user)
    after_login = session.pop('after_login', None)
    return redirect(after_login or url_for('student.index'))

def use_testing_login():
    """
    Return True if we use the unsecure testing login instead of Google OAuth.
    Requires TESTING_LOGIN = True in the config and the environment is not prod.
    """
    return (current_app.config.get('TESTING_LOGIN', False) and
            current_app.config.get('ENV') != 'prod')

def csrf_check():
    """ Manually against CSRF if available. Usually done by default, but this
    function is neccesary for routes in blueprints that have disabled csrf protection.

    CSRF protect is disabled in testing, but not in dev or prod.
    Always checks for CSRF in prod
    """
    current_env = current_app.config.get('ENV')
    csrf_enabled = current_app.config.get('WTF_CSRF_ENABLED', True)

    if current_env == 'prod' or csrf_enabled:
        csrf.protect()

@auth.route("/login/")
def login():
    """
    Authenticates a user with an access token using Google APIs.
    """
    if use_testing_login():
        return redirect(url_for('.testing_login'))
    return google_auth.authorize(callback=url_for('.authorized', _external=True))

@auth.route('/login/authorized/')
@google_auth.authorized_handler
def authorized(resp):
    if isinstance(resp, OAuthException):
        error = "{0} - {1}".format(resp.data.get('error', 'Unknown Error'),
                                   resp.data.get('error_description', 'Unknown'))
        flash(error, "error")
        # TODO Error Page
        return redirect("/")
    if resp is None:
        error = "Access denied: reason={0} error={1}".format(
            request.args['error_reason'],
            request.args['error_description']
        )
        flash(error, "error")
        # TODO Error Page
        return redirect("/")

    access_token = resp['access_token']
    user = user_from_google_token(access_token)

    expires_in = resp.get('expires_in', 0)
    session['token_expiry'] = dt.datetime.now() + dt.timedelta(seconds=expires_in)
    session['google_token'] = (access_token, '')  # (access_token, secret)
    return authorize_user(user)

################
# Other Routes #
################

@auth.route('/sudo/<email>/')
@login_required
def sudo_login(email):
    logger.info("Sudo attempt to %s from %s", email, current_user)
    if not current_user.is_admin:
        logger.info("Unauthorized sudo %s", current_user)
        return abort(403, 'Unauthorized to sudo')
    user = User.lookup(email)
    if not user:
        return abort(404, "User does not exist")
    logger.info("Sudo Mode: %s from %s", email, current_user)
    session['sudo-user'] = current_user.email
    return authorize_user(user)

# Backdoor log in if you want to impersonate a user.
# Will not give you a Google auth token.
# Requires that TESTING_LOGIN = True in the config and we must not be running in prod.
@auth.route('/testing-login/')
def testing_login():
    if not use_testing_login():
        abort(404)

    random_staff = utils.random_row(Enrollment.query.filter_by(role='staff'))
    if random_staff:
        random_staff = random_staff.user
    random_student = utils.random_row(Enrollment.query.filter_by(role='student'))
    if random_student:
        random_student = random_student.user
    return render_template('testing-login.html',
        callback=url_for(".testing_authorized"),
        random_admin=utils.random_row(User.query.filter_by(is_admin=True)),
        random_staff=random_staff,
        random_student=random_student,
        random_user=utils.random_row(User.query))

@auth.route('/testing-login/authorized/', methods=['POST'])
def testing_authorized():
    if not use_testing_login():
        abort(404)
    user = user_from_email(request.form['email'])
    return authorize_user(user)

@auth.route('/testing-login/logout/', methods=['POST'])
def testing_logout():
    if not use_testing_login():
        abort(404)
    logout_user()
    session.clear()
    return redirect(url_for('student.index'))

@auth.route("/logout/", methods=['POST'])
@login_required
def logout():
    # Only CSRF protect this route.
    csrf_check()

    logout_user()
    session.clear()
    return redirect(url_for('student.index'))
<commit_msg>avoid mutable args in oauth scope check<commit_after>"""
There are two ways to authenticate a request:
* Present the session cookie returned after logging in
* Send a Google access token as the access_token query parameter
"""
from flask import (abort, Blueprint, current_app, flash, redirect,
                   render_template, request, session, url_for, jsonify)
from flask_oauthlib.client import OAuth, OAuthException
from flask_oauthlib.contrib.oauth2 import bind_sqlalchemy

from flask_login import (LoginManager, login_user, logout_user, login_required,
                         current_user)

import datetime as dt
import logging

from server import utils
from server.models import db, User, Enrollment, Client, Token, Grant
from server.extensions import csrf, oauth_provider

logger = logging.getLogger(__name__)

auth = Blueprint('auth', __name__)

auth.config = {}

@auth.record
def record_params(setup_state):
    """ Load used app configs into local config on registration from
    server/__init__.py """
    app = setup_state.app
    oauth.init_app(app)

oauth = OAuth()
google_auth = oauth.remote_app(
    'google',
    app_key='GOOGLE',
    request_token_params={
        'scope': 'email',
        'prompt': 'select_account'
    },
    base_url='https://www.googleapis.com/oauth2/v1/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url='https://accounts.google.com/o/oauth2/token',
    authorize_url='https://accounts.google.com/o/oauth2/auth',
)

@google_auth.tokengetter
def google_oauth_token(token=None):
    return session.get('google_token')

###########
# Helpers #
###########

def check_oauth_token(scopes=None):
    """ Check the request for OAuth creds.
    Requires: Flask Request and access_token in request.args
    Return Token or None
    """
    if scopes is None:
        scopes = []
    # Check with local OAuth Provider for user
    valid, req = oauth_provider.verify_request(scopes)
    if valid:
        return req

def get_token_if_valid(treshold_min=2):
    """ Get the current google token if it will continue to be valid for the
    next TRESHOLD_MIN minutes. Otherwise, return None.
    """
    future_usage = dt.datetime.now() + dt.timedelta(minutes=treshold_min)
    expiry_time = session.get('token_expiry')
    if expiry_time and expiry_time >= future_usage:
        return session.get('google_token')
    return None

def user_from_email(email):
    """Get a User with the given email, or create one."""
    user = User.lookup(email)
    if not user:
        user = User(email=email)
        db.session.add(user)
        db.session.commit()
    return user

def user_from_google_token(token):
    """
    Get a User with the given Google access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("okstaff@okpy.org")
    resp = google_auth.get('userinfo', token=(token, ''))
    if resp.status != 200:
        return None
    return user_from_email(resp.data['email'])

login_manager = LoginManager()

@login_manager.user_loader
def load_user(userid):
    return User.get_by_id(userid)

@login_manager.request_loader
def load_user_from_request(request):
    """ For the API routes to allow login via access_token.
    """
    if request.blueprint != "api":
        return None
    # Checks for bearer token in header authentication
    oauth_token = check_oauth_token()
    if oauth_token:
        oauth_token.user.scopes = oauth_token.access_token.scopes
        return oauth_token.user
    # Fallback to Google Auth
    token = request.args.get('access_token')
    return user_from_google_token(token)

@login_manager.unauthorized_handler
def unauthorized():
    session['after_login'] = request.url
    return redirect(url_for('auth.login'))

def authorize_user(user):
    login_user(user)
    after_login = session.pop('after_login', None)
    return redirect(after_login or url_for('student.index'))

def use_testing_login():
    """
    Return True if we use the unsecure testing login instead of Google OAuth.
    Requires TESTING_LOGIN = True in the config and the environment is not prod.
    """
    return (current_app.config.get('TESTING_LOGIN', False) and
            current_app.config.get('ENV') != 'prod')

def csrf_check():
    """ Manually against CSRF if available. Usually done by default, but this
    function is neccesary for routes in blueprints that have disabled csrf protection.

    CSRF protect is disabled in testing, but not in dev or prod.
    Always checks for CSRF in prod
    """
    current_env = current_app.config.get('ENV')
    csrf_enabled = current_app.config.get('WTF_CSRF_ENABLED', True)

    if current_env == 'prod' or csrf_enabled:
        csrf.protect()

@auth.route("/login/")
def login():
    """
    Authenticates a user with an access token using Google APIs.
    """
    if use_testing_login():
        return redirect(url_for('.testing_login'))
    return google_auth.authorize(callback=url_for('.authorized', _external=True))

@auth.route('/login/authorized/')
@google_auth.authorized_handler
def authorized(resp):
    if isinstance(resp, OAuthException):
        error = "{0} - {1}".format(resp.data.get('error', 'Unknown Error'),
                                   resp.data.get('error_description', 'Unknown'))
        flash(error, "error")
        # TODO Error Page
        return redirect("/")
    if resp is None:
        error = "Access denied: reason={0} error={1}".format(
            request.args['error_reason'],
            request.args['error_description']
        )
        flash(error, "error")
        # TODO Error Page
        return redirect("/")

    access_token = resp['access_token']
    user = user_from_google_token(access_token)

    expires_in = resp.get('expires_in', 0)
    session['token_expiry'] = dt.datetime.now() + dt.timedelta(seconds=expires_in)
    session['google_token'] = (access_token, '')  # (access_token, secret)
    return authorize_user(user)

################
# Other Routes #
################

@auth.route('/sudo/<email>/')
@login_required
def sudo_login(email):
    logger.info("Sudo attempt to %s from %s", email, current_user)
    if not current_user.is_admin:
        logger.info("Unauthorized sudo %s", current_user)
        return abort(403, 'Unauthorized to sudo')
    user = User.lookup(email)
    if not user:
        return abort(404, "User does not exist")
    logger.info("Sudo Mode: %s from %s", email, current_user)
    session['sudo-user'] = current_user.email
    return authorize_user(user)

# Backdoor log in if you want to impersonate a user.
# Will not give you a Google auth token.
# Requires that TESTING_LOGIN = True in the config and we must not be running in prod.
@auth.route('/testing-login/')
def testing_login():
    if not use_testing_login():
        abort(404)

    random_staff = utils.random_row(Enrollment.query.filter_by(role='staff'))
    if random_staff:
        random_staff = random_staff.user
    random_student = utils.random_row(Enrollment.query.filter_by(role='student'))
    if random_student:
        random_student = random_student.user
    return render_template('testing-login.html',
        callback=url_for(".testing_authorized"),
        random_admin=utils.random_row(User.query.filter_by(is_admin=True)),
        random_staff=random_staff,
        random_student=random_student,
        random_user=utils.random_row(User.query))

@auth.route('/testing-login/authorized/', methods=['POST'])
def testing_authorized():
    if not use_testing_login():
        abort(404)
    user = user_from_email(request.form['email'])
    return authorize_user(user)

@auth.route('/testing-login/logout/', methods=['POST'])
def testing_logout():
    if not use_testing_login():
        abort(404)
    logout_user()
    session.clear()
    return redirect(url_for('student.index'))

@auth.route("/logout/", methods=['POST'])
@login_required
def logout():
    # Only CSRF protect this route.
    csrf_check()

    logout_user()
    session.clear()
    return redirect(url_for('student.index'))
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""Defines the main menu module for a program that inputs a MemberHub directory dump,
a school roster, and a hub map to perform analyses on the MemberHub directory.
"""

import directory_tools
import roster_tools
import hub_map_tools
import import_file_tools
import family
import person

def FindMissingEmail(directory):
    """menu.FindMissingEmail
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have an
    email address associated with their entry.
    ASSUMPTIONS:
    None.
    """
    adult_count = no_email_count = 0
    for entry_family in directory:
        for adult in entry_family.GetAdults():
            adult_count += 1
            if adult.DoesNotListEmailAddress():
                print "The entry for this person does not have an email address:"
                adult.Print()
                no_email_count += 1

    print "Found %d out of %d adults with missing email addresses" % \
          (no_email_count, adult_count)

def FindOrphans(directory):
    """menu.FindOrphans
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the children in the directory who do not have an
    parent associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = orphan_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsOrphan():
            print "The entry for this family does not identify parents:"
            entry_family.Print()
            orphan_count += 1

    print "Found %d families without adults out of %d families" % \
          (orphan_count, family_count)

def FindChildless(directory):
    """menu.FindChildless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have a
    child associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = childless_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsChildless():
            print "The entry for this family does not identify children:"
            entry_family.Print()
            childless_count += 1

    print "Found %d families without children out of %d families" % \
          (childless_count, family_count)

def FindHubless(arg_list):
    """menu.FindHubless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    map_d     = arg_list[1]
    hubless   = []

    child_count = adult_count = 0

    for directory_family in directory:
        for adult in directory_family.GetAdults():
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, adult.GetHubs()):
                print "Found adult not in a classroom hub (%s)" % adult.GetHubs()
                adult.Print()
                adult_count += 1
                hubless.append(adult)

        for child in directory_family.GetChildren():
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, child.GetHubs()):
                print "Found child not in a classroom hub (%s)" % child.GetHubs()
                child.Print()
                child_count += 1
                hubless.append(child)

    print "Found %d children who are not in a classroom hub." % child_count
    print "Found %d adults who are not in at least one classroom hub." % adult_count

    return hubless

def PrintHubless(arg_list):
    discard = FindHubless(arg_list)

def MakeImportForHubless(arg_list):
    """menu.MakeImportForHubless
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    Creates a comma-separated text file that can be imported into MemberHub to assign
    hub IDs to existing directory entries.
    ASSUMPTIONS:
    None.
    """
    directory   = arg_list[0]
    map_d       = arg_list[1]
    roster      = arg_list[2]
    hubless     = FindHubless(arg_list)
    update_hubs = []

    hubed_count = hubless_count = 0

    for hubless_person in hubless:
        for roster_family in roster:
            found_person = roster_family.FindPersonInFamily(hubless_person)
            if not found_person == None:
                hubless_person.SetHubs(found_person.GetHubs())
                update_hubs.append(hubless_person)
                hubed_count += 1
                break
        else:
            print "Did not find match for this person in the roster:"
            hubless_person.Print()
            hubless_count += 1

    print "Processed %d entries that were not in any classroom hub." % len(hubless)
    print "Was able to find classroom hubs for %d entries." % hubed_count
    print "Was not able to find classroom hubs for %d entries." % hubless_count

    import_file_tools.CreateHublessImportFile(update_hubs)

def FindEntriless(arg_list):
    """menu.FindEntriless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - roster    -- list containing the school roster families
    OUTPUTS:
    - entriless -- returns list of families in the school roster that could not
                   be found in the directory
    Also prints to standard output the names in the school roster who are not in the
    MemberHub directory.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    entriless = []

    for roster_family in roster:

        for directory_family in direct_d:
            if directory_family.IsSameFamily(roster_family):
                break

        else:
            print "Did not find this family from the roster in the directory:"
            roster_family.Print()
            entriless.append(roster_family)

    print "Found %d people on the roster who were not in the directory" % len(entriless)
    return entriless

def PrintNotInDirectory(arg_list):
    discard = FindEntriless(arg_list)

def MakeImportNotInDirectory(arg_list):
    """menu.MakeImportNotInDirectory
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    map_d     = arg_list[2]
    entriless = FindEntriless(arg_list)

    import_file_tools.CreateNewMemberImport(entriless)

def MakePrompt(choices):
    choice_list = sorted(choices)
    guts = '\n'.join(['(%s)%s' % (choice[0], choice[1:])
                      for choice in choice_list])
    return 'Choose:\n' + guts + '\nOr press <enter> to quit '

def RunMenu(directory, roster, map_d):
    """Runs the user interface for dictionary manipulation."""
    # The choices dictionary has function names for values.
    choices = {'1 - Find Missing Email':{'Function':FindMissingEmail,'Arg':directory},
               '2 - Find Orphans':{'Function':FindOrphans,'Arg':directory},
               '3 - Find Childless':{'Function':FindChildless,'Arg':directory},
               '4 - Find Not In Hub':{'Function':PrintHubless,'Arg':[directory,map_d]},
               '5 - Make Import File for Not In Hub':{'Function':MakeImportForHubless,
                                                      'Arg':[directory,map_d,roster]},
               '6 - Find Not in Directory':{'Function':PrintNotInDirectory,
                                            'Arg':[directory,roster]},
               '7 - Make Import File for Not In Directory':
                                           {'Function':MakeImportNotInDirectory,
                                            'Arg':[directory,roster,map_d]}}

    prompt = MakePrompt(choices)

    while True:
        raw_choice = raw_input(prompt)
        if not raw_choice:
            break
        given_choice = raw_choice[0].lower()
        for maybe_choice in choices:
            if maybe_choice[0] == given_choice:
                # The appropriate function is called
                # using the dictionary value for the name
                # of the function.
                choices[maybe_choice]['Function'](choices[maybe_choice]['Arg'])
                break
        else:
            print '%s is not an acceptible choice.' % raw_choice

def main():
    directory = directory_tools.ReadDirectory()
    roster    = roster_tools.ReadRoster()
    map_d     = hub_map_tools.ReadMap()
    RunMenu(directory, roster, map_d)

if __name__ == '__main__':
    main()
<commit_msg>clean up screen output<commit_after>#!/usr/bin/env python
"""Defines the main menu module for a program that inputs a MemberHub directory dump,
a school roster, and a hub map to perform analyses on the MemberHub directory.
"""

import directory_tools
import roster_tools
import hub_map_tools
import import_file_tools
import family
import person

def FindMissingEmail(directory):
    """menu.FindMissingEmail
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have an
    email address associated with their entry.
    ASSUMPTIONS:
    None.
    """
    adult_count = no_email_count = 0
    for entry_family in directory:
        for adult in entry_family.GetAdults():
            adult_count += 1
            if adult.DoesNotListEmailAddress():
                print "The entry for this person does not have an email address:",
                adult.Print()
                no_email_count += 1

    print "Found %d out of %d adults with missing email addresses" % \
          (no_email_count, adult_count)

def FindOrphans(directory):
    """menu.FindOrphans
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the children in the directory who do not have an
    parent associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = orphan_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsOrphan():
            print "The entry for this family does not identify parents:",
            entry_family.Print()
            orphan_count += 1

    print "Found %d families without adults out of %d families" % \
          (orphan_count, family_count)

def FindChildless(directory):
    """menu.FindChildless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have a
    child associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = childless_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsChildless():
            print "The entry for this family does not identify children:",
            entry_family.Print()
            childless_count += 1

    print "Found %d families without children out of %d families" % \
          (childless_count, family_count)

def FindHubless(arg_list):
    """menu.FindHubless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    map_d     = arg_list[1]
    hubless   = []

    child_count = adult_count = 0

    for directory_family in directory:
        for adult in directory_family.GetAdults():
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, adult.GetHubs()):
                print "Found adult not in a classroom hub (%s)" % adult.GetHubs()
                adult.Print()
                adult_count += 1
                hubless.append(adult)

        for child in directory_family.GetChildren():
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, child.GetHubs()):
                print "Found child not in a classroom hub (%s)" % child.GetHubs()
                child.Print()
                child_count += 1
                hubless.append(child)

    print "Found %d children who are not in a classroom hub." % child_count
    print "Found %d adults who are not in at least one classroom hub." % adult_count

    return hubless

def PrintHubless(arg_list):
    discard = FindHubless(arg_list)

def MakeImportForHubless(arg_list):
    """menu.MakeImportForHubless
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    Creates a comma-separated text file that can be imported into MemberHub to assign
    hub IDs to existing directory entries.
    ASSUMPTIONS:
    None.
    """
    directory   = arg_list[0]
    map_d       = arg_list[1]
    roster      = arg_list[2]
    hubless     = FindHubless(arg_list)
    update_hubs = []

    hubed_count = hubless_count = 0

    for hubless_person in hubless:
        for roster_family in roster:
            found_person = roster_family.FindPersonInFamily(hubless_person)
            if not found_person == None:
                hubless_person.SetHubs(found_person.GetHubs())
                update_hubs.append(hubless_person)
                hubed_count += 1
                break
        else:
            print "Did not find match for this person in the roster:",
            hubless_person.Print()
            hubless_count += 1

    print "Processed %d entries that were not in any classroom hub." % len(hubless)
    print "Was able to find classroom hubs for %d entries." % hubed_count
    print "Was not able to find classroom hubs for %d entries." % hubless_count

    import_file_tools.CreateHublessImportFile(update_hubs)

def FindEntriless(arg_list):
    """menu.FindEntriless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - roster    -- list containing the school roster families
    OUTPUTS:
    - entriless -- returns list of families in the school roster that could not
                   be found in the directory
    Also prints to standard output the names in the school roster who are not in the
    MemberHub directory.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    entriless = []

    for roster_family in roster:

        for directory_family in direct_d:
            if directory_family.IsSameFamily(roster_family):
                break

        else:
            print "Did not find this family from the roster in the directory:",
            roster_family.Print()
            entriless.append(roster_family)

    print "Found %d people on the roster who were not in the directory" % len(entriless)
    return entriless

def PrintNotInDirectory(arg_list):
    discard = FindEntriless(arg_list)

def MakeImportNotInDirectory(arg_list):
    """menu.MakeImportNotInDirectory
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    map_d     = arg_list[2]
    entriless = FindEntriless(arg_list)

    import_file_tools.CreateNewMemberImport(entriless)

def MakePrompt(choices):
    choice_list = sorted(choices)
    guts = '\n'.join(['(%s)%s' % (choice[0], choice[1:])
                      for choice in choice_list])
    return 'Choose:\n' + guts + '\nOr press <enter> to quit '

def RunMenu(directory, roster, map_d):
    """Runs the user interface for dictionary manipulation."""
    # The choices dictionary has function names for values.
    choices = {'1 - Find Missing Email':{'Function':FindMissingEmail,'Arg':directory},
               '2 - Find Orphans':{'Function':FindOrphans,'Arg':directory},
               '3 - Find Childless':{'Function':FindChildless,'Arg':directory},
               '4 - Find Not In Hub':{'Function':PrintHubless,'Arg':[directory,map_d]},
               '5 - Make Import File for Not In Hub':{'Function':MakeImportForHubless,
                                                      'Arg':[directory,map_d,roster]},
               '6 - Find Not in Directory':{'Function':PrintNotInDirectory,
                                            'Arg':[directory,roster]},
               '7 - Make Import File for Not In Directory':
                                           {'Function':MakeImportNotInDirectory,
                                            'Arg':[directory,roster,map_d]}}

    prompt = MakePrompt(choices)

    while True:
        raw_choice = raw_input(prompt)
        if not raw_choice:
            break
        given_choice = raw_choice[0].lower()
        for maybe_choice in choices:
            if maybe_choice[0] == given_choice:
                # The appropriate function is called
                # using the dictionary value for the name
                # of the function.
                choices[maybe_choice]['Function'](choices[maybe_choice]['Arg'])
                break
        else:
            print '%s is not an acceptible choice.' % raw_choice

def main():
    directory = directory_tools.ReadDirectory()
    roster    = roster_tools.ReadRoster()
    map_d     = hub_map_tools.ReadMap()
    RunMenu(directory, roster, map_d)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>import graphene
from graphene_django import DjangoObjectType
from django.utils import timezone
from accelerator.models import (
    ExpertProfile,
    UserRole,
    ProgramRole,
    Program,
)
from impact.graphql.types.industry_type import IndustryType  # noqa: F401
from impact.graphql.types.startup_type import StartupType
from impact.graphql.types.program_family_type import ProgramFamilyType  # noqa: F401, E501
from impact.graphql.types.user_type import UserType  # noqa: F401
from impact.graphql.types.functional_expertise_type import FunctionalExpertiseType  # noqa: F401, E501
from impact.graphql.types.interest_category_type import InterestCategoryType  # noqa: F401, E501

class ExpertProfileType(DjangoObjectType):
    mentees = graphene.List(StartupType)
    image_url = graphene.String()
    program_interests = graphene.List(graphene.String)
    available_office_hours = graphene.Boolean()

    class Meta:
        model = ExpertProfile
        only_fields = (
            'title',
            'company',
            'phone',
            'twitter_handle',
            'linked_in_url',
            'personal_website_url',
            'bio',
            'expert_category',
            'primary_industry',
            'additional_industries',
            'home_program_family',
            'user',
            'functional_expertise',
            'interest_categories',
        )

    def resolve_image_url(self, info, **kwargs):
        return self.image and self.image.url

    def resolve_program_interests(self, info, **kwargs):
        return self.interest_categories.all().values_list(
            'program__program_family__name', flat=True).distinct()

    def resolve_available_office_hours(self, info, **kwargs):
        user = info.context.user
        filter_kwargs = {
            'finalist__isnull': True,
            'date__gte': timezone.now(),
            'start_time__gte': timezone.now().time()
        }
        if not user.is_staff:
            filter_kwargs['program__in'] = _get_user_programs(user)
        return self.user.mentor_officehours.filter(
            **filter_kwargs).exists()

def _get_user_programs(user):
    # todo: refactor this and move it to a sensible place
    # todo: test this
    participant_roles = UserRole.FINALIST_USER_ROLES
    user_program_roles_as_participant = ProgramRole.objects.filter(
        programrolegrant__person=user,
        user_role__name__in=participant_roles
    )
    return Program.objects.filter(
        programrole__in=user_program_roles_as_participant).distinct()
<commit_msg>[AC-5775] adding office_hours url as a grahpql attribute<commit_after>import graphene
from graphene_django import DjangoObjectType
from django.utils import timezone
from accelerator.models import (
    ExpertProfile,
    UserRole,
    ProgramRole,
    Program,
)
from impact.graphql.types.industry_type import IndustryType  # noqa: F401
from impact.graphql.types.startup_type import StartupType
from impact.graphql.types.program_family_type import ProgramFamilyType  # noqa: F401, E501
from impact.graphql.types.user_type import UserType  # noqa: F401
from impact.graphql.types.functional_expertise_type import FunctionalExpertiseType  # noqa: F401, E501
from impact.graphql.types.interest_category_type import InterestCategoryType  # noqa: F401, E501
from django.core.urlresolvers import reverse

class ExpertProfileType(DjangoObjectType):
    mentees = graphene.List(StartupType)
    image_url = graphene.String()
    office_hours_url = graphene.String()
    program_interests = graphene.List(graphene.String)
    available_office_hours = graphene.Boolean()

    class Meta:
        model = ExpertProfile
        only_fields = (
            'title',
            'company',
            'phone',
            'twitter_handle',
            'linked_in_url',
            'personal_website_url',
            'bio',
            'expert_category',
            'primary_industry',
            'additional_industries',
            'home_program_family',
            'user',
            'functional_expertise',
            'interest_categories',
        )

    def resolve_image_url(self, info, **kwargs):
        return self.image and self.image.url

    def resolve_program_interests(self, info, **kwargs):
        return self.interest_categories.all().values_list(
            'program__program_family__name', flat=True).distinct()

    def resolve_available_office_hours(self, info, **kwargs):
        user = info.context.user
        filter_kwargs = {
            'date__gte': timezone.now(),
            'start_time__gte': timezone.now().time()
        }
        if not user.is_staff:
            filter_kwargs['program__in'] = _get_user_programs(user)
        return self.user.mentor_officehours.filter(
            **filter_kwargs).exists()

    def resolve_office_hours_url(self, info, **kwargs):
        user = info.context.user
        if user.programrolegrant_set.filter(
                program_role__user_role__name=UserRole.MENTOR
        ).exists():
            latest_grant = user.programrolegrant_set.filter(
                program_role__user_role__name=UserRole.MENTOR
            ).latest('created_at')
            latest_mentor_program = latest_grant.program_role.program
            return "/officehours/list/{family_slug}/{program_slug}/".format(
                family_slug=latest_mentor_program.program_family.url_slug,
                program_slug=latest_mentor_program.url_slug) + (
                '?mentor_id={mentor_id}'.format(
                    mentor_id=user.id))

def _get_user_programs(user):
    # todo: refactor this and move it to a sensible place
    # todo: test this
    participant_roles = UserRole.FINALIST_USER_ROLES
    user_program_roles_as_participant = ProgramRole.objects.filter(
        programrolegrant__person=user,
        user_role__name__in=participant_roles
    )
    return Program.objects.filter(
        programrole__in=user_program_roles_as_participant).distinct()
<|endoftext|>


<commit_before>#!/bin/python
# this script uses pandocfilters: https://github.com/jgm/pandocfilters
# the walk function in particular is a modified version of the one there. see the pandocfilters license (3-clause BSD) at: https://github.com/jgm/pandocfilters/blob/master/LICENSE

import json, sys
from pandocfilters import Str, Space
import pandocfilters
import collections

# Below, (a, [b]) means that the tag a implies tag b; so if you have a
# page with tag a, it will automatically also be applied the tag b.
# Note that the order here is important.  Let's say we also have
#    (b, [c])
# then doing tag a should also imply tag c, since the implication chain
# goes a -> b -> c.  In other words, tag implication should be
# transitive, in that a -> b and b -> c together mean a -> c.  This
# means though that you should put the line (a, [b]) before the line (b,
# [c]), since then the first will be applied, leaving you with the tags
# a and b, and then the second will be applied, leaving you with tags a,
# b, and c.
tag_implications = collections.OrderedDict([
    ("hakyll", ["haskell"]),
    ("python", ["programming"]),
    ("latex", ["linux"]),
    ("qs", ["quantified-self"]),
    ("lesswrong", ["rationality"]),
    ("logic", ["math"]),
    ("physics", ["science"]),
    ("atmospheric-sciences", ["science"]),
    ("astronomy", ["science"]),
    ("chemistry", ["science"]),
    ("analysis", ["math"]),
    ("haskell", ["programming"]),
    ("depression", ["psychology"]),
])

tag_synonyms = {
    "effective-altruism": ["ea", "effective altruism", "effectivealtruism"],
    "university-of-washington": ["uw", "uwashington", "university of washington"],
    "set-theory": ["set theory"],
    "lesswrong": ["lw", "less-wrong", "less wrong"],
    "cognito-mentoring": ["cm", "cognito mentoring", "cognito"],
    "math": ["maths", "mathematics"],
    "link-collection": ["link collection", "resources", "links"],
    "atmopsheric-sciences": ["atmos"],
    "chemistry": ["chem"],
    "computer-science": ["cs", "computer science"],
}

def imply_tags(tags, tag_implications):
    '''
    Take a list of tags along with a dictionary of tag implications.
    Return a new list of tags that includes all the implciations.
    '''
    result = list(tags)
    for key in tag_implications:
        if key in result:
            result.extend(tag_implications.get(key))
    return list(set(result))

t = ['hakyll']
print imply_tags(t, tag_implications)

def standardize_tags(tags, tag_synonyms):
    '''
    Take a list of tags ("tags") along with a dictionary of tag synonyms
    and return a new list of tags, where all synonymous tags are
    standardized according to tag_synonyms.  For instance, if
    tag_synonyms contains the line
        "university-of-washington": ["uw", "uwashington"],
    and if tags contains "uw" or "uwashington", then this will be
    replaced by "university-of-washington".
    '''
    result = []
    for tag in tags:
        canonical = [key for key, value in tag_synonyms.items() if tag in value]
        result.extend(canonical)
    return result

def stringify(x):
    """Walks the tree x and returns concatenated string content,
    leaving out all formatting.
    """
    result = []

    def go(key, val, format, meta):
        if key == 'Str':
            result.append(val)
        elif key == 'Code':
            result.append(val[1])
        elif key == 'Math':
            result.append(val[1])
        elif key == 'LineBreak':
            result.append(" ")
        elif key == 'Space':
            result.append(" ")

    walk(x, go, "", {})
    #return ''.join(result)
    return result

def gogo(key, val, f, meta):
    if key == 'MetaInLines':
        result = meta.get("tags", {}).get('t', {})
        if 'MetaInLines' in result:
            return Str(val + "yo")
    #elif key == 'Code':
        #return Str(val)
    #elif key == 'Math':
        #return Str(val)
    #elif key == 'LineBreak':
        #return Str(val)
    #elif key == 'Space':
        #return Str(val)

def caps(key, val, f, meta):
    if key == 'Str':
        return Str(val.upper())

def do_nothing(key, val, f, meta):
    pass

def walk(x, action, format, meta):
    """Walk a tree, applying an action to every object.
    Returns a modified tree.
    """
    if isinstance(x, list):
        #print "list!"
        array = []
        if isinstance(x[0], dict) and 't' in x[0]:
            res = action(x[0]['t'], x[0]['c'], format, meta)
            if res is None:
                array.append(pandocfilters.walk(x[0], do_nothing, format, meta))
            elif isinstance(res, list):
                for z in res:
                    array.append(pandocfilters.walk(z, do_nothing, format, meta))
            else:
                array.append(pandocfilters.walk(res, do_nothing, format, meta))
        else:
            array.append(pandocfilters.walk(x[0], do_nothing, format, meta))

        for item in x[1:]:
            if isinstance(item, dict) and 't' in item:
                res = action(item['t'], item['c'], format, meta)
                if res is None:
                    array.append(pandocfilters.walk(item, action, format, meta))
                elif isinstance(res, list):
                    for z in res:
                        array.append(pandocfilters.walk(z, action, format, meta))
                else:
                    array.append(pandocfilters.walk(res, action, format, meta))
            else:
                array.append(pandocfilters.walk(item, action, format, meta))
        return array
    elif isinstance(x, dict):
        #print "dict!"
        obj = {}
        for k in x:
            obj[k] = pandocfilters.walk(x[k], action, format, meta)
        return obj
    else:
        return x

def listify(x):
    '''
    Take a YAML-JSON list or string of comma-delimited tags,
    and return a cleaned list.
    '''
    if x['t'] == 'MetaInlines':
        w = [i.strip(',') for i in stringify(x) if i is not ' ']
        return w
    elif x['t'] == 'MetaList':
        return stringify(x)

def intersperse(iterable, delimiter):
    '''See http://stackoverflow.com/a/5656097/3422337 '''
    it = iter(iterable)
    yield next(it)
    for x in it:
        yield delimiter
        yield x

def pack_tags(tags):
    '''
    Take a list of tags ("tags") and return a YAML-JSON list of the tags
    '''
    result = []
    for tag in tags:
        tag_dict = {'t': 'MetaInlines', 'c': [Str(tag)]}
        result.append(tag_dict)
    return result
    #return list(intersperse([Str(i) for i in tags], Space()))

with open('hello.json','r') as f:
    x = f.next()
    data = json.loads(x)
    #print json.dumps(data, indent=2)
    tags = data[0]['unMeta']['tags']
    tags2 = data[0]['unMeta']['tags2']
    tags3 = data[0]['unMeta']['tags3']
    tags4 = data[0]['unMeta']['tags4']
    #print data[0]['unMeta'].get('tags', {})
    #print json.dumps(tags, indent=2)
    w = listify(tags)
    w.append("newtag")
    tags['c'] = pack_tags(w)
    tags['t'] = 'MetaList'
    #print tags['c']
    #print json.dumps(tags, separators=(',',':'))
    #print json.dumps(, separators=(',',':'))
    #print stringify(tags)
    #print stringify(tags2)
    #print stringify(tags3)
    #print stringify(tags4)
    #if len(sys.argv) > 1:
        #format = sys.argv[1]
    #else:
        #format = ""
    array = []
    altered = walk(data, caps, "", data[0]['unMeta'])
    #print altered
    #print json.dumps(altered, indent=2)
    #json.dump(altered, sys.stdout)

<commit_msg>tuple was split over a linebreak<commit_after>#!/bin/python
# this script uses pandocfilters: https://github.com/jgm/pandocfilters
# the walk function in particular is a modified version of the one there. see the pandocfilters license (3-clause BSD) at: https://github.com/jgm/pandocfilters/blob/master/LICENSE

import json, sys
from pandocfilters import Str, Space
import pandocfilters
import collections

# Below, (a, [b]) means that the tag a implies tag b; so if you have a
# page with tag a, it will automatically also be applied the tag b.
# Note that the order here is important.  Let's say we also have
#    (b, [c])
# then doing tag a should also imply tag c, since the implication chain
# goes a -> b -> c.  In other words, tag implication should be
# transitive, in that a -> b and b -> c together mean a -> c.  This
# means though that you should put the line (a, [b]) before the line
# (b, [c]), since then the first will be applied, leaving you with the
# tags a and b, and then the second will be applied, leaving you with
# tags a, b, and c.
tag_implications = collections.OrderedDict([
    ("hakyll", ["haskell"]),
    ("python", ["programming"]),
    ("latex", ["linux"]),
    ("qs", ["quantified-self"]),
    ("lesswrong", ["rationality"]),
    ("logic", ["math"]),
    ("physics", ["science"]),
    ("atmospheric-sciences", ["science"]),
    ("astronomy", ["science"]),
    ("chemistry", ["science"]),
    ("analysis", ["math"]),
    ("haskell", ["programming"]),
    ("depression", ["psychology"]),
])

tag_synonyms = {
    "effective-altruism": ["ea", "effective altruism", "effectivealtruism"],
    "university-of-washington": ["uw", "uwashington", "university of washington"],
    "set-theory": ["set theory"],
    "lesswrong": ["lw", "less-wrong", "less wrong"],
    "cognito-mentoring": ["cm", "cognito mentoring", "cognito"],
    "math": ["maths", "mathematics"],
    "link-collection": ["link collection", "resources", "links"],
    "atmopsheric-sciences": ["atmos"],
    "chemistry": ["chem"],
    "computer-science": ["cs", "computer science"],
}

def imply_tags(tags, tag_implications):
    '''
    Take a list of tags along with a dictionary of tag implications.
    Return a new list of tags that includes all the implciations.
    '''
    result = list(tags)
    for key in tag_implications:
        if key in result:
            result.extend(tag_implications.get(key))
    return list(set(result))

t = ['hakyll']
print imply_tags(t, tag_implications)

def standardize_tags(tags, tag_synonyms):
    '''
    Take a list of tags ("tags") along with a dictionary of tag synonyms
    and return a new list of tags, where all synonymous tags are
    standardized according to tag_synonyms.  For instance, if
    tag_synonyms contains the line
        "university-of-washington": ["uw", "uwashington"],
    and if tags contains "uw" or "uwashington", then this will be
    replaced by "university-of-washington".
    '''
    result = []
    for tag in tags:
        canonical = [key for key, value in tag_synonyms.items() if tag in value]
        result.extend(canonical)
    return result

def stringify(x):
    """Walks the tree x and returns concatenated string content,
    leaving out all formatting.
    """
    result = []

    def go(key, val, format, meta):
        if key == 'Str':
            result.append(val)
        elif key == 'Code':
            result.append(val[1])
        elif key == 'Math':
            result.append(val[1])
        elif key == 'LineBreak':
            result.append(" ")
        elif key == 'Space':
            result.append(" ")

    walk(x, go, "", {})
    #return ''.join(result)
    return result

def gogo(key, val, f, meta):
    if key == 'MetaInLines':
        result = meta.get("tags", {}).get('t', {})
        if 'MetaInLines' in result:
            return Str(val + "yo")
    #elif key == 'Code':
        #return Str(val)
    #elif key == 'Math':
        #return Str(val)
    #elif key == 'LineBreak':
        #return Str(val)
    #elif key == 'Space':
        #return Str(val)

def caps(key, val, f, meta):
    if key == 'Str':
        return Str(val.upper())

def do_nothing(key, val, f, meta):
    pass

def walk(x, action, format, meta):
    """Walk a tree, applying an action to every object.
    Returns a modified tree.
    """
    if isinstance(x, list):
        #print "list!"
        array = []
        if isinstance(x[0], dict) and 't' in x[0]:
            res = action(x[0]['t'], x[0]['c'], format, meta)
            if res is None:
                array.append(pandocfilters.walk(x[0], do_nothing, format, meta))
            elif isinstance(res, list):
                for z in res:
                    array.append(pandocfilters.walk(z, do_nothing, format, meta))
            else:
                array.append(pandocfilters.walk(res, do_nothing, format, meta))
        else:
            array.append(pandocfilters.walk(x[0], do_nothing, format, meta))

        for item in x[1:]:
            if isinstance(item, dict) and 't' in item:
                res = action(item['t'], item['c'], format, meta)
                if res is None:
                    array.append(pandocfilters.walk(item, action, format, meta))
                elif isinstance(res, list):
                    for z in res:
                        array.append(pandocfilters.walk(z, action, format, meta))
                else:
                    array.append(pandocfilters.walk(res, action, format, meta))
            else:
                array.append(pandocfilters.walk(item, action, format, meta))
        return array
    elif isinstance(x, dict):
        #print "dict!"
        obj = {}
        for k in x:
            obj[k] = pandocfilters.walk(x[k], action, format, meta)
        return obj
    else:
        return x

def listify(x):
    '''
    Take a YAML-JSON list or string of comma-delimited tags,
    and return a cleaned list.
    '''
    if x['t'] == 'MetaInlines':
        w = [i.strip(',') for i in stringify(x) if i is not ' ']
        return w
    elif x['t'] == 'MetaList':
        return stringify(x)

def intersperse(iterable, delimiter):
    '''See http://stackoverflow.com/a/5656097/3422337 '''
    it = iter(iterable)
    yield next(it)
    for x in it:
        yield delimiter
        yield x

def pack_tags(tags):
    '''
    Take a list of tags ("tags") and return a YAML-JSON list of the tags
    '''
    result = []
    for tag in tags:
        tag_dict = {'t': 'MetaInlines', 'c': [Str(tag)]}
        result.append(tag_dict)
    return result
    #return list(intersperse([Str(i) for i in tags], Space()))

with open('hello.json','r') as f:
    x = f.next()
    data = json.loads(x)
    #print json.dumps(data, indent=2)
    tags = data[0]['unMeta']['tags']
    tags2 = data[0]['unMeta']['tags2']
    tags3 = data[0]['unMeta']['tags3']
    tags4 = data[0]['unMeta']['tags4']
    #print data[0]['unMeta'].get('tags', {})
    #print json.dumps(tags, indent=2)
    w = listify(tags)
    w.append("newtag")
    tags['c'] = pack_tags(w)
    tags['t'] = 'MetaList'
    #print tags['c']
    #print json.dumps(tags, separators=(',',':'))
    #print json.dumps(, separators=(',',':'))
    #print stringify(tags)
    #print stringify(tags2)
    #print stringify(tags3)
    #print stringify(tags4)
    #if len(sys.argv) > 1:
        #format = sys.argv[1]
    #else:
        #format = ""
    array = []
    altered = walk(data, caps, "", data[0]['unMeta'])
    #print altered
    #print json.dumps(altered, indent=2)
    #json.dump(altered, sys.stdout)

<|endoftext|>


<commit_before>"""
Import sample data for similar product engine
"""

import predictionio
import argparse
import random

SEED = 3

def import_events(client):
  random.seed(SEED)
  count = 0
  print client.get_status()
  print "Importing data..."

  # generate 10 users, with user ids u1,u2,....,u10
  user_ids = ["u%s" % i for i in range(1, 11)]
  for user_id in user_ids:
    print "Set user", user_id
    client.create_event(
      event="$set",
      entity_type="user",
      entity_id=user_id
    )
    count += 1

  # generate 50 items, with item ids i1,i2,....,i50
  # random assign 1 to 4 categories among c1-c6 to items
  categories = ["c%s" % i for i in range(1, 7)]
  item_ids = ["i%s" % i for i in range(1, 51)]
  for item_id in item_ids:
    print "Set item", item_id
    client.create_event(
      event="$set",
      entity_type="item",
      entity_id=item_id,
      properties={
        "categories" : random.sample(categories, random.randint(1, 4))
      }
    )
    count += 1

  # each user randomly viewed 10 items
  for user_id in user_ids:
    for viewed_item in random.sample(item_ids, 10):
      print "User", user_id ,"views item", viewed_item
      client.create_event(
        event="view",
        entity_type="user",
        entity_id=user_id,
        target_entity_type="item",
        target_entity_id=viewed_item
      )
      count += 1

  print "%s events are imported." % count

if __name__ == '__main__':
  parser = argparse.ArgumentParser(
    description="Import sample data for similar product engine")
  parser.add_argument('--access_key', default='invald_access_key')
  parser.add_argument('--url', default="http://localhost:7070")

  args = parser.parse_args()
  print args

  client = predictionio.EventClient(
    access_key=args.access_key,
    url=args.url,
    threads=5,
    qsize=500)
  import_events(client)
<commit_msg>PDIO-480 Generate random like/dislike events in sample data import<commit_after>"""
Import sample data for similar product engine
"""

import predictionio
import argparse
import random

SEED = 3

def import_events(client):
  random.seed(SEED)
  count = 0
  print client.get_status()
  print "Importing data..."

  # generate 10 users, with user ids u1,u2,....,u10
  user_ids = ["u%s" % i for i in range(1, 11)]
  for user_id in user_ids:
    print "Set user", user_id
    client.create_event(
      event="$set",
      entity_type="user",
      entity_id=user_id
    )
    count += 1

  # generate 50 items, with item ids i1,i2,....,i50
  # random assign 1 to 4 categories among c1-c6 to items
  categories = ["c%s" % i for i in range(1, 7)]
  item_ids = ["i%s" % i for i in range(1, 51)]
  for item_id in item_ids:
    print "Set item", item_id
    client.create_event(
      event="$set",
      entity_type="item",
      entity_id=item_id,
      properties={
        "categories" : random.sample(categories, random.randint(1, 4))
      }
    )
    count += 1

  # each user randomly viewed 10 items
  for user_id in user_ids:
    for viewed_item in random.sample(item_ids, 10):
      print "User", user_id ,"views item", viewed_item
      client.create_event(
        event="view",
        entity_type="user",
        entity_id=user_id,
        target_entity_type="item",
        target_entity_id=viewed_item
      )
      count += 1

  # each user randomly liked/disliked 10 items
  for user_id in user_ids:
    for viewed_item in random.sample(item_ids, 10):
      if random.choice((False, True)) :
        print "User", user_id ,"likes item", viewed_item
        client.create_event(
          event="like",
          entity_type="user",
          entity_id=user_id,
          target_entity_type="item",
          target_entity_id=viewed_item
        )
      else:
        print "User", user_id ,"dislikes item", viewed_item
        client.create_event(
          event="dislike",
          entity_type="user",
          entity_id=user_id,
          target_entity_type="item",
          target_entity_id=viewed_item
        )
      count += 1

  print "%s events are imported." % count

if __name__ == '__main__':
  parser = argparse.ArgumentParser(
    description="Import sample data for similar product engine")
  parser.add_argument('--access_key', default='invald_access_key')
  parser.add_argument('--url', default="http://localhost:7070")

  args = parser.parse_args()
  print args

  client = predictionio.EventClient(
    access_key=args.access_key,
    url=args.url,
    threads=5,
    qsize=500)
  import_events(client)
<|endoftext|>