def test_assignment_reminder_task_on_date(self):
        user = BlueBottleUserFactory.create(first_name='Nono')
        end = now() + timedelta(days=4)
        assignment = AssignmentFactory.create(
            owner=user,
            status='open',
            end_date_type='on_date',
            initiative=self.initiative,
            date=end
        )

        ApplicantFactory.create_batch(2, activity=assignment, status='new')
        ApplicantFactory.create(activity=assignment, status='accepted')
        withdrawn = ApplicantFactory.create(activity=assignment, status='new')
        withdrawn.states.withdraw(save=True)

        mail.outbox = []
        tenant = connection.tenant
        assignment_tasks()

        with LocalTenant(tenant, clear_tenant=True):
            assignment.refresh_from_db()

        recipients = [message.to[0] for message in mail.outbox]

        for applicant in assignment.contributions.instance_of(Applicant).all():
            if applicant.status in ['new', 'accepted']:
                self.assertTrue(applicant.user.email in recipients)
            else:
                self.assertFalse(applicant.user.email in recipients)
        self.assertEqual(
            mail.outbox[0].subject,
            '"{}" will take place in 5 days!'.format(assignment.title)
        )
    def test_assignment_check_end_date_future(self):
        user = BlueBottleUserFactory.create(first_name='Nono')

        deadline = now() - timedelta(days=4)
        date = now() + timedelta(days=2)

        assignment = AssignmentFactory.create(
            owner=user,
            status='open',
            capacity=3,
            registration_deadline=deadline.date(),
            initiative=self.initiative,
            date=date,
        )

        applicants = ApplicantFactory.create_batch(3, activity=assignment)
        for applicant in applicants:
            applicant.states.accept(save=True)

        ApplicantFactory.create_batch(3, activity=assignment)

        tenant = connection.tenant

        future = timezone.now() + timedelta(days=3)
        with mock.patch.object(timezone, 'now', return_value=future):
            assignment_tasks()

        with LocalTenant(tenant, clear_tenant=True):
            assignment.refresh_from_db()

        self.assertEqual(assignment.status, 'succeeded')
        for applicant in assignment.applicants:
            self.assertEqual(applicant.status, 'succeeded')
示例#3
0
    def test_event_end_task(self):
        user = BlueBottleUserFactory.create(first_name='Nono')
        start = timezone.now() + timedelta(hours=5)
        event = EventFactory.create(
            owner=user,
            initiative=self.initiative,
            title='Finish them translations, Rolfertjan!',
            start=start,
            duration=1
        )
        event.states.submit(save=True)
        ParticipantFactory.create_batch(3, activity=event)

        tenant = connection.tenant

        mail.outbox = []

        future = timezone.now() + timedelta(hours=6)
        with mock.patch.object(timezone, 'now', return_value=future):
            event_tasks()
        with LocalTenant(tenant, clear_tenant=True):
            event = Event.objects.get(pk=event.pk)
        self.assertEqual(event.status, EventStateMachine.succeeded.value)

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, u'Your event "{}" took place! \U0001f389'.format(event.title))
        self.assertTrue("Hi Nono,", mail.outbox[0].body)
    def test_assignment_check_registration_deadline(self):
        user = BlueBottleUserFactory.create(first_name='Nono')

        deadline = now() - timedelta(days=1)
        end = now() + timedelta(days=4)

        assignment = AssignmentFactory.create(
            owner=user,
            status='open',
            capacity=3,
            end_date_type='on_date',
            registration_deadline=deadline.date(),
            initiative=self.initiative,
            duration=4,
            date=end,
        )
        applicants = ApplicantFactory.create_batch(3, activity=assignment, status='new')
        for applicant in applicants:
            applicant.states.accept(save=True)

        tenant = connection.tenant
        assignment_tasks()

        with LocalTenant(tenant, clear_tenant=True):
            assignment.refresh_from_db()

        self.assertEqual(assignment.status, 'full')
示例#5
0
def update_time_spent(apps, schema_editor):
    TaskMember = apps.get_model('tasks', "TaskMember")
    with LocalTenant(connection.tenant):
            for tm in TaskMember.objects.filter(status='realized'):
                if tm.task and tm.task.time_needed:
                    tm.time_spent = tm.task.time_needed
                    tm.save()
示例#6
0
    def generate_participation_xls(self):
        file_name = self.get_file_name()
        self.file_path = self.get_xls_file_name(file_name)
        client = Client.objects.get(client_name=self.tenant)

        with xlsxwriter.Workbook(self.file_path, {
                'default_date_format': 'dd/mm/yy',
                'remove_timezone': True
        }) as workbook:
            with LocalTenant(client, clear_tenant=True):
                logger.info(
                    'export participation metrics - tenant:{} start_date:{} end_date:{}'
                    .format(self.tenant, self.start_date.to_iso8601_string(),
                            self.end_date.to_iso8601_string()))
                logger.info('file path: {}'.format(self.file_path))
                self.generate_participants_worksheet(workbook)
                self.generate_worksheet(workbook, 'aggregated')
                self.generate_worksheet(workbook, 'location_segmentation')
                self.generate_worksheet(workbook, 'theme_segmentation')

        if self.to_email:
            with open(self.file_path, 'r') as f:
                User = namedtuple('User', 'email')
                user = User(email=self.to_email)
                send_mail(template_name='participation_metrics_email',
                          subject='Participation Metrics',
                          to=user,
                          attachments=[(file_name, f.read())],
                          connection=connection)
def create_refunded_phase(apps, schema_editor):
    ProjectPhase = apps.get_model('bb_projects', 'ProjectPhase')
    try:
        ProjectPhase.objects.get_or_create(
            id=13,
            slug='refunded',
            viewable=True,
            editable=False,
            sequence=11,
            description='The project was refunded')
    except FieldError:
        # If project phases are already translated then translate description
        object, created = ProjectPhase.objects.get_or_create(id=13,
                                                             slug='refunded',
                                                             viewable=True,
                                                             editable=False,
                                                             sequence=11)
        Client = apps.get_model('clients', 'Client')
        PhaseTranslation = apps.get_model('bb_projects',
                                          'ProjectPhaseTranslation')

        tenant = Client.objects.get(schema_name=connection.tenant.schema_name)

        with LocalTenant(tenant):
            languages = get_languages()
            for (language, _long_language) in languages:
                activate(language)
                _trans._active.value = tenant_translation(
                    language, tenant.client_name)
                PhaseTranslation.objects.create(
                    master_id=object.pk,
                    language_code=language,
                    name=_('Refunded'),
                    description=_('The project was refunded'),
                )
示例#8
0
    def handle(self, *args, **options):
        if options['all']:
            tenants = Client.objects.all()

        if options['tenant']:
            tenants = [Client.objects.get(schema_name=options['tenant'])]

        for client in tenants:
            print "\n\nCreating homepage for {}".format(client.name)
            with LocalTenant(client, clear_tenant=True):
                ContentType.objects.clear_cache()

                (page, _created) = HomePage.objects.get_or_create(pk=1)
                languages = [lang[0] for lang in properties.LANGUAGES]

                for language_code in languages:
                    page.translations.get_or_create(
                        language_code=language_code, )

                page_type = ContentType.objects.get_for_model(page)

                (placeholder, _created) = Placeholder.objects.get_or_create(
                    parent_id=page.pk,
                    parent_type_id=page_type.pk,
                    slot='content',
                    role='m')
                for item in ContentItem.objects.filter(parent_id=page.pk,
                                                       parent_type=page_type):
                    item.delete()

                for lang, blocks in properties.HOMEPAGE.items():
                    for (block_type, block) in blocks:
                        self.create_block(block_type, block, placeholder, lang)
示例#9
0
文件: utils.py 项目: raux/bluebottle
    def _merge_attrs(data, attrs):
        try:
            items = attrs.iteritems()
        except AttributeError:
            logger.exception('analytics_merge_attrs')
            return

        for label, attr in items:
            options = {}
            # If a dict is passed then the key is the dotted
            # property string and the value is options.
            try:
                new_attr = attr.keys()[0]
                options = attr[new_attr]
                attr = new_attr
            except AttributeError:
                # TODO: Logging
                pass

            value = _multi_getattr(instance, attr, default='')

            if options.get('translate', False):
                with LocalTenant():
                    # Translate using the default tenant language
                    with TenantLanguage(
                            getattr(properties, 'LANGUAGE_CODE', 'en')):
                        # If attr is a string then try to translate
                        # Note: tag values should always be strings.
                        value = _(value)

            data[label] = value
示例#10
0
    def handle(self, *args, **options):
        if options['all'] and options['tenant']:
            raise CommandError('--all and --tenant cannot be used together')

        if options['all']:
            tenants = Client.objects.all()
        else:
            tenants = Client.objects.filter(client_name=options['tenant'])

        tokens = []
        for tenant in tenants:
            with LocalTenant(tenant):
                tokens += [{
                    'api_key': token.key,
                    'name': tenant.client_name,
                    'domain': 'https://{}'.format(tenant.domain_url),
                    'fees': {
                        'under_target':
                        properties.PROJECT_PAYOUT_FEES.get(
                            'not_fully_funded', 0),
                        'over_target':
                        properties.PROJECT_PAYOUT_FEES.get('fully_funded', 0)
                    }
                } for token in Token.objects.filter(
                    user__email=options['email'])]

        self.stdout.write(json.dumps(tokens, indent=4))
def add_group_permissions(apps, schema_editor):
    tenant = Client.objects.get(schema_name=connection.tenant.schema_name)
    with LocalTenant(tenant):
        group_perms = {
            'Staff': {
                'perms': (
                    'add_participant',
                    'change_participant',
                    'delete_participant',
                )
            },
            'Anonymous': {
                'perms':
                ('api_read_event', ) if not properties.CLOSED_SITE else ()
            },
            'Authenticated': {
                'perms': (
                    'api_read_participant',
                    'api_add_participant',
                    'api_change_own_participant',
                )
            }
        }

        update_group_permissions('events', group_perms, apps)
示例#12
0
def _post_to_facebook(instance, tenant=None):
    """ Post a Wallpost to users Facebook page using Celery """
    logger.info("FB post for:")
    logger.info("{0} with id {1} and tenant {2}".format(instance.__class__,
                                                        instance.id,
                                                        tenant.client_name))

    if not tenant:
        return

    with LocalTenant(tenant, clear_tenant=True):
        social = instance.author.social_auth.get(provider='facebook')
        authorization_header = 'Bearer {token}'.format(
            token=social.extra_data['access_token']
        )

        graph_url = 'https://graph.facebook.com/v2.4/me/feed'
        base_url = 'https://{domain}'.format(
            domain=tenant.domain_url)

        link = instance.content_object.get_absolute_url()

        image = None
        # This code is executed via Celery, we assume the MediaWallpostPhoto
        # is saved and available on the instance. If the user uploaded
        # photos with the MediaWallpost we take the first one and include it
        # in the Facebook post. Otherwise we fallback to the project image.
        if isinstance(instance, MediaWallpost) and instance.photos.count() > 0:
            image = urljoin(base_url,
                            get_thumbnail(instance.photos.all()[0].photo,
                                          "600x400").url
                            )
        else:
            if hasattr(instance.content_object, 'image') and instance.content_object.image:
                image = urljoin(
                    base_url,
                    get_thumbnail(instance.content_object.image, "600x400").url
                )

        description = getattr(
            instance.content_object, 'pitch', instance.content_object.description
        )

        data = {
            'link': link,
            'name': instance.content_object.title,
            'description': description,
            'message': instance.text,
            'picture': image,
            'caption': tenant_url()
        }

        # TODO: log failed requests
        requests.post(
            graph_url,
            data=json.dumps(data),
            headers={
                'Authorization': authorization_header,
                'Content-Type': 'application/json'}
        )
示例#13
0
    def handle(self, *args, **options):
        results = []
        for client in Client.objects.all():
            connection.set_tenant(client)
            with LocalTenant(client, clear_tenant=True):
                ContentType.objects.clear_cache()

                projects = Project.objects.filter(amount_donated__gt=0)

                if options['start']:
                    projects = projects.filter(created__gte=options['start'])
                if options['end']:
                    projects = projects.filter(deadline__lte=options['end'])

                for project in projects:
                    started = project.campaign_started if project.campaign_started else project.created
                    ended = project.campaign_ended if project.campaign_ended else project.deadline
                    results.append({
                        'tenant': client.client_name,
                        'id': project.id,
                        'title': project.title,
                        'slug': project.slug,
                        'started': started.strftime('%Y-%m-%d'),
                        'ended': ended.strftime('%Y-%m-%d')
                    })

        if options['file']:
            text_file = open(options['file'], "w")
            text_file.write(json.dumps(results))
            text_file.close()
        else:
            print json.dumps(results)
    def test_enough_donations(self):
        donation = DonationFactory.create(activity=self.funding,
                                          amount=Money(300, 'EUR'))
        PledgePaymentFactory.create(donation=donation)
        donation = DonationFactory.create(activity=self.funding,
                                          amount=Money(450, 'EUR'))
        PledgePaymentFactory.create(donation=donation)
        self.assertEqual(len(mail.outbox), 4)
        self.assertEqual(donation.status, 'succeeded')
        self.funding.deadline = now() - timedelta(days=1)
        self.funding.save()

        # Run scheduled task
        tenant = connection.tenant
        funding_tasks()
        with LocalTenant(tenant, clear_tenant=True):
            self.funding.refresh_from_db()

        self.assertEqual(len(mail.outbox), 5)
        self.assertEqual(
            mail.outbox[4].subject,
            u'Your campaign "{}" has been successfully completed! \U0001f389'.
            format(self.funding.title))
        self.assertTrue('Hi Jean Baptiste,' in mail.outbox[4].body)
        self.assertTrue(self.funding.title in mail.outbox[4].body)
        url = 'http://testserver/en/initiatives/activities/details/funding/{}/{}'.format(
            self.funding.id, self.funding.slug)
        self.assertTrue(url in mail.outbox[4].body)

        organizer = self.funding.contributions.instance_of(Organizer).get()
        self.assertEqual(organizer.status, organizer.states.succeeded.value)
示例#15
0
    def test_assignment_check_start_date(self):
        user = BlueBottleUserFactory.create(first_name='Nono')

        registration_deadline = now() - timedelta(days=1)
        date = now() + timedelta(hours=6)

        assignment = AssignmentFactory.create(
            owner=user,
            status='open',
            capacity=3,
            registration_deadline=registration_deadline.date(),
            initiative=self.initiative,
            end_date_type='on_date',
            duration=10,
            date=date
        )
        applicants = ApplicantFactory.create_batch(3, activity=assignment, status='new')
        for applicant in applicants:
            applicant.states.accept(save=True)

        tenant = connection.tenant
        with mock.patch.object(timezone, 'now', return_value=(timezone.now() + timedelta(hours=7))):
            assignment_tasks()

        with LocalTenant(tenant, clear_tenant=True):
            assignment.refresh_from_db()

        self.assertEqual(assignment.status, 'running')
示例#16
0
    def handle(self, **options):
        logger = logging.getLogger('console')

        send_email = not options['no_email']

        try:
            client = Client.objects.get(client_name=options['tenant'])
        except Client.DoesNotExist:
            logger.error(
                "You must specify a valid tenant with -t or --tenant.")
            tenants = Client.objects.all().values_list('client_name',
                                                       flat=True)
            logger.info("Valid tenants are: {0}".format(", ".join(tenants)))
            sys.exit(1)

        with LocalTenant(client, clear_tenant=True):
            if options['prepare']:
                prepare_monthly_batch()

            if options['process']:
                process_monthly_batch(tenant=client,
                                      monthly_batch=None,
                                      send_email=send_email)
            if options['process_single']:
                process_single_monthly_order(options['process_single'], None,
                                             send_email)
示例#17
0
    def handle(self, *args, **options):
        client = Client.objects.get(client_name=options['tenant'])
        self.upload = options['upload']

        with LocalTenant(client, clear_tenant=True):

            with open(options['file']) as json_file:
                data = json.load(json_file)

            if options['models']:
                self.models = options['models']

            counter = Counter()
            for key in self.models:
                if key in data:
                    logger.info("Importing {}".format(key))
                    counter.reset(total=len(data[key]))
                    for value in data[key]:
                        counter.inc()
                        method_to_call = getattr(self,
                                                 '_handle_{}'.format(key))
                        method_to_call(value)
                    logger.info(" Done!\n")

            if 'orders' in self.models:
                for project in Project.objects.exclude(
                        status__slug='plan-new').all():
                    if project.deadline < now():
                        project.status = ProjectPhase.objects.get(
                            slug='campaign')
                        project.campaign_ended = None
                        project.save()
示例#18
0
    def handle(self, *args, **options):
        results = []
        for client in Client.objects.all():
            with LocalTenant(client, clear_tenant=True):

                payouts = ProjectPayout.objects.filter(amount_payable__gt=0,
                                                       status='settled')
                if options['start']:
                    payouts = payouts.filter(created__gte=options['start'])
                if options['end']:
                    payouts = payouts.filter(created__lte=options['end'])

                for payout in payouts:
                    result = {
                        'id':
                        payout.id,
                        'tenant':
                        client.client_name,
                        'status':
                        payout.status,
                        'created':
                        payout.created.strftime('%Y-%m-%d'),
                        'invoice_reference':
                        payout.invoice_reference,
                        'amount_raised': {
                            'amount': float(payout.amount_raised.amount),
                            'currency': str(payout.amount_raised.currency)
                        },
                        'amount_payable': {
                            'amount': float(payout.amount_payable.amount),
                            'currency': str(payout.amount_payable.currency)
                        },
                        'organization_fee': {
                            'amount': float(payout.organization_fee.amount),
                            'currency': str(payout.organization_fee.currency)
                        },
                        'donations': [
                            serialize_donation(donation)
                            for donation in payout.project.donations
                        ]
                    }

                    if payout.amount_raised != payout.project.amount_donated:
                        result['donations'] += [
                            serialize_donation(donation)
                            for donation in Donation.objects.filter(
                                project=payout.project,
                                order__order_payments__status='charged_back',
                                order__updated__gt=payout.created)
                        ]

                    results.append(result)

        if options['file']:
            text_file = open(options['file'], "w")
            text_file.write(json.dumps(results))
            text_file.close()
        else:
            print json.dumps(results)
示例#19
0
    def test_validators_different_tenant(self):
        with override_properties(
                AUTH_PASSWORD_VALIDATORS=self.password_validators):
            validators = get_default_password_validators()
            self.assertEqual(validators[0].min_length, 10)

            with LocalTenant(Client.objects.get(client_name='test2')):
                validators = get_default_password_validators()
                self.assertEqual(validators[0].min_length, 8)
示例#20
0
文件: tasks.py 项目: raux/bluebottle
def refund_project(tenant, project):
    with LocalTenant(tenant, clear_tenant=True):
        for donation in project.donations:
            service = PaymentService(donation.order.order_payment)
            try:
                service.refund_payment()
            except Exception:
                # Don't trip if one refund throws an error
                pass
def add_group_permissions(apps, schema_editor):
    tenant = Client.objects.get(schema_name=connection.tenant.schema_name)
    with LocalTenant(tenant):
        group_perms = {
            'Anonymous': {
                'perms': ('api_read_category', ) if not properties.CLOSED_SITE else ()
            }
        }

        update_group_permissions('categories', group_perms, apps)
示例#22
0
文件: tasks.py 项目: raux/bluebottle
def check_payment_statuses(order_payments, tenant):
    connection.set_tenant(tenant)

    with LocalTenant(tenant, clear_tenant=True):

        for order_payment in order_payments:
            service = PaymentService(order_payment)
            try:
                service.check_payment_status()
            except (PaymentException, TypeError):
                pass
示例#23
0
 def test_event_scheduled_task_expire(self):
     tenant = connection.tenant
     with mock.patch.object(timezone,
                            'now',
                            return_value=(timezone.now() +
                                          timedelta(days=10, hours=12))):
         event_tasks()
     with LocalTenant(tenant, clear_tenant=True):
         self.event.refresh_from_db()
     event = Event.objects.get(pk=self.event.pk)
     self.assertEqual(event.status, 'cancelled')
示例#24
0
    def handle(self, *args, **options):
        results = []
        for client in Client.objects.all():
            connection.set_tenant(client)
            with LocalTenant(client, clear_tenant=True):
                ContentType.objects.clear_cache()

                orders = Order.objects.filter(
                    status__in=('pending', 'success')).exclude(
                        order_payments__payment_method='')

                if options['start']:
                    orders = orders.filter(created__gte=options['start'])
                if options['end']:
                    orders = orders.filter(created__lte=options['end'])

                for order in orders:
                    try:
                        transaction_reference = order.order_payment.payment.transaction_reference
                    except Exception:
                        transaction_reference = ''

                    results.append({
                        'id':
                        order.id,
                        'transaction_reference':
                        transaction_reference,
                        'tenant':
                        client.client_name,
                        'status':
                        order.status,
                        'created':
                        order.created.strftime('%Y-%m-%d'),
                        'amount': {
                            'amount': float(order.total.amount),
                            'currency': str(order.total.currency)
                        },
                        'donations': [{
                            'id': donation.id,
                            'amount': {
                                'amount': float(donation.amount.amount),
                                'currency': str(donation.amount.currency)
                            },
                            'donation_id': donation.pk,
                            'project_id': donation.project.pk
                        } for donation in order.donations.all()]
                    })

        if options['file']:
            text_file = open(options['file'], "w")
            text_file.write(json.dumps(results))
            text_file.close()
        else:
            print json.dumps(results)
示例#25
0
def timeout_locked_order(order, tenant):
    """ Timeout locked orders.

    If the order's status is still LOCKED, assume the the order
    will never be  payed.
    """
    logger.info("Timeing out order {}".format(order))

    with LocalTenant(tenant, clear_tenant=True):
        order = Order.objects.get(pk=order.pk)
        if order.status == StatusDefinition.LOCKED:
            order.transition_to(StatusDefinition.FAILED)
    def generate_engagement_xls(self):
        file_name = self.get_xls_file_name(self.start_date, self.end_date)

        with xlsxwriter.Workbook(file_name) as workbook:
            for client in Client.objects.all():
                if self.tenants is None or client.client_name in self.tenants:
                    with LocalTenant(client, clear_tenant=True):
                        logger.info('export tenant:{}'.format(client.client_name))
                        raw_data = self.generate_raw_data()
                        aggregated_data = self.generate_aggregated_data(raw_data)
                        self.generate_raw_data_worksheet(workbook, client.client_name, raw_data)
                        self.generate_aggregated_data_worksheet(workbook, client.client_name, aggregated_data)
def add_group_permissions(apps, schema_editor):
    tenant = Client.objects.get(schema_name=connection.tenant.schema_name)
    with LocalTenant(tenant):
        group_perms = {
            'Staff': {
                'perms': (
                    'add_homepagestatisticscontent', 'change_homepagestatisticscontent', 'delete_homepagestatisticscontent',
                )
            },
        }

        update_group_permissions('cms', group_perms, apps)
示例#28
0
文件: tasks.py 项目: raux/bluebottle
def update_popularity():
    """ Update the popularity score of all the projects

    Simply loops over all the tenants, and updates the scores
    """
    logger.info("Updating projects popularity using Celery")

    for tenant in Client.objects.all():
        with LocalTenant(tenant, clear_tenant=True):
            Project.update_popularity()

    logger.info("Finished updating projects popularity using Celery")
示例#29
0
def timeout_new_order(order, tenant):
    """ Timeout new orders.

    If the order's status is still CREATED, assume that the order will
    never be finished.
    """
    logger.info("Timeing out order {}".format(order))

    with LocalTenant(tenant, clear_tenant=True):
        order = Order.objects.get(pk=order.pk)
        if order.status == StatusDefinition.CREATED:
            order.transition_to(StatusDefinition.FAILED)
示例#30
0
文件: tasks.py 项目: raux/bluebottle
def update_exchange_rates():
    """ Update the popularity score of all the projects

    Simply loops over all the tenants, and updates the scores
    """
    logger.info("Retrieving up to date exchange rates")
    # call_command('update_rates')

    logger.info("Updating amounts of all running projects")
    for tenant in Client.objects.all():
        with LocalTenant(tenant, clear_tenant=True):
            for project in Project.objects.filter(status__slug='campaign'):
                project.update_amounts()