django.core.urlresolvers.reverse

Here are the examples of the python api django.core.urlresolvers.reverse taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

200 Examples 7

Example 1

Project: reviewboard
Source File: urlresolvers.py
View license
def local_site_reverse(viewname, request=None, local_site_name=None,
                       local_site=None, args=None, kwargs=None,
                       *func_args, **func_kwargs):
    """Reverse a URL name and return a working URL.

    This works much like Django's :py:func:`~django.core.urlresolvers.reverse`,
    but handles returning a LocalSite version of a URL when invoked with one of
    the following:

    * A ``request`` argument, representing an HTTP request to a URL within a
      LocalSite.
    * A ``local_site_name`` argument, indicating the name of the local site.
    * A ``local_site`` argument.

    Args:
        viewname (unicode):
            The name of the view to generate a URL for.

        request (django.http.HttpRequest, optional):
            The current HTTP request. The current local site can be extracted
            from this.

        local_site_name (unicode, optional):
            The name of the local site.

        local_site (reviewboard.site.models.LocalSite, optional):
            The local site.

        args (list, optional):
            Positional arguments to use for reversing in
            :py:func:`~django.core.urlresolvers.reverse`.

        kwargs (dict, optional):
            Keyword arguments to use for reversing in
             :py:func:`~django.core.urlresolvers.reverse`.

        func_args (tuple, optional):
            Additional positional arguments to pass to
            :py:func:`~django.core.urlresolvers.reverse`.

        func_kwargs (dict, optional):
            Additional keyword arguments to pass to
            :py:func:`~django.core.urlresolvers.reverse`.

    Returns:
        unicode:
        The reversed URL.

    Raises:
        django.core.urlresolvers.NoReverseMatch:
            Raised when there is no URL matching the view and arguments.
    """
    assert not (local_site_name and local_site)

    if request or local_site_name or local_site:
        if local_site:
            local_site_name = local_site.name
        elif request and not local_site_name:
            local_site_name = getattr(request, '_local_site_name', None)

        if local_site_name:
            if args:
                new_args = [local_site_name] + list(args)
                new_kwargs = kwargs
            else:
                new_args = args
                new_kwargs = {
                    'local_site_name': local_site_name,
                }

                if kwargs:
                    new_kwargs.update(kwargs)

            try:
                return reverse(viewname, args=new_args, kwargs=new_kwargs,
                               *func_args, **func_kwargs)
            except NoReverseMatch:
                # We'll try it again without those arguments.
                pass

    return reverse(viewname, args=args, kwargs=kwargs,
                   *func_args, **func_kwargs)

Example 2

Project: vumi-go
Source File: views.py
View license
@login_required
@csrf_protect
def _static_group(request, contact_store, group):
    if group is None:
        raise Http404

    if request.method == 'POST':
        group_form = ContactGroupForm(request.POST)
        if '_save_group' in request.POST:
            if group_form.is_valid():
                group.name = group_form.cleaned_data['name']
                group.save()
            messages.info(request, 'The group name has been updated')
            return redirect(_group_url(group.key))
        elif '_export' in request.POST:
            tasks.export_group_contacts.delay(
                request.user_api.user_account_key,
                group.key)

            messages.info(request,
                          'The export is scheduled and should '
                          'complete within a few minutes.')
            return redirect(_group_url(group.key))
        elif '_remove' in request.POST:
            contacts = request.POST.getlist('contact')
            for person_key in contacts:
                contact = contact_store.get_contact_by_key(person_key)
                contact.groups.remove(group)
                contact.save()
            messages.info(
                request,
                '%d Contacts removed from group' % len(contacts))
            return redirect(_group_url(group.key))
        elif '_delete_group_contacts' in request.POST:
            tasks.delete_group_contacts.delay(
                request.user_api.user_account_key, group.key)
            messages.info(request,
                          "The group's contacts will be deleted shortly.")
            return redirect(_group_url(group.key))
        elif '_delete_group' in request.POST:
            tasks.delete_group.delay(request.user_api.user_account_key,
                                     group.key)
            messages.info(request, 'The group will be deleted shortly.')
            return redirect(reverse('contacts:index'))
        elif '_complete_contact_upload' in request.POST:
            try:
                import_rule = request.POST.get('import_rule')
                import_handler = {
                    'existing_is_truth': handle_import_existing_is_truth,
                    'upload_is_truth': handle_import_upload_is_truth,
                }.get(import_rule, handle_import_new_contacts)

                import_handler(request, group)
                messages.info(
                    request,
                    'The contacts are being imported. '
                    'We will notify you via email when the import '
                    'has been completed')

            except (ContactParserException, ContactImportException), e:
                if isinstance(e, ContactImportException):
                    error_msg = str(e)
                else:
                    error_msg = 'Something is wrong with the file'
                messages.error(request, error_msg)
                _, file_path = utils.get_file_hints_from_session(request)
                default_storage.delete(file_path)
                utils.clear_file_hints_from_session(request)

            return redirect(_group_url(group.key))

        else:
            upload_contacts_form = UploadContactsForm(request.POST,
                                                      request.FILES)
            if upload_contacts_form.is_valid():
                file_object = upload_contacts_form.cleaned_data['file']
                file_name, file_path = utils.store_temporarily(file_object)
                utils.store_file_hints_in_session(
                    request, file_name, file_path)
                return redirect(_group_url(group.key))
            else:
                # We didn't get any useful POST variables, so just redirect
                # back to the group page without doing anything.
                return redirect(_group_url(group.key))

    else:
        group_form = ContactGroupForm({
            'name': group.name,
        })

    context = {
        'group': group,
        'group_form': group_form,
    }

    if 'clear-upload' in request.GET:
        # FIXME this is a debug statement
        utils.clear_file_hints_from_session(request)

    if utils.has_uncompleted_contact_import(request):
        try:
            file_name, file_path = utils.get_file_hints_from_session(request)
            file_type, parser = ContactFileParser.get_parser(file_name)
            has_header, headers, row = parser.guess_headers_and_row(file_path)
            context.update({
                'contact_data_headers': headers,
                'field_normalizer': FieldNormalizer(),
                'contact_data_row': row,
                # NOTE: Only if we have a key (contact UUID) value in the
                #       row we can look at updating contacts instead of
                #       only writing new ones.
                'can_update_contacts': 'key' in row,
            })
        except (ValueError, ContactParserException):
            messages.error(request, 'Something is wrong with the file')
            utils.clear_file_hints_from_session(request)
            default_storage.delete(file_path)

    query = request.GET.get('q', '')
    if query:
        if ':' not in query:
            query = 'name:%s' % (query,)
        keys_page = contact_store.search_contacts(query)
    else:
        keys_page = contact_store.get_contact_keys_for_group(group)

    limit = int(request.GET.get('limit', 100))
    count, keys = _get_count_and_keys_from_index(keys_page, limit)
    if keys:
        messages.info(
            request,
            "Showing %s of the group's %s contact(s)" % (len(keys), count))

    contacts = utils.contacts_by_key(contact_store, *keys)
    context.update({
        'query': request.GET.get('q'),
        'selected_contacts': contacts,
        'member_count': contact_store.count_contacts_for_group(group),
    })

    return render(request, 'contacts/static_group_detail.html', context)

Example 3

Project: django-yarr
Source File: views.py
View license
@login_required
def entry_state(
    request, feed_pk=None, entry_pk=None, state=None, if_state=None,
    template="yarr/confirm.html",
):
    """
    Change entry state for an entry, a feed, or all entries
    """
    # Filter entries by selection
    qs = models.Entry.objects.user(request.user)
    if entry_pk is not None:
        # Changing specific entry
        qs = qs.filter(pk=entry_pk)
        
    elif state == ENTRY_READ:
        if feed_pk is not None:
            # Changing all entries in a feed
            qs = qs.filter(feed__pk=feed_pk)
            
        # Only mark unread as read - don't change saved
        qs = qs.unread()
        
    else:
        # Either unknown state, or trying to bulk unread/save
        messages.error(request, 'Cannot perform this operation')
        return HttpResponseRedirect(reverse(home))
        
    # Check for if_state
    if if_state is not None:
        if if_state == ENTRY_UNREAD:
            qs = qs.unread()
        elif if_state == ENTRY_READ:
            qs = qs.read()
        elif if_state == ENTRY_SAVED:
            qs = qs.saved()
        else:
            messages.error(request, 'Unknown condition')
            return HttpResponseRedirect(reverse(home))
        
    # Check there's something to change
    count = qs.count()
    if count == 0:
        messages.error(request, 'No entries found to change')
        return HttpResponseRedirect(reverse(home))
    
    # Process
    if request.POST:
        # Change state and update unread count
        qs.set_state(state)
        
        # If they're not marked as read, they can't ever expire
        # If they're marked as read, they will be given an expiry date
        # when Feed._update_entries determines they can expire
        if state != ENTRY_READ:
            qs.clear_expiry()
        
        if state is ENTRY_UNREAD:
            messages.success(request, 'Marked as unread')
        elif state is ENTRY_READ:
            messages.success(request, 'Marked as read')
        elif state is ENTRY_SAVED:
            messages.success(request, 'Saved')
        return HttpResponseRedirect(reverse(home))
    
    # Prep messages
    op_text = {
        'verb': 'mark',
        'desc': '',
    }
    if state is ENTRY_UNREAD:
        op_text['desc'] = ' as unread'
    elif state is ENTRY_READ:
        op_text['desc'] = ' as read'
    elif state is ENTRY_SAVED:
        op_text['verb'] = 'save'
        
    if entry_pk:
        title = '%(verb)s item%(desc)s'
        msg = 'Are you sure you want to %(verb)s this item%(desc)s?'
    elif feed_pk:
        title = '%(verb)s feed%(desc)s'
        msg = 'Are you sure you want to %(verb)s all items in the feed%(desc)s?'
    else:
        title = '%(verb)s all items%(desc)s'
        msg = 'Are you sure you want to %(verb)s all items in every feed%(desc)s?'
    
    title = title % op_text
    title = title[0].upper() + title[1:]
    
    return render(request, template, {
        'title':    title,
        'message':  msg % op_text,
        'submit_label': title,
    })

Example 4

View license
    def test_change_role_categories_permissions_view(self):
        """change role categories perms view works"""
        self.client.post(
            reverse('misago:admin:permissions:users:new'),
            data=fake_post_data(Role(), {'name': 'Test CategoryRole'}))

        test_role = Role.objects.get(name='Test CategoryRole')

        root = Category.objects.root_category()
        for descendant in root.get_descendants():
            descendant.delete()

        self.assertEqual(Category.objects.count(), 2)
        response = self.client.get(
            reverse('misago:admin:permissions:users:categories', kwargs={
                'pk': test_role.pk
            }))
        self.assertEqual(response.status_code, 302)

        """
        Create categories tree for test cases:

        Category A
          + Category B
        Category C
          + Category D
        """
        root = Category.objects.root_category()
        self.client.post(reverse('misago:admin:categories:nodes:new'), data={
            'name': 'Category A',
            'new_parent': root.pk,
            'prune_started_after': 0,
            'prune_replied_after': 0,
        })
        self.client.post(reverse('misago:admin:categories:nodes:new'), data={
            'name': 'Category C',
            'new_parent': root.pk,
            'prune_started_after': 0,
            'prune_replied_after': 0,
        })

        category_a = Category.objects.get(slug='category-a')
        category_c = Category.objects.get(slug='category-c')

        self.client.post(reverse('misago:admin:categories:nodes:new'), data={
            'name': 'Category B',
            'new_parent': category_a.pk,
            'prune_started_after': 0,
            'prune_replied_after': 0,
        })
        category_b = Category.objects.get(slug='category-b')

        self.client.post(reverse('misago:admin:categories:nodes:new'), data={
            'name': 'Category D',
            'new_parent': category_c.pk,
            'prune_started_after': 0,
            'prune_replied_after': 0,
        })
        category_d = Category.objects.get(slug='category-d')

        self.assertEqual(Category.objects.count(), 6)

        # See if form page is rendered
        response = self.client.get(
            reverse('misago:admin:permissions:users:categories', kwargs={
                'pk': test_role.pk
            }))
        self.assertContains(response, category_a.name)
        self.assertContains(response, category_b.name)
        self.assertContains(response, category_c.name)
        self.assertContains(response, category_d.name)

        # Set test roles
        self.client.post(
            reverse('misago:admin:permissions:categories:new'),
            data=fake_data({'name': 'Test Comments'}))
        role_comments = CategoryRole.objects.get(name='Test Comments')

        self.client.post(
            reverse('misago:admin:permissions:categories:new'),
            data=fake_data({'name': 'Test Full'}))
        role_full = CategoryRole.objects.get(name='Test Full')

        # See if form contains those roles
        response = self.client.get(
            reverse('misago:admin:permissions:users:categories', kwargs={
                'pk': test_role.pk
            }))
        self.assertContains(response, role_comments.name)
        self.assertContains(response, role_full.name)

        # Assign roles to categories
        response = self.client.post(
            reverse('misago:admin:permissions:users:categories', kwargs={
                'pk': test_role.pk
            }),
            data={
                ('%s-role' % category_a.pk): role_comments.pk,
                ('%s-role' % category_b.pk): role_comments.pk,
                ('%s-role' % category_c.pk): role_full.pk,
                ('%s-role' % category_d.pk): role_full.pk,
            })
        self.assertEqual(response.status_code, 302)

        # Check that roles were assigned
        categories_acls = test_role.categories_acls
        self.assertEqual(
            categories_acls.get(category=category_a).category_role_id,
            role_comments.pk)
        self.assertEqual(
            categories_acls.get(category=category_b).category_role_id,
            role_comments.pk)
        self.assertEqual(
            categories_acls.get(category=category_c).category_role_id,
            role_full.pk)
        self.assertEqual(
            categories_acls.get(category=category_d).category_role_id,
            role_full.pk)

Example 5

Project: rapidpro
Source File: test_models.py
View license
    def test_event_deliveries(self):
        sms = self.create_msg(contact=self.joe, direction='I', status='H', text="I'm gonna pop some tags")

        with patch('requests.Session.send') as mock:
            now = timezone.now()
            mock.return_value = MockResponse(200, "Hello World")

            # trigger an event, shouldnn't fire as we don't have a webhook
            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            self.assertFalse(WebHookEvent.objects.all())

        self.setupChannel()

        with patch('requests.Session.send') as mock:
            # clear out which events we listen for, we still shouldnt be notified though we have a webhook
            self.channel.org.webhook_events = 0
            self.channel.org.save()

            now = timezone.now()
            mock.return_value = MockResponse(200, "Hello World")

            # trigger an event, shouldnn't fire as we don't have a webhook
            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            self.assertFalse(WebHookEvent.objects.all())

        self.setupChannel()

        with patch('requests.Session.send') as mock:
            # remove all the org users
            self.org.administrators.clear()
            self.org.editors.clear()
            self.org.viewers.clear()

            mock.return_value = MockResponse(200, "Hello World")

            # trigger an event
            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            self.assertEquals('F', event.status)
            self.assertEquals(0, event.try_count)
            self.assertFalse(event.next_attempt)

            result = WebHookResult.objects.get()
            self.assertStringContains("No active user", result.message)
            self.assertEquals(0, result.status_code)

            self.assertFalse(mock.called)

            # what if they send weird json back?
            WebHookEvent.objects.all().delete()
            WebHookResult.objects.all().delete()

        # add ad manager back in
        self.org.administrators.add(self.admin)
        self.admin.set_org(self.org)

        with patch('requests.Session.send') as mock:
            mock.return_value = MockResponse(200, "Hello World")

            # trigger an event
            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            self.assertEquals('C', event.status)
            self.assertEquals(1, event.try_count)
            self.assertFalse(event.next_attempt)

            result = WebHookResult.objects.get()
            self.assertStringContains("Event delivered successfully", result.message)
            self.assertStringContains("not JSON", result.message)
            self.assertEquals(200, result.status_code)

            self.assertTrue(mock.called)

            WebHookEvent.objects.all().delete()
            WebHookResult.objects.all().delete()

        with patch('requests.Session.send') as mock:
            # valid json, but not our format
            bad_json = '{ "thrift_shops": ["Goodwill", "Value Village"] }'
            mock.return_value = MockResponse(200, bad_json)

            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            self.assertEquals('C', event.status)
            self.assertEquals(1, event.try_count)
            self.assertFalse(event.next_attempt)

            self.assertTrue(mock.called)

            result = WebHookResult.objects.get()
            self.assertStringContains("Event delivered successfully", result.message)
            self.assertStringContains("ignoring", result.message)
            self.assertEquals(200, result.status_code)
            self.assertEquals(bad_json, result.body)

            WebHookEvent.objects.all().delete()
            WebHookResult.objects.all().delete()

        with patch('requests.Session.send') as mock:
            mock.return_value = MockResponse(200, '{ "phone": "+250788123123", "text": "I am success" }')

            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            self.assertEquals('C', event.status)
            self.assertEquals(1, event.try_count)
            self.assertFalse(event.next_attempt)

            result = WebHookResult.objects.get()
            self.assertEquals(200, result.status_code)

            self.assertTrue(mock.called)

            broadcast = Broadcast.objects.get()
            contact = Contact.get_or_create(self.org, self.admin, name=None, urns=["tel:+250788123123"], channel=self.channel)
            self.assertTrue("I am success", broadcast.text)
            self.assertTrue(contact, broadcast.contacts.all())

            self.assertTrue(mock.called)
            args = mock.call_args_list[0][0]
            prepared_request = args[0]
            self.assertEquals(self.org.get_webhook_url(), prepared_request.url)

            data = parse_qs(prepared_request.body)
            self.assertEquals(self.joe.get_urn(TEL_SCHEME).path, data['phone'][0])
            self.assertEquals(unicode(self.joe.get_urn(TEL_SCHEME)), data['urn'][0])
            self.assertEquals(self.joe.uuid, data['contact'][0])
            self.assertEquals(sms.pk, int(data['sms'][0]))
            self.assertEquals(self.channel.pk, int(data['channel'][0]))
            self.assertEquals(SMS_RECEIVED, data['event'][0])
            self.assertEquals("I'm gonna pop some tags", data['text'][0])
            self.assertTrue('time' in data)

            WebHookEvent.objects.all().delete()
            WebHookResult.objects.all().delete()

        with patch('requests.Session.send') as mock:
            mock.return_value = MockResponse(500, "I am error")

            next_attempt_earliest = timezone.now() + timedelta(minutes=4)
            next_attempt_latest = timezone.now() + timedelta(minutes=6)

            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            self.assertEquals('E', event.status)
            self.assertEquals(1, event.try_count)
            self.assertTrue(event.next_attempt)
            self.assertTrue(next_attempt_earliest < event.next_attempt and next_attempt_latest > event.next_attempt)

            result = WebHookResult.objects.get()
            self.assertStringContains("Error", result.message)
            self.assertEquals(500, result.status_code)
            self.assertEquals("I am error", result.body)

            # make sure things become failures after three retries
            event.try_count = 2
            event.deliver()
            event.save()

            self.assertTrue(mock.called)

            self.assertEquals('F', event.status)
            self.assertEquals(3, event.try_count)
            self.assertFalse(event.next_attempt)

            result = WebHookResult.objects.get()
            self.assertStringContains("Error", result.message)
            self.assertEquals(500, result.status_code)
            self.assertEquals("I am error", result.body)
            self.assertEquals("http://fake.com/webhook.php", result.url)
            self.assertTrue(result.data.find("pop+some+tags") > 0)

            # check out our api log
            response = self.client.get(reverse('api.log'))
            self.assertRedirect(response, reverse('users.user_login'))

            response = self.client.get(reverse('api.log_read', args=[event.pk]))
            self.assertRedirect(response, reverse('users.user_login'))

            WebHookEvent.objects.all().delete()
            WebHookResult.objects.all().delete()

        # add a webhook header to the org
        self.channel.org.webhook = u'{"url": "http://fake.com/webhook.php", "headers": {"X-My-Header": "foobar", "Authorization": "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="}, "method": "POST"}'
        self.channel.org.save()

        # check that our webhook settings have saved
        self.assertEquals('http://fake.com/webhook.php', self.channel.org.get_webhook_url())
        self.assertDictEqual({'X-My-Header': 'foobar', 'Authorization': 'Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}, self.channel.org.get_webhook_headers())

        with patch('requests.Session.send') as mock:
            mock.return_value = MockResponse(200, "Boom")
            WebHookEvent.trigger_sms_event(SMS_RECEIVED, sms, now)
            event = WebHookEvent.objects.get()

            result = WebHookResult.objects.get()
            # both headers should be in the json-encoded url string
            self.assertStringContains('X-My-Header: foobar', result.request)
            self.assertStringContains('Authorization: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==', result.request)

Example 6

Project: rapidpro
Source File: tests.py
View license
    def test_views(self):
        # update the planting date for our contacts
        self.farmer1.set_field(self.user, 'planting_date', '1/10/2020')

        # don't log in, try to create a new campaign
        response = self.client.get(reverse('campaigns.campaign_create'))
        self.assertRedirect(response, reverse('users.user_login'))

        # ok log in as an org
        self.login(self.admin)

        # go to to the creation page
        response = self.client.get(reverse('campaigns.campaign_create'))
        self.assertEquals(200, response.status_code)

        post_data = dict(name="Planting Reminders", group=self.farmers.pk)
        response = self.client.post(reverse('campaigns.campaign_create'), post_data)

        # should redirect to read page for this campaign
        campaign = Campaign.objects.get()
        self.assertRedirect(response, reverse('campaigns.campaign_read', args=[campaign.pk]))

        # go to the list page, should be there as well
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertContains(response, "Planting Reminders")

        # try searching for the campaign by group name
        response = self.client.get(reverse('campaigns.campaign_list') + "?search=farmers")
        self.assertContains(response, "Planting Reminders")

        # test no match
        response = self.client.get(reverse('campaigns.campaign_list') + "?search=factory")
        self.assertNotContains(response, "Planting Reminders")

        # archive a campaign
        post_data = dict(action='archive', objects=campaign.pk)
        self.client.post(reverse('campaigns.campaign_list'), post_data)
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertNotContains(response, "Planting Reminders")

        # restore the campaign
        response = self.client.get(reverse('campaigns.campaign_archived'))
        self.assertContains(response, "Planting Reminders")
        post_data = dict(action='restore', objects=campaign.pk)
        self.client.post(reverse('campaigns.campaign_archived'), post_data)
        response = self.client.get(reverse('campaigns.campaign_archived'))
        self.assertNotContains(response, "Planting Reminders")
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertContains(response, "Planting Reminders")

        # test viewers cannot use action archive or restore
        self.client.logout()

        # create a viewer
        self.viewer = self.create_user("Viewer")
        self.org.viewers.add(self.viewer)
        self.viewer.set_org(self.org)

        self.login(self.viewer)

        # go to the list page, should be there as well
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertContains(response, "Planting Reminders")

        # cannot archive a campaign
        post_data = dict(action='archive', objects=campaign.pk)
        self.client.post(reverse('campaigns.campaign_list'), post_data)
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertContains(response, "Planting Reminders")
        response = self.client.get(reverse('campaigns.campaign_archived'))
        self.assertNotContains(response, "Planting Reminders")

        self.client.logout()
        self.login(self.admin)

        # see if we can create a new event, should see both sms and voice flows
        response = self.client.get(reverse('campaigns.campaignevent_create') + "?campaign=%d" % campaign.pk)
        self.assertContains(response, self.reminder_flow.name)
        self.assertContains(response, self.voice_flow.name)
        self.assertEquals(200, response.status_code)

        post_data = dict(relative_to=self.planting_date.pk, delivery_hour=15, base='', direction='A', offset=2, unit='D', event_type='M', flow_to_start=self.reminder_flow.pk)
        response = self.client.post(reverse('campaigns.campaignevent_create') + "?campaign=%d" % campaign.pk, post_data)

        self.assertTrue(response.context['form'].errors)
        self.assertTrue('A message is required' in unicode(response.context['form'].errors['__all__']))

        post_data = dict(relative_to=self.planting_date.pk, delivery_hour=15, base='', direction='A', offset=2, unit='D', event_type='F')
        response = self.client.post(reverse('campaigns.campaignevent_create') + "?campaign=%d" % campaign.pk, post_data)

        self.assertTrue(response.context['form'].errors)
        self.assertTrue('Please select a flow' in response.context['form'].errors['flow_to_start'])

        post_data = dict(relative_to=self.planting_date.pk, delivery_hour=15, base='', direction='A', offset=2, unit='D', event_type='F', flow_to_start=self.reminder_flow.pk)
        response = self.client.post(reverse('campaigns.campaignevent_create') + "?campaign=%d" % campaign.pk, post_data)

        # should be redirected back to our campaign read page
        self.assertRedirect(response, reverse('campaigns.campaign_read', args=[campaign.pk]))

        # should now have a campaign event
        event = CampaignEvent.objects.get()
        self.assertEquals(self.reminder_flow, event.flow)
        self.assertEquals(self.planting_date, event.relative_to)
        self.assertEquals(2, event.offset)

        # read the campaign read page
        response = self.client.get(reverse('campaigns.campaign_read', args=[campaign.pk]))
        self.assertContains(response, "Color Flow")
        self.assertContains(response, "1")

        # should also have event fires scheduled for our contacts
        fire = EventFire.objects.get()
        self.assertEquals(13, fire.scheduled.hour)
        self.assertEquals(3, fire.scheduled.day)
        self.assertEquals(10, fire.scheduled.month)
        self.assertEquals(2020, fire.scheduled.year)
        self.assertEquals(event, fire.event)

        post_data = dict(relative_to=self.planting_date.pk, delivery_hour=15, base='', direction='A', offset=1, unit='D', event_type='F', flow_to_start=self.reminder_flow.pk)
        response = self.client.post(reverse('campaigns.campaignevent_update', args=[event.pk]), post_data)

        # should be redirected back to our campaign event read page
        self.assertRedirect(response, reverse('campaigns.campaignevent_read', args=[event.pk]))

        # should now have update the campaign event
        event = CampaignEvent.objects.get()
        self.assertEquals(self.reminder_flow, event.flow)
        self.assertEquals(self.planting_date, event.relative_to)
        self.assertEquals(1, event.offset)

        # should also event fires rescheduled for our contacts
        fire = EventFire.objects.get()
        self.assertEquals(13, fire.scheduled.hour)
        self.assertEquals(2, fire.scheduled.day)
        self.assertEquals(10, fire.scheduled.month)
        self.assertEquals(2020, fire.scheduled.year)
        self.assertEquals(event, fire.event)

        # trying to archive our flow should fail since it belongs to a campaign
        post_data = dict(action='archive', objects=self.reminder_flow.pk)
        response = self.client.post(reverse('flows.flow_list'), post_data)
        self.reminder_flow.refresh_from_db()
        self.assertFalse(self.reminder_flow.is_archived)
        self.assertEqual('Color Flow is used inside a campaign. To archive it, first remove it from your campaigns.', response.get('Temba-Toast'))

        # archive the campaign
        post_data = dict(action='archive', objects=campaign.pk)
        self.client.post(reverse('campaigns.campaign_list'), post_data)
        response = self.client.get(reverse('campaigns.campaign_list'))
        self.assertNotContains(response, "Planting Reminders")

        # should have no event fires
        self.assertFalse(EventFire.objects.all())

        # restore the campaign
        post_data = dict(action='restore', objects=campaign.pk)
        self.client.post(reverse('campaigns.campaign_archived'), post_data)

        # EventFire should be back
        self.assertTrue(EventFire.objects.all())

        # set a planting date on our other farmer
        self.farmer2.set_field(self.user, 'planting_date', '1/6/2022')

        # should have two fire events now
        fires = EventFire.objects.all()
        self.assertEquals(2, len(fires))

        fire = fires[0]
        self.assertEquals(2, fire.scheduled.day)
        self.assertEquals(10, fire.scheduled.month)
        self.assertEquals(2020, fire.scheduled.year)
        self.assertEquals(event, fire.event)

        fire = fires[1]
        self.assertEquals(2, fire.scheduled.day)
        self.assertEquals(6, fire.scheduled.month)
        self.assertEquals(2022, fire.scheduled.year)
        self.assertEquals(event, fire.event)

        # setting a planting date on our outside contact has no effect
        self.nonfarmer.set_field(self.user, 'planting_date', '1/7/2025')
        self.assertEquals(2, EventFire.objects.all().count())

        # remove one of the farmers from the group
        response = self.client.post(reverse('contacts.contact_read', args=[self.farmer1.uuid]),
                                    dict(contact=self.farmer1.pk, group=self.farmers.pk))
        self.assertEquals(200, response.status_code)

        # should only be one event now (on farmer 2)
        fire = EventFire.objects.get()
        self.assertEquals(2, fire.scheduled.day)
        self.assertEquals(6, fire.scheduled.month)
        self.assertEquals(2022, fire.scheduled.year)
        self.assertEquals(event, fire.event)

        # but if we add him back in, should be updated
        post_data = dict(name=self.farmer1.name,
                         groups=[self.farmers.id],
                         __urn__tel=self.farmer1.get_urn('tel').path)

        self.client.post(reverse('contacts.contact_update', args=[self.farmer1.id]), post_data)
        response = self.client.post(reverse('contacts.contact_update_fields', args=[self.farmer1.id]),
                                    dict(__field__planting_date=['4/8/2020']))
        self.assertRedirect(response, reverse('contacts.contact_read', args=[self.farmer1.uuid]))

        fires = EventFire.objects.all()
        self.assertEquals(2, len(fires))

        fire = fires[0]
        self.assertEquals(5, fire.scheduled.day)
        self.assertEquals(8, fire.scheduled.month)
        self.assertEquals(2020, fire.scheduled.year)
        self.assertEquals(event, fire.event)
        self.assertEquals(str(fire), "%s - %s" % (fire.event, fire.contact))

        event = CampaignEvent.objects.get()

        # get the detail page of the event
        response = self.client.get(reverse('campaigns.campaignevent_read', args=[event.pk]))
        self.assertEquals(200, response.status_code)
        self.assertEquals(response.context['scheduled_event_fires_count'], 0)
        self.assertEquals(len(response.context['scheduled_event_fires']), 2)

        # delete an event
        self.client.post(reverse('campaigns.campaignevent_delete', args=[event.pk]), dict())
        self.assertFalse(CampaignEvent.objects.all()[0].is_active)
        response = self.client.get(reverse('campaigns.campaign_read', args=[campaign.pk]))
        self.assertNotContains(response, "Color Flow")

Example 7

Project: rapidpro
Source File: tests.py
View license
    @patch('temba.orgs.models.TwilioRestClient', MockTwilioClient)
    @patch('temba.ivr.clients.TwilioClient', MockTwilioClient)
    @patch('twilio.util.RequestValidator', MockRequestValidator)
    def test_ivr_flow(self):
        from temba.orgs.models import ACCOUNT_TOKEN, ACCOUNT_SID

        # should be able to create an ivr flow
        self.assertTrue(self.org.supports_ivr())
        self.assertTrue(self.admin.groups.filter(name="Beta"))
        self.assertContains(self.client.get(reverse('flows.flow_create')), 'Phone Call')

        # no twilio config yet
        self.assertFalse(self.org.is_connected_to_twilio())
        self.assertIsNone(self.org.get_twilio_client())

        # connect it and check our client is configured
        self.org.connect_twilio("TEST_SID", "TEST_TOKEN", self.admin)
        self.org.save()
        self.assertTrue(self.org.is_connected_to_twilio())
        self.assertIsNotNone(self.org.get_twilio_client())

        # no twiml api config yet
        self.assertIsNone(self.channel.get_twiml_client())

        # twiml api config
        config = {Channel.CONFIG_SEND_URL: 'https://api.twilio.com',
                  ACCOUNT_SID: 'TEST_SID',
                  ACCOUNT_TOKEN: 'TEST_TOKEN'}
        channel = Channel.add_twiml_api_channel(self.org, self.org.get_user(), 'BR', '558299990000', config, 'AC')
        self.assertEqual(channel.org, self.org)
        self.assertEqual(channel.address, '+558299990000')

        # import an ivr flow
        self.import_file('call_me_maybe')

        # make sure our flow is there as expected
        flow = Flow.objects.filter(name='Call me maybe').first()
        self.assertEquals('callme', flow.triggers.filter(trigger_type='K').first().keyword)

        user_settings = self.admin.get_settings()
        user_settings.tel = '+18005551212'
        user_settings.save()

        # start our flow as a test contact
        test_contact = Contact.get_test_contact(self.admin)
        Contact.set_simulation(True)
        flow.start([], [test_contact])
        call = IVRCall.objects.filter(direction=OUTGOING).first()

        # should be using the usersettings number in test mode
        self.assertEquals('Placing test call to +1 800-555-1212', ActionLog.objects.all().first().text)

        # our twilio callback on pickup
        post_data = dict(CallSid='CallSid', CallStatus='in-progress', CallDuration=20)
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), post_data)

        # simulate a button press and that our message is handled
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), dict(Digits=4))
        msg = Msg.objects.filter(contact=test_contact, text="4", direction='I').first()
        self.assertIsNotNone(msg)
        self.assertEqual('H', msg.status)

        # explicitly hanging up on a test call should remove it
        call.update_status('in-progress', 0)
        call.save()
        IVRCall.hangup_test_call(flow)
        self.assertTrue(IVRCall.objects.filter(pk=call.pk).first())

        ActionLog.objects.all().delete()
        IVRCall.objects.all().delete()
        Msg.objects.all().delete()

        # now pretend we are a normal caller
        eric = self.create_contact('Eric Newcomer', number='+13603621737')
        Contact.set_simulation(False)
        flow.start([], [eric], restart_participants=True)

        # we should have an outbound ivr call now
        call = IVRCall.objects.filter(direction=OUTGOING).first()

        self.assertEquals(0, call.get_duration())
        self.assertIsNotNone(call)
        self.assertEquals('CallSid', call.external_id)

        # after a call is picked up, twilio will call back to our server
        post_data = dict(CallSid='CallSid', CallStatus='in-progress', CallDuration=20)
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), post_data)

        self.assertContains(response, '<Say>Would you like me to call you? Press one for yes, two for no, or three for maybe.</Say>')
        self.assertEquals(1, Msg.objects.filter(msg_type=IVR).count())
        self.assertEquals(1, self.org.get_credits_used())

        # make sure a message from the person on the call goes to the
        # inbox since our flow doesn't handle text messages
        msg = self.create_msg(direction='I', contact=eric, text="message during phone call")
        self.assertFalse(Flow.find_and_handle(msg))

        # updated our status and duration accordingly
        call = IVRCall.objects.get(pk=call.pk)
        self.assertEquals(20, call.duration)
        self.assertEquals(IN_PROGRESS, call.status)

        # don't press any numbers, but # instead
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]) + "?empty=1", dict())
        self.assertContains(response, '<Say>Press one, two, or three. Thanks.</Say>')
        self.assertEquals(4, self.org.get_credits_used())

        # press the number 4 (unexpected)
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), dict(Digits=4))

        # our inbound message should be handled
        msg = Msg.objects.filter(text='4', msg_type=IVR).order_by('-created_on').first()
        self.assertEqual('H', msg.status)

        self.assertContains(response, '<Say>Press one, two, or three. Thanks.</Say>')
        self.assertEquals(6, self.org.get_credits_used())

        # two more messages, one inbound and it's response
        self.assertEquals(5, Msg.objects.filter(msg_type=IVR).count())

        # now let's have them press the number 3 (for maybe)
        response = self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), dict(Digits=3))
        self.assertContains(response, '<Say>This might be crazy.</Say>')
        messages = Msg.objects.filter(msg_type=IVR).order_by('pk')
        self.assertEquals(7, messages.count())
        self.assertEquals(8, self.org.get_credits_used())

        for msg in messages:
            self.assertEquals(1, msg.steps.all().count(), msg="Message '%s' not attached to step" % msg.text)

        # twilio would then disconnect the user and notify us of a completed call
        self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), dict(CallStatus='completed'))
        call = IVRCall.objects.get(pk=call.pk)
        self.assertEquals(COMPLETED, call.status)
        self.assertFalse(FlowRun.objects.filter(call=call).first().is_active)

        # simulation gets flipped off by middleware, and this unhandled message doesn't flip it back on
        self.assertFalse(Contact.get_simulation())

        # also shouldn't have any ActionLogs for non-test users
        self.assertEquals(0, ActionLog.objects.all().count())
        self.assertEquals(1, flow.get_completed_runs())

        # should still have no active runs
        self.assertEquals(0, FlowRun.objects.filter(is_active=True).count())

        # and we've exited the flow
        step = FlowStep.objects.all().order_by('-pk').first()
        self.assertTrue(step.left_on)

        # test other our call status mappings with twilio
        def test_status_update(call_to_update, twilio_status, temba_status):
            call_to_update.update_status(twilio_status, 0)
            call_to_update.save()
            self.assertEquals(temba_status, IVRCall.objects.get(pk=call_to_update.pk).status)

        test_status_update(call, 'queued', QUEUED)
        test_status_update(call, 'ringing', RINGING)
        test_status_update(call, 'canceled', CANCELED)
        test_status_update(call, 'busy', BUSY)
        test_status_update(call, 'failed', FAILED)
        test_status_update(call, 'no-answer', NO_ANSWER)

        FlowStep.objects.all().delete()
        IVRCall.objects.all().delete()

        # try sending callme trigger
        from temba.msgs.models import INCOMING
        msg = self.create_msg(direction=INCOMING, contact=eric, text="callme")

        # make sure if we are started with a message we still create a normal voice run
        flow.start([], [eric], restart_participants=True, start_msg=msg)

        # we should have an outbound ivr call now, and no steps yet
        call = IVRCall.objects.filter(direction=OUTGOING).first()
        self.assertIsNotNone(call)
        self.assertEquals(0, FlowStep.objects.all().count())

        # after a call is picked up, twilio will call back to our server
        post_data = dict(CallSid='CallSid', CallStatus='in-progress', CallDuration=20)
        self.client.post(reverse('ivr.ivrcall_handle', args=[call.pk]), post_data)

        # should have two flow steps (the outgoing messages, and the step to handle the response)
        steps = FlowStep.objects.all().order_by('pk')

        # the first step has exactly one message which is an outgoing IVR message
        self.assertEquals(1, steps.first().messages.all().count())
        self.assertEquals(1, steps.first().messages.filter(direction=OUTGOING, msg_type=IVR).count())

        # the next step shouldn't have any messages yet since they haven't pressed anything
        self.assertEquals(0, steps[1].messages.all().count())

        # try updating our status to completed for a test contact
        Contact.set_simulation(True)
        flow.start([], [test_contact])
        call = IVRCall.objects.filter(direction=OUTGOING).order_by('-pk').first()
        call.update_status('completed', 30)
        call.save()
        call.refresh_from_db()

        self.assertEqual(ActionLog.objects.all().order_by('-pk').first().text, 'Call ended.')
        self.assertEqual(call.duration, 30)

        # now look at implied duration
        call.update_status('in-progress', None)
        call.save()
        call.refresh_from_db()
        self.assertIsNotNone(call.get_duration())

Example 8

Project: rapidpro
Source File: tests.py
View license
    def test_trigger_schedule(self):
        self.login(self.admin)
        flow = self.create_flow()

        chester = self.create_contact("Chester", "+250788987654")
        shinoda = self.create_contact("Shinoda", "+250234213455")
        linkin_park = self.create_group("Linkin Park", [chester, shinoda])
        stromae = self.create_contact("Stromae", "+250788645323")

        now = timezone.now()
        now_stamp = time.mktime(now.timetuple())

        tommorrow = now + timedelta(days=1)
        tommorrow_stamp = time.mktime(tommorrow.timetuple())

        post_data = dict()
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['repeat_period'] = 'D'
        post_data['start'] = 'later'
        post_data['start_datetime_value'] = "%d" % tommorrow_stamp

        response = self.client.post(reverse("triggers.trigger_schedule"), post_data)
        self.assertEquals(response.context['form'].errors.keys(), ['flow'])
        self.assertFalse(Trigger.objects.all())
        self.assertFalse(Schedule.objects.all())

        # survey flows should not be an option
        flow.flow_type = Flow.SURVEY
        flow.save()
        response = self.client.get(reverse("triggers.trigger_schedule"))
        self.assertEqual(0, response.context['form'].fields['flow'].queryset.all().count())

        # back to normal flow type
        flow.flow_type = Flow.FLOW
        flow.save()
        self.assertEqual(1, response.context['form'].fields['flow'].queryset.all().count())

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['start'] = 'never'
        post_data['repeat_period'] = 'O'

        response = self.client.post(reverse("triggers.trigger_schedule"), post_data)
        self.assertEquals(1, Trigger.objects.all().count())

        trigger = Trigger.objects.all().order_by('-pk')[0]
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.status, 'U')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['start'] = 'stop'
        post_data['repeat_period'] = 'O'

        response = self.client.post(reverse("triggers.trigger_schedule"), post_data)
        self.assertEquals(2, Trigger.objects.all().count())

        trigger = Trigger.objects.all().order_by('-pk')[0]
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.status, 'U')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['repeat_period'] = 'O'
        post_data['start'] = 'now'
        post_data['start_datetime_value'] = "%d" % now_stamp

        response = self.client.post(reverse("triggers.trigger_schedule"), post_data)
        self.assertEquals(3, Trigger.objects.all().count())

        trigger = Trigger.objects.all().order_by('-pk')[0]
        self.assertTrue(trigger.schedule)
        self.assertFalse(trigger.schedule.next_fire)
        self.assertEquals(trigger.schedule.repeat_period, 'O')
        self.assertEquals(trigger.schedule.repeat_days, 0)
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['repeat_period'] = 'D'
        post_data['start'] = 'later'
        post_data['start_datetime_value'] = "%d" % tommorrow_stamp

        response = self.client.post(reverse("triggers.trigger_schedule"), post_data)
        self.assertEquals(4, Trigger.objects.all().count())

        trigger = Trigger.objects.all().order_by('-pk')[0]
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.repeat_period, 'D')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        update_url = reverse('triggers.trigger_update', args=[trigger.pk])

        post_data = dict()
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['repeat_period'] = 'O'
        post_data['start'] = 'now'
        post_data['start_datetime_value'] = "%d" % now_stamp

        response = self.client.post(update_url, post_data)
        self.assertEquals(response.context['form'].errors.keys(), ['flow'])

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s" % linkin_park.uuid
        post_data['repeat_period'] = 'O'
        post_data['start'] = 'now'
        post_data['start_datetime_value'] = "%d" % now_stamp

        response = self.client.post(update_url, post_data)

        trigger = Trigger.objects.get(pk=trigger.pk)
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.repeat_period, 'O')
        self.assertFalse(trigger.schedule.next_fire)
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertFalse(trigger.contacts.all())

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['start'] = 'never'
        post_data['repeat_period'] = 'O'

        response = self.client.post(update_url, post_data)

        trigger = Trigger.objects.get(pk=trigger.pk)
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.status, 'U')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['start'] = 'stop'
        post_data['repeat_period'] = 'O'

        response = self.client.post(update_url, post_data)

        trigger = Trigger.objects.get(pk=trigger.pk)
        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.status, 'U')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

        post_data = dict()
        post_data['flow'] = flow.pk
        post_data['omnibox'] = "g-%s,c-%s" % (linkin_park.uuid, stromae.uuid)
        post_data['repeat_period'] = 'D'
        post_data['start'] = 'later'
        post_data['start_datetime_value'] = "%d" % tommorrow_stamp

        response = self.client.post(update_url, post_data)

        trigger = Trigger.objects.get(pk=trigger.pk)

        self.assertTrue(trigger.schedule)
        self.assertEquals(trigger.schedule.repeat_period, 'D')
        self.assertEquals(trigger.groups.all()[0].pk, linkin_park.pk)
        self.assertEquals(trigger.contacts.all()[0].pk, stromae.pk)

Example 9

Project: rapidpro
Source File: tests.py
View license
    def test_category_results(self):
        self.setup_color_gender_flow()

        # create a state field:
        # assign c1 and c2 to Kigali
        ContactField.get_or_create(self.org, self.admin, 'state', label="State", value_type=Value.TYPE_STATE)
        ContactField.get_or_create(self.org, self.admin, 'district', label="District", value_type=Value.TYPE_DISTRICT)

        self.c1.set_field(self.user, 'state', "Kigali City")
        self.c1.set_field(self.user, 'district', "Nyarugenge")
        self.c2.set_field(self.user, 'state', "Kigali City")
        self.c2.set_field(self.user, 'district', "Nyarugenge")

        self.run_color_gender_flow(self.c1, "red", "male", "16")
        self.run_color_gender_flow(self.c2, "blue", "female", "19")
        self.run_color_gender_flow(self.c3, "green", "male", "75")
        self.run_color_gender_flow(self.c4, "maroon", "female", "50")

        # create a group of the women
        ladies = self.create_group("Ladies", [self.c2, self.c4])

        # get our rulesets
        color = RuleSet.objects.get(flow=self.flow, label="Color")
        gender = RuleSet.objects.get(flow=self.flow, label="Gender")
        age = RuleSet.objects.get(flow=self.flow, label="Age")

        # fetch our results through the view
        self.login(self.admin)
        response = self.client.get(reverse('flows.ruleset_results', args=[color.pk]))
        response = json.loads(response.content)

        categories = response['results'][0]['categories']
        self.assertEqual('Red', categories[0]['label'])
        self.assertEqual('Blue', categories[1]['label'])
        self.assertEqual('Green', categories[2]['label'])

        self.assertEqual(2, categories[0]['count'])
        self.assertEqual(1, categories[1]['count'])
        self.assertEqual(1, categories[2]['count'])

        # categories should be in the same order as our rules, should have correct counts
        result = Value.get_value_summary(ruleset=color)[0]
        self.assertEquals(3, len(result['categories']))
        self.assertFalse(result['open_ended'])
        self.assertResult(result, 0, "Red", 2)
        self.assertResult(result, 1, "Blue", 1)
        self.assertResult(result, 2, "Green", 1)

        # check our age category as well
        result = Value.get_value_summary(ruleset=age)[0]
        self.assertEquals(3, len(result['categories']))
        self.assertFalse(result['open_ended'])
        self.assertResult(result, 0, "Child", 1)
        self.assertResult(result, 1, "Adult", 2)
        self.assertResult(result, 2, "Senior", 1)

        # and our gender categories
        result = Value.get_value_summary(ruleset=gender)[0]
        self.assertEquals(2, len(result['categories']))
        self.assertFalse(result['open_ended'])
        self.assertResult(result, 0, "Male", 2)
        self.assertResult(result, 1, "Female", 2)

        # now filter the results and only get responses by men
        result = Value.get_value_summary(ruleset=color, filters=[dict(ruleset=gender.pk, categories=["Male"])])[0]
        self.assertResult(result, 0, "Red", 1)
        self.assertResult(result, 1, "Blue", 0)
        self.assertResult(result, 2, "Green", 1)

        # what about men that are adults?
        result = Value.get_value_summary(ruleset=color, filters=[dict(ruleset=gender.pk, categories=["Male"]),
                                         dict(ruleset=age.pk, categories=["Adult"])])[0]
        self.assertResult(result, 0, "Red", 0)
        self.assertResult(result, 1, "Blue", 0)
        self.assertResult(result, 2, "Green", 0)

        # union of all genders
        result = Value.get_value_summary(ruleset=color, filters=[dict(ruleset=gender.pk, categories=["Male", "Female"]),
                                         dict(ruleset=age.pk, categories=["Adult"])])[0]

        self.assertResult(result, 0, "Red", 1)
        self.assertResult(result, 1, "Blue", 1)
        self.assertResult(result, 2, "Green", 0)

        # just women adults by group
        result = Value.get_value_summary(ruleset=color, filters=[dict(groups=[ladies.pk]), dict(ruleset=age.pk, categories="Adult")])[0]

        self.assertResult(result, 0, "Red", 1)
        self.assertResult(result, 1, "Blue", 1)
        self.assertResult(result, 2, "Green", 0)

        # remove one of the women from the group
        ladies.update_contacts(self.user, [self.c2], False)

        # get a new summary
        result = Value.get_value_summary(ruleset=color, filters=[dict(groups=[ladies.pk]), dict(ruleset=age.pk, categories="Adult")])[0]

        self.assertResult(result, 0, "Red", 1)
        self.assertResult(result, 1, "Blue", 0)
        self.assertResult(result, 2, "Green", 0)

        # ok, back in she goes
        ladies.update_contacts(self.user, [self.c2], True)

        # do another run for contact 1
        self.run_color_gender_flow(self.c1, "blue", "male", "16")

        # totals should reflect the new value, not the old
        result = Value.get_value_summary(ruleset=color)[0]
        self.assertResult(result, 0, "Red", 1)
        self.assertResult(result, 1, "Blue", 2)
        self.assertResult(result, 2, "Green", 1)

        # what if we do a partial run?
        self.send_message(self.flow, "red", contact=self.c1, restart_participants=True)

        # should change our male/female breakdown since c1 now no longer has a gender
        result = Value.get_value_summary(ruleset=gender)[0]
        self.assertEquals(2, len(result['categories']))
        self.assertResult(result, 0, "Male", 1)
        self.assertResult(result, 1, "Female", 2)

        # back to a full flow
        self.run_color_gender_flow(self.c1, "blue", "male", "16")

        # ok, now segment by gender
        result = Value.get_value_summary(ruleset=color, filters=[], segment=dict(ruleset=gender.pk, categories=["Male", "Female"]))
        male_result = result[0]
        self.assertResult(male_result, 0, "Red", 0)
        self.assertResult(male_result, 1, "Blue", 1)
        self.assertResult(male_result, 2, "Green", 1)

        female_result = result[1]
        self.assertResult(female_result, 0, "Red", 1)
        self.assertResult(female_result, 1, "Blue", 1)
        self.assertResult(female_result, 2, "Green", 0)

        # segment by gender again, but use the contact field to do so
        result = Value.get_value_summary(ruleset=color, filters=[], segment=dict(contact_field="Gender", values=["MALE", "Female"]))
        male_result = result[0]
        self.assertResult(male_result, 0, "Red", 0)
        self.assertResult(male_result, 1, "Blue", 1)
        self.assertResult(male_result, 2, "Green", 1)

        female_result = result[1]
        self.assertResult(female_result, 0, "Red", 1)
        self.assertResult(female_result, 1, "Blue", 1)
        self.assertResult(female_result, 2, "Green", 0)

        # add in a filter at the same time
        result = Value.get_value_summary(ruleset=color, filters=[dict(ruleset=color.pk, categories=["Blue"])],
                                         segment=dict(ruleset=gender.pk, categories=["Male", "Female"]))

        male_result = result[0]
        self.assertResult(male_result, 0, "Red", 0)
        self.assertResult(male_result, 1, "Blue", 1)
        self.assertResult(male_result, 2, "Green", 0)

        female_result = result[1]
        self.assertResult(female_result, 0, "Red", 0)
        self.assertResult(female_result, 1, "Blue", 1)
        self.assertResult(female_result, 2, "Green", 0)

        # ok, try segmenting by location instead
        result = Value.get_value_summary(ruleset=color, segment=dict(location="State"))

        eastern_result = result[0]
        self.assertEquals('171591', eastern_result['boundary'])
        self.assertEquals('Eastern Province', eastern_result['label'])
        self.assertResult(eastern_result, 0, "Red", 0)
        self.assertResult(eastern_result, 1, "Blue", 0)
        self.assertResult(eastern_result, 2, "Green", 0)

        kigali_result = result[1]
        self.assertEquals('1708283', kigali_result['boundary'])
        self.assertEquals('Kigali City', kigali_result['label'])
        self.assertResult(kigali_result, 0, "Red", 0)
        self.assertResult(kigali_result, 1, "Blue", 2)
        self.assertResult(kigali_result, 2, "Green", 0)

        # updating state location leads to updated data
        self.c2.set_field(self.user, 'state', "Eastern Province")
        result = Value.get_value_summary(ruleset=color, segment=dict(location="State"))

        eastern_result = result[0]
        self.assertEquals('171591', eastern_result['boundary'])
        self.assertEquals('Eastern Province', eastern_result['label'])
        self.assertResult(eastern_result, 0, "Red", 0)
        self.assertResult(eastern_result, 1, "Blue", 1)
        self.assertResult(eastern_result, 2, "Green", 0)

        kigali_result = result[1]
        self.assertEquals('1708283', kigali_result['boundary'])
        self.assertEquals('Kigali City', kigali_result['label'])
        self.assertResult(kigali_result, 0, "Red", 0)
        self.assertResult(kigali_result, 1, "Blue", 1)
        self.assertResult(kigali_result, 2, "Green", 0)

        # segment by district instead
        result = Value.get_value_summary(ruleset=color, segment=dict(parent="1708283", location="District"))

        # only on district in kigali
        self.assertEquals(1, len(result))
        kigali_result = result[0]
        self.assertEquals('3963734', kigali_result['boundary'])
        self.assertEquals('Nyarugenge', kigali_result['label'])
        self.assertResult(kigali_result, 0, "Red", 0)
        self.assertResult(kigali_result, 1, "Blue", 2)
        self.assertResult(kigali_result, 2, "Green", 0)

        # do a sanity check on our choropleth view
        self.login(self.admin)
        response = self.client.get(reverse('flows.ruleset_choropleth', args=[color.pk]) +
                                   "?_format=json&boundary=" + self.org.country.osm_id)

        # response should be valid json
        response = json.loads(response.content)

        # should have breaks
        self.assertTrue('breaks' in response)

        # should have two categories, Blue and Others
        self.assertEquals(2, len(response['categories']))
        self.assertEquals("Blue", response['categories'][0])
        self.assertEquals("Others", response['categories'][1])

        # assert our kigali result
        kigali_result = response['scores']['1708283']
        self.assertEquals(1, kigali_result['score'])
        self.assertEquals("Kigali City", kigali_result['name'])
        self.assertEquals("Blue", kigali_result['results'][0]['label'])
        self.assertEquals("Others", kigali_result['results'][1]['label'])

        self.assertEquals(1, kigali_result['results'][0]['count'])
        self.assertEquals(0, kigali_result['results'][1]['count'])

        self.assertEquals(100, kigali_result['results'][0]['percentage'])
        self.assertEquals(0, kigali_result['results'][1]['percentage'])

        with patch('temba.values.models.Value.get_value_summary') as mock:
            mock.return_value = []

            response = self.client.get(reverse('flows.ruleset_choropleth', args=[color.pk]) +
                                       "?_format=json&boundary=" + self.org.country.osm_id)

            # response should be valid json
            response = json.loads(response.content)

            # should have two categories, Blue and Others
            self.assertEquals(2, len(response['categories']))
            self.assertEquals("", response['categories'][0])
            self.assertEquals("", response['categories'][1])

            # all counts and percentage are 0
            self.assertEquals(0, response['totals']['count'])
            self.assertEquals(0, response['totals']['results'][0]['count'])
            self.assertEquals(0, response['totals']['results'][0]['percentage'])
            self.assertEquals(0, response['totals']['results'][1]['count'])
            self.assertEquals(0, response['totals']['results'][1]['percentage'])

            # and empty string labels
            self.assertEquals("", response['totals']['results'][0]['label'])
            self.assertEquals("", response['totals']['results'][1]['label'])

        # also check our analytics view
        response = self.client.get(reverse('flows.ruleset_analytics'))

        # make sure we have only one flow in it
        flows = json.loads(response.context['flows'])
        self.assertEquals(1, len(flows))
        self.assertEquals(3, len(flows[0]['rules']))

Example 10

Project: Observatory
Source File: projects.py
View license
@login_required
def add(request):
  feed_repo_form = FeedRepositoryForm()
  cloned_repo_form = ClonedRepositoryForm()
  project_form = ProjectForm()
  blog_form = BlogForm()
  
  form_keys = {
    1: ('title', 'description', 'website', 'wiki'),
    2: ('web_url', 'clone_url', 'vcs', 'repo_rss', 'cmd'),
    3: ('url', 'rss')
  }
  
  if 'current' in request.POST:
    current = int(request.POST['current'])
  else:
    current = 0
  
  if current == 1:
    project_form = ProjectForm(request.POST)
    if not project_form.is_valid():
      current -= 1
  
  elif current == 2:
    if 'clone_url' in request.POST:
      cloned_repo_form = ClonedRepositoryForm(request.POST)
      if not cloned_repo_form.is_valid():
        current -= 1
    elif 'repo_rss' in request.POST:
      feed_repo_form = FeedRepositoryForm(request.POST)
      if not feed_repo_form.is_valid():
        current -= 1
  
  elif current == 3:
    blog_form = BlogForm(request.POST)
    if not ('url' not in request.POST or blog_form.is_valid()):
      current -= 1
  
  # go to the next form
  current += 1
  
  # if there are more parts to the form
  if current < 4:
    # remove the csrf token and current from a copy of the POST data
    post = request.POST.copy()
    if 'csrfmiddlewaretoken' in post:
      post.pop('csrfmiddlewaretoken')
      post.pop('current')

      # remove any of the keys that should be set on this form page
      for key in form_keys[current]:
        try:
          post.pop(key)
        except:
          pass
    
    return render_to_response('projects/add.html', {
        'parts': [1, 2, 3],
        'current': current,
        'previous_data': post,
        'cloned_repo_form': cloned_repo_form,
        'feed_repo_form': feed_repo_form,
        'project_form': project_form,
        'blog_form': blog_form,
        'js_page_id': 'add_project'
      }, context_instance = RequestContext(request))
  
  # otherwise, if the form is complete, create the project
  else:
    # validate and clean all forms
    project_form = ProjectForm(request.POST)
    cloned_repo_form = ClonedRepositoryForm(request.POST)
    feed_repo_form = FeedRepositoryForm(request.POST)
    blog_form = BlogForm(request.POST)
    
    for form in [project_form, cloned_repo_form, feed_repo_form, blog_form]:
      form.is_valid()
    
    # create the blog object
    if 'rss' in request.POST:
      blog = Blog(url = blog_form.cleaned_data['url'],
                  rss = blog_form.cleaned_data['rss'],
                  from_feed = True)
    else:
      blog = Blog(from_feed = False)
    blog.save()

    # create the repository object
    # if using google code removes read only addition
    # if [email protected] is mistakenly typed, git:// is placed in
    if 'clone_url' in request.POST:
      url = cloned_repo_form.cleaned_data['clone_url']
      gitfix = url.replace('[email protected]', 'git://')
      url = gitfix
      if "google.com" in url:
        split = url.split(' ')
        url = split[0]

      repo = Repository(web_url = cloned_repo_form.cleaned_data['web_url'],
                        clone_url = url,
                        from_feed = False)
    else:
      repo = Repository(web_url = feed_repo_form.cleaned_data['web_url'],
                        repo_rss = feed_repo_form.cleaned_data['repo_rss'],
                        from_feed = True)
    repo.save()

    # create the project object
    project = Project(title = project_form.cleaned_data['title'],
                      website = project_form.cleaned_data['website'],
                      wiki = project_form.cleaned_data['wiki'],
                      description = project_form.cleaned_data['description'],
                      active = True,
                      repository_id = repo.id,
                      blog_id = blog.id,
					  pending = True)

    # get the project a primary key
    project.save()

    # associate the current user with the project as an author
    project.authors.add(request.user)

    # save the project again
    project.save()

    # Set the active flag as true
    project.active = True

    # Save the project again
    project.save()

    # redirect to the show page for the new project
    return HttpResponseRedirect(reverse(show, args = (project.url_path,)))

Example 11

Project: Observatory
Source File: projects.py
View license
@login_required
def modify(request, project_url_path, tab_id = 1):
  # redirect if the url path is not in the correct format
  resp = force_url_paths(modify, project_url_path)
  if resp: return resp
  
  project = get_object_or_404(Project, url_path = project_url_path)
  screenshots = Screenshot.objects.filter(project = project)
  
  # if someone tries to edit a project they shouldn't be able to
  if not (request.user in project.authors.all() or request.user.info.mentor):
    return HttpResponseRedirect(reverse(show, args = (project.url_path,)))
  
  # default forms
  project_form = ProjectForm(instance = project)
  cloned_repo_form = ClonedRepositoryForm(instance = project.repository)
  feed_repo_form = FeedRepositoryForm(instance = project.repository)
  blog_form = BlogForm(instance = project.blog)
  screenshot_form = UploadScreenshotForm()
  
  # if changes should be saved or rejected
  if request.POST:
    # uploading a screenshot
    if 'screenshot_upload' in request.POST:
      form = UploadScreenshotForm(request.POST, request.FILES)
      if form.is_valid():
        Screenshot.create(form, request.FILES["file"], project)
      else:
        screenshot_form = form

    # wrote a post with the js overlay
    if 'title' in request.POST and 'markdown' in request.POST:
      from dashboard.views.blogs import create_post_real
      return create_post_real(request.POST)

    # editing the project's information
    elif 'title' in request.POST:
      form = ProjectForm(request.POST)
      
      # if the form is valid, save
      if form.is_valid():
        project.title = form.cleaned_data['title']
        project.website = form.cleaned_data['website']
        project.wiki = form.cleaned_data['wiki']
        project.description = form.cleaned_data['description']
        project.active = form.cleaned_data['active']
        project.save()
        project_form = ProjectForm(instance = project)
      
      # otherwise, display the errors
      else:
        project_form = form
    
    # editing a cloned repository
    elif 'clone_url' in request.POST:
      form = ClonedRepositoryForm(request.POST)
      
      if form.is_valid():
        project.repository.web_url = form.cleaned_data['web_url']
        project.repository.clone_url = form.cleaned_data['clone_url']
        project.repository.vcs = form.cleaned_data['vcs']
        project.repository.from_feed = False
        project.repository.save()
        cloned_repo_form = ClonedRepositoryForm(instance = project.repository)
      else:
        cloned_repo_form = form
    
    # editing a feed repository
    elif 'repo_rss' in request.POST:
      form = FeedRepositoryForm(request.POST)
      
      if form.is_valid():
        project.repository.repo_rss = form.cleaned_data['repo_rss']
        project.repository.cmd = form.cleaned_data['cmd']
        project.repository.web_url = form.cleaned_data['web_url']
        project.repository.from_feed = True
        project.repository.save()
        feed_repo_form = FeedRepositoryForm(instance = project.repository)
      else:
        feed_repo_form = form
    
    # editing a feed-based blog
    elif 'url' in request.POST:
      form = BlogForm(request.POST)
      
      if form.is_valid():
        project.blog.url = form.cleaned_data['url']
        project.blog.rss = form.cleaned_data['rss']
        project.blog.from_feed = True
        project.blog.save()
        blog_form = BlogForm(instance = project.blog)
      else:
        blog_form = form
    
    # switching to hosted blog
    elif 'switch-to-hosted' in request.POST:
      project.blog.from_feed = False
      project.blog.save()
      
  return render_to_response('projects/modify.html', {
    'project': project,
    'screenshots': screenshots,
    'project_form': project_form,
    'cloned_repo_form': cloned_repo_form,
    'feed_repo_form': feed_repo_form,
    'blog_form': blog_form,
    'screenshot_form': screenshot_form,
    'post_form': BlogPostForm(),
    'repo': project.repository,
    'tab': int(tab_id)
  }, context_instance = RequestContext(request))

Example 12

Project: classic.rhizome.org
Source File: views.py
View license
@login_required
def edit_profile(request): 
    context = RequestContext(request)
    rhizomeuser = request.user.get_profile()
    
    initial_list_data = [l.listid for l in Member.objects.filter(user=rhizomeuser, deleted = 0)]
    
    personal_info_form = EditPersonalInfoForm(instance=rhizomeuser)
    account_info_form = EditAccountInfoForm(instance=rhizomeuser)
    bio_form = EditBioForm(instance=rhizomeuser)
    add_info_form = EditAdditionalInfoForm(instance=rhizomeuser)
   
    try:
        address = rhizomeuser.address('billing')
        address_form = UserBillingAddressForm(instance=address)
    except:
        address_form = UserBillingAddressForm()
    
    set_password_form = SetPasswordForm(rhizomeuser)
    manage_email_form = ManageForm(request.POST or None, initial={'mailinglists':initial_list_data})
    ip_address = request.META.get('REMOTE_ADDR', 'unknown')
    updated = ''
    
    if request.method == 'POST': 
        response = ''           
        if request.POST['form'] == "personal_info":
            
            personal_info_form = EditPersonalInfoForm(request.POST or None, 
                    instance=rhizomeuser and RhizomeUser.objects.get(id=rhizomeuser.id))
            
            if personal_info_form.is_valid():
                rhizomeuser = personal_info_form.save()
                rhizomeuser.save()
                updated = "pass"
            else:
                updated = "fail" 
                
        if request.POST['form'] == "address_form":
            try:
                address_form = UserBillingAddressForm(request.POST or None, instance=address)        
            except:
                address_form = UserBillingAddressForm(request.POST or None)
            if address_form.is_valid():
                address_form.save(rhizomeuser)
                updated = "pass"
            else:
                updated = "fail" 
                          
        if request.POST['form'] == "bio":
            bio_form = EditBioForm(request.POST or None, 
                    instance=rhizomeuser and RhizomeUser.objects.get(id=rhizomeuser.id))        
            if bio_form.is_valid():
                rhizomeuser = bio_form.save()
                rhizomeuser.save()
                updated = "pass"
            else:
                updated = "fail" 
                
        if request.POST['form'] == "account_info":
            account_info_form = EditAccountInfoForm(request.POST or None, request.FILES or None, 
                    instance=rhizomeuser and RhizomeUser.objects.get(id=rhizomeuser.id))
            if account_info_form.is_valid():
                rhizomeuser = account_info_form.save()
                rhizomeuser.save()
                updated = "pass"
            else:
                updated = "fail" 
                        
        if request.POST['form'] == "set_password":
            set_password_form = SetPasswordForm(rhizomeuser,request.POST)
            if set_password_form.is_valid():
                rhizomeuser = set_password_form.save()
                rhizomeuser.save()
                updated = "pass"
            else:
                updated = "fail" 
                       
        if request.POST['form'] == "add_info":
            add_info_form = EditAdditionalInfoForm(request.POST or None, 
                    instance=rhizomeuser and RhizomeUser.objects.get(id=rhizomeuser.id))
            if add_info_form.is_valid():
                rhizomeuser = add_info_form.save()
                rhizomeuser.save()
                updated = "pass"
            else:
                updated = "fail" 
        
        if request.POST['form'] == "manage_email_form":   
            manage_email_form = ManageForm(request.POST)     
            if manage_email_form.is_valid():
                mailinglists = manage_email_form.cleaned_data['mailinglists']
                notice = manage_email_form.save(request, mailinglists)
                updated = "pass"
            else:
                updated = "fail"
        if updated == 'pass':
            moderator.process(rhizomeuser, request)
            return HttpResponseRedirect('/profiles/edit?updated=True')
    
    breadcrumb = (("Profiles", rhizomeuser.get_absolute_url()), ("Edit",None)) 
 
    if rhizomeuser.id == request.user.id:
        return render_to_response(
            "accounts/edit.html",
            {
            "rhizomeuser":rhizomeuser,
            "personal_info_form":personal_info_form,
            "account_info_form":account_info_form,
            "bio_form":bio_form,
            "add_info_form":add_info_form,
            "set_password_form":set_password_form,
            "manage_email_form":manage_email_form,
            "address_form":address_form,
            "updated": updated,
            "breadcrumb":breadcrumb,
            "today": datetime.datetime.now(),
            }, 
            context
            )
    else:
        return HttpResponseRedirect(reverse(profiles_list))

Example 13

Project: classic.rhizome.org
Source File: views.py
View license
@login_required  
def edit(request, type, id):
    context = RequestContext(request)
    username = request.user.get_profile()       
        
    #CHECK THE TYPE, GRAB OBJECT OR CATCH MISSING INFO
    if type == 'opportunities':
        announcement = get_object_or_404(Opportunity, id=id, is_spam=False)
        announcement_form = OpportunityForm(
                                request.POST or None, 
                                request.FILES or None, 
                                instance=announcement, 
                                initial={'username':username}
                            )
    elif type == 'jobs':
        announcement = get_object_or_404(Job, id=id, is_spam=False)
        announcement_form = JobForm(
                                request.POST or None, 
                                request.FILES or None, 
                                instance=announcement,  
                                initial={'username':username}
                                )
    elif type == 'events':
        announcement = get_object_or_404(Event, id=id, is_spam=False)
        announcement_form = EventForm(
                                request.POST or None, 
                                request.FILES or None, 
                                instance=announcement, 
                                initial={'username':username}
                            )
    else:
        raise Http404
    
    if not announcement.can_edit():
        # can only edit if announcement less than 2 wks old...    
        return HttpResponseRedirect(reverse('announce_index'))  
    else:
        # MAKE SURE THE USER OWNS THE ANNOUNCEMENT
        if request.user != announcement.user:
            return HttpResponseRedirect(reverse('announce_index'))  
        else:
            # HANDLE THE POST
            if request.method == 'POST':
            
                if request.POST.get("form-type") == "opportunity-form":
                    announcement_form = OpportunityForm(
                                            request.POST, 
                                            request.FILES or None, 
                                            instance=announcement, 
                                            initial={'username':username}
                                        )
                if request.POST.get("form-type") == "job-form":
                    announcement_form = JobForm(
                                            request.POST, 
                                            request.FILES or None, 
                                            instance=announcement, 
                                            initial={'username':username}
                                        )
                if request.POST.get("form-type") == "event-form":  
                    announcement_form = EventForm(
                                            request.POST, 
                                            request.FILES or None, 
                                            instance=announcement, 
                                            initial={'username':username}
                                            )
           
                if announcement_form.is_valid():
                    announcement = announcement_form.save(commit=False)
                    announcement.user_id = request.user.id
                    announcement.ip_address = request.META["REMOTE_ADDR"]
                    
                    if request.POST.get("delete_image"):
                        if announcement.image:
                            import os
                            if os.path.exists(announcement.image.path):
                                os.remove(announcement.image.path)
                        announcement.image = None
                    
                    #save now so can create thumbanail with id in title
                    announcement.save() 
                    
                    if announcement.image and not announcement.thumbnail:
                        announcement.thumbnail = create_thumbnail(announcement.image)
                        announcement.save()           
                    
                    ####
                    # if announcement is not yet published
                    ####
                    if request.POST.get("status") == "preview":
                        announcement.status = False
                        announcement.save()
                        return HttpResponseRedirect(reverse(preview, kwargs={'type':type, 'id':announcement.id}))                    
                        
                    if request.POST.get("status") == "publish":

                        if type == 'jobs' and not announcement.is_paid() and not request.user.get_profile().is_member():
                            return HttpResponseRedirect(reverse(job_payment))

                        if not moderator.process(announcement, request):
                            announcement.status = True
                            announcement.save()
                            send_to_announce_mailing_list(announcement.__class__, announcement, created=True)
 
                        return HttpResponseRedirect(reverse(thanks, kwargs={'type':type,'id':announcement.id}))

                    
                    ####
                    # if announcement is published
                    ####
                    if request.POST.get("status") == "unpublish":
                        announcement.status = False
                        announcement.save()
                        #return HttpResponseRedirect('/announce/%s/%s/preview/' % (type, announcement.id))
                        return HttpResponseRedirect(reverse(edit,kwargs={'type':type,'id':announcement.id}))

                    if request.POST.get("status") == "update":
                        moderator.process(announcement, request)
                            
                        #return HttpResponseRedirect('/announce/%s/%s/preview/' % (type, announcement.id))
                        return HttpResponseRedirect(reverse(thanks,kwargs={'type':type,'id':announcement.id}))
                
                    else:
                        if type == 'opportunities':   
                            announcement_form = OpportunityForm(request.POST)
                        if type == 'jobs':   
                            announcement_form = JobForm(request.POST)
                        if type == 'events':   
                            announcement_form = EventForm(request.POST)       
        
        return render_to_response(
            "announce/submit.html",
            {"announcement_form":announcement_form,
            "type": type  
            }, 
            context
            )

Example 14

Project: django-facebookconnect
Source File: views.py
View license
def setup(request,redirect_url=None,
          registration_form_class=FacebookUserCreationForm,
          template_name='facebook/setup.html',
          extra_context=None):
    """
    setup
    ===============================
    
    Handles a new facebook user. There are three ways to setup a new facebook user.
     1. Link the facebook account with an existing django account.
     2. Create a dummy django account to attach to facebook. The user must always use
        facebook to login.
     3. Ask the user to create a new django account
     
    The built in template presents the user with all three options. Once setup is 
    complete the user will get redirected. The url used in the following order of 
    presidence:

      1. whatever url is in the 'next' get parameter passed to the setup url
      2. whatever url is passed to the setup view when the url is defined
      3. whatever url is defined in the LOGIN_REDIRECT_URL setting directive
    
    If you define a url to use this view, you can pass the following parameters:
     * redirect_url: Defines where to send the user after they are setup. This
                     can get overridden by the url in the 'next' get param passed on 
                     the url.
     * registration_form_class: Django form class to use for new user way #3 explained
                                above. The form should create a new user.
     * template_name: Template to use. Uses 'facebook/setup.html' by default.
     * extra_context: A context object whose contents will be passed to the template.
    """
    log.debug('in setup view')
    #you need to be logged into facebook.
    if not request.facebook.uid:
        log.debug('Need to be logged into facebook')
        url = reverse(facebook_login)
        if request.REQUEST.get(REDIRECT_FIELD_NAME,False):
            url += "?%s=%s" % (REDIRECT_FIELD_NAME, request.REQUEST[REDIRECT_FIELD_NAME])
        return HttpResponseRedirect(url)

    #setup forms
    login_form = AuthenticationForm()
    registration_form = registration_form_class()

    #figure out where to go after setup
    if request.REQUEST.get(REDIRECT_FIELD_NAME,False):
        redirect_url = request.REQUEST[REDIRECT_FIELD_NAME]
    elif redirect_url is None:
        redirect_url = getattr(settings, "LOGIN_REDIRECT_URL", "/")

    #check that this fb user is not already in the system
    try:
        FacebookProfile.objects.get(facebook_id=request.facebook.uid)
        # already setup, move along please
        return HttpResponseRedirect(redirect_url)
    except FacebookProfile.DoesNotExist, e:
        # not in the db, ok to continue
        pass

    #user submitted a form - which one?
    if request.method == "POST":
        log.debug('Submitted form')
        #lets setup a facebook only account. The user will have to use
        #facebook to login.
        if request.POST.get('facebook_only',False):
            log.debug('Facebook Only')
            profile = FacebookProfile(facebook_id=request.facebook.uid)
            user = User(username=request.facebook.uid,
                        email=profile.email)
            user.set_unusable_password()
            user.save()
            profile.user = user
            profile.save()
            log.info("Added user and profile for %s!" % request.facebook.uid)
            user = authenticate(request=request)
            login(request, user)
            return HttpResponseRedirect(redirect_url)
        
        # user setup his/her own local account in addition to their facebook
        # account. The user will have to login with facebook unless they 
        # reset their password.
        elif request.POST.get('register',False):
            log.debug('Register a new account')
            profile = FacebookProfile(facebook_id=request.facebook.uid)
            if profile.first_name != "(Private)":
                fname = profile.first_name
            if profile.last_name != "(Private)":
                lname = profile.last_name
            user = User(first_name=fname, last_name=lname)
            registration_form = registration_form_class(
                                        data=request.POST, instance=user)
            if registration_form.is_valid():
                user = registration_form.save()
                profile.user = user
                profile.save()
                log.info("Added user and profile for %s!" % request.facebook.uid)
                login(request, authenticate(request=request))
                return HttpResponseRedirect(redirect_url)
            else:
                request.user = User()
                request.user.facebook_profile = FacebookProfile(facebook_id=request.facebook.uid)
    
        #user logs in in with an existing account, and the two are linked.
        elif request.POST.get('login',False):
            login_form = AuthenticationForm(data=request.POST)

            if login_form.is_valid():
                user = login_form.get_user()
                log.debug("Trying to setup FB: %s, %s" % (user,request.facebook.uid))
                if user and user.is_active:
                    FacebookProfile.objects.get_or_create(user=user, facebook_id=request.facebook.uid)
                    log.info("Attached facebook profile %s to user %s!" % (request.facebook.uid, user))
                    login(request, user)
                    return HttpResponseRedirect(redirect_url)
            else:
                request.user = User()
                request.user.facebook_profile = FacebookProfile(facebook_id=request.facebook.uid)
    
    #user didn't submit a form, but is logged in already. We'll just link up their facebook
    #account automatically.
    elif request.user.is_authenticated():
        log.debug('Already logged in')
        try:
            request.user.facebook_profile
        except FacebookProfile.DoesNotExist:
            profile = FacebookProfile(facebook_id=request.facebook.uid)
            profile.user = request.user
            profile.save()
            log.info("Attached facebook profile %s to user %s!" % (profile.facebook_id,profile.user))

        return HttpResponseRedirect(redirect_url)
    
    # user just showed up
    else:
        log.debug('Setting up form...')
        request.user.facebook_profile = profile = FacebookProfile(facebook_id=request.facebook.uid)
        login_form = AuthenticationForm(request)
        log.debug('creating a dummy user')
        fname = lname = ''
        if profile.first_name != "(Private)":
            fname = profile.first_name
        if profile.last_name != "(Private)":
            lname = profile.last_name
        user = User(first_name=fname, last_name=lname)
        registration_form = registration_form_class(instance=user)
    
    log.debug('going all the way...')
    
    # add the extra_context to this one
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value

    template_dict = {
        "login_form":login_form,
        "registration_form":registration_form
    }
    
    # we only need to set next if its been passed in the querystring or post vars
    if request.REQUEST.get(REDIRECT_FIELD_NAME, False):
        template_dict.update( {REDIRECT_FIELD_NAME: request.REQUEST[REDIRECT_FIELD_NAME]})
        
    return render_to_response(
        template_name,
        template_dict,
        context_instance=context)

Example 15

Project: scielo-manager
Source File: tests_helpers.py
View license
    def test_POST_valid_formdata_do_log(self):
        # with:
        perm_journal_change = _makePermission(perm='change_journal', model='journal', app_label='journalmanager')
        perm_journal_list = _makePermission(perm='list_journal', model='journal', app_label='journalmanager')
        self.user.user_permissions.add(perm_journal_change)
        self.user.user_permissions.add(perm_journal_list)

        sponsor = jm_modelfactories.SponsorFactory.create()
        use_license = jm_modelfactories.UseLicenseFactory.create()
        language = jm_modelfactories.LanguageFactory.create()
        subject_category = jm_modelfactories.SubjectCategoryFactory.create()
        study_area = jm_modelfactories.StudyAreaFactory.create()

        form = self.app.get(reverse('journal.add'), user=self.user).forms['journal-form']
        form['journal-sponsor'] = [sponsor.pk]
        form['journal-study_areas'] = [study_area.pk]
        form['journal-ctrl_vocabulary'] = 'decs'
        form['journal-frequency'] = 'Q'
        form['journal-final_num'] = ''
        form['journal-eletronic_issn'] = '0102-6720'
        form['journal-init_vol'] = '1'
        form['journal-title'] = u'ABCD. Arquivos Brasileiros de Cirurgia Digestiva (São Paulo)'
        form['journal-title_iso'] = u'ABCD. Arquivos B. de C. D. (São Paulo)'
        form['journal-short_title'] = u'ABCD.(São Paulo)'
        form['journal-editorial_standard'] = 'vancouv'
        form['journal-scielo_issn'] = 'print'
        form['journal-init_year'] = '1986'
        form['journal-acronym'] = 'ABCD'
        form['journal-pub_level'] = 'CT'
        form['journal-init_num'] = '1'
        form['journal-final_vol'] = ''
        form['journal-subject_descriptors'] = 'MEDICINA, CIRURGIA, GASTROENTEROLOGIA, GASTROENTEROLOGIA'
        form['journal-print_issn'] = '0102-6720'
        form['journal-copyrighter'] = 'Texto do copyrighter'
        form['journal-publisher_name'] = 'Colégio Brasileiro de Cirurgia Digestiva'
        form['journal-publisher_country'] = 'BR'
        form['journal-publisher_state'] = 'SP'
        form['journal-publication_city'] = 'São Paulo'
        form['journal-editor_name'] = 'Colégio Brasileiro de Cirurgia Digestiva'
        form['journal-editor_address'] = 'Av. Brigadeiro Luiz Antonio, 278 - 6° - Salas 10 e 11'
        form['journal-editor_address_city'] = 'São Paulo'
        form['journal-editor_address_state'] = 'SP'
        form['journal-editor_address_zip'] = '01318-901'
        form['journal-editor_address_country'] = 'BR'
        form['journal-editor_phone1'] = '(11) 3288-8174'
        form['journal-editor_phone2'] = '(11) 3289-0741'
        form['journal-editor_email'] = '[email protected]'
        form['journal-use_license'] = use_license.pk
        form['journal-languages'] = [language.pk]
        form['journal-abstract_keyword_languages'] = [language.pk]
        form.set('journal-subject_categories', [str(subject_category.pk),])
        form['journal-is_indexed_scie'] = True
        form['journal-is_indexed_ssci'] = False
        form['journal-is_indexed_aehci'] = True

        # when:
        response = form.submit().follow()

        # then:
        self.assertIn('Saved.', response.body)
        self.assertIn('ABCD.(São Paulo)', response.body)
        self.assertTemplateUsed(response, 'journalmanager/journal_dash.html')

        self.assertEqual(audit_models.AuditLogEntry.objects.count(), 1)
        log_entry = audit_models.AuditLogEntry.objects.all()[0]
        audited_object = log_entry.get_audited_object()
        # inspect audited log entry data:
        self.assertEqual(log_entry.action_flag, audit_models.ADDITION)
        self.assertEqual(log_entry.object_id, unicode(audited_object.pk))
        self.assertEqual(log_entry.content_type, ContentType.objects.get_for_model(audited_object))
        self.assertEqual(log_entry.old_values, None)
        self.assertEqual(log_entry.user, self.user)

        fields_edited = [
            'sponsor',
            'use_license',
            'languages',
            'abstract_keyword_languages',
            'subject_categories',
            'study_areas',
            'title',
            'title_iso',
            'short_title',
            'acronym',
            'scielo_issn',
            'print_issn',
            'eletronic_issn',
            'subject_descriptors',
            'init_year',
            'init_vol',
            'init_num',
            'frequency',
            'editorial_standard',
            'ctrl_vocabulary',
            'pub_level',
            'copyrighter',
            'editor_name',
            'editor_address',
            'editor_address_city',
            'editor_address_state',
            'editor_address_zip',
            'editor_address_country',
            'editor_phone1',
            'editor_phone2',
            'editor_email',
            'publisher_name',
            'publisher_country',
            'publisher_state',
            'publication_city',
            'is_indexed_scie',
            'is_indexed_aehci',
        ]

        self.assertEqual(log_entry.new_values.keys(), [u'form_data', u'formsets_data'])
        for field_edited in fields_edited:
            # all edited fields are in "new_values"-dict
            self.assertIn(field_edited, log_entry.new_values['form_data'].keys())
            # all edited fields are in the "change message" field
            self.assertIn(field_edited, log_entry.change_message)

        # compare form data and stored new_values data
        for k,v in log_entry.new_values['form_data'].iteritems():
            form_value = form['journal-%s' % k].value
            self.assertEqual(log_entry.new_values['form_data'][k], force_unicode(v))

Example 16

Project: django-dbsettings
Source File: tests.py
View license
    def test_forms(self):
        "Forms should display only the appropriate settings"
        from django.contrib.auth.models import User, Permission
        from django.core.urlresolvers import reverse

        site_form = reverse(views.site_settings)

        # Set up a users to test the editor forms
        user = User.objects.create_user('dbsettings', '', 'dbsettings')

        # Check named url
        site_form = reverse('site_settings')

        # First test without any authenticated user
        response = self.client.get(site_form)
        self.assertLoginFormShown(response)

        # Then test a standard non-staff user
        self.client.login(username='dbsettings', password='dbsettings')
        response = self.client.get(site_form)
        self.assertLoginFormShown(response)

        # Add staff status, but no settings permissions
        user.is_staff = True
        user.save()

        # Test the site-wide settings editor
        response = self.client.get(site_form)
        self.assertTemplateUsed(response, 'dbsettings/site_settings.html')
        self.assertEqual(response.context[0]['title'], 'Site settings')
        # No settings should show up without proper permissions
        self.assertEqual(len(response.context[0]['form'].fields), 0)

        # Add permissions so that settings will show up
        perm = Permission.objects.get(codename='can_edit_editable_settings')
        user.user_permissions.add(perm)

        # Check if verbose_name appears
        response = self.client.get(site_form)
        self.assertContains(response, 'Verbose name')

        # Erroneous submissions should be caught by newforms
        data = {
            '%s__Editable__integer' % MODULE_NAME: '3.5',
            '%s__Editable__string' % MODULE_NAME: '',
            '%s__Editable__list_semi_colon' % MODULE_NAME: '',
            '%s__Editable__list_comma' % MODULE_NAME: '',
            '%s__Editable__date' % MODULE_NAME: '3-77-99',
            '%s__Editable__time' % MODULE_NAME: 'abc',
            '%s__Editable__datetime' % MODULE_NAME: '',
        }
        response = self.client.post(site_form, data)
        self.assertFormError(response, 'form', '%s__Editable__integer' % MODULE_NAME,
                             'Enter a whole number.')
        self.assertFormError(response, 'form', '%s__Editable__string' % MODULE_NAME,
                             'This field is required.')
        self.assertFormError(response, 'form', '%s__Editable__list_semi_colon' % MODULE_NAME,
                             'This field is required.')
        self.assertFormError(response, 'form', '%s__Editable__list_comma' % MODULE_NAME,
                             'This field is required.')
        self.assertFormError(response, 'form', '%s__Editable__date' % MODULE_NAME,
                             'Enter a valid date.')
        self.assertFormError(response, 'form', '%s__Editable__time' % MODULE_NAME,
                             'Enter a valid time.')
        self.assertFormError(response, 'form', '%s__Editable__datetime' % MODULE_NAME,
                             'This field is required.')

        # Successful submissions should redirect
        data = {
            '%s__Editable__integer' % MODULE_NAME: '4',
            '%s__Editable__string' % MODULE_NAME: 'Success!',
            '%s__Editable__list_semi_colon' % MODULE_NAME: '[email protected];[email protected]',
            '%s__Editable__list_comma' % MODULE_NAME: '[email protected],[email protected]',
            '%s__Editable__date' % MODULE_NAME: '2012-06-28',
            '%s__Editable__time' % MODULE_NAME: '16:37:45',
            '%s__Editable__datetime' % MODULE_NAME: '2012-06-28 16:37:45',
        }
        response = self.client.post(site_form, data)
        self.assertRedirects(response, site_form)

        # And the data submitted should be immediately available in Python
        self.assertEqual(Editable.settings.integer, 4)
        self.assertEqual(Editable.settings.string, 'Success!')
        self.assertEqual(Editable.settings.list_semi_colon, ['[email protected]', '[email protected]'])
        self.assertEqual(Editable.settings.list_comma, ['[email protected]', '[email protected]'])
        self.assertEqual(Editable.settings.date, datetime.date(2012, 6, 28))
        self.assertEqual(Editable.settings.time, datetime.time(16, 37, 45))
        self.assertEqual(Editable.settings.datetime, datetime.datetime(2012, 6, 28, 16, 37, 45))

        # Check if module level settings show properly
        self._test_form_fields(site_form, 8, False)
        # Add perm for whole app
        perm = Permission.objects.get(codename='can_edit__settings')  # module-level settings
        user.user_permissions.add(perm)
        self._test_form_fields(site_form, 18)
        # Remove other perms - left only global perm
        perm = Permission.objects.get(codename='can_edit_editable_settings')
        user.user_permissions.remove(perm)
        self._test_form_fields(site_form, 10)

Example 17

Project: seantis-questionnaire
Source File: views.py
View license
@commit_on_success
def questionnaire(request, runcode=None, qs=None):
    """
    Process submitted answers (if present) and redirect to next page

    If this is a POST request, parse the submitted data in order to store
    all the submitted answers.  Then return to the next questionset or
    return a completed response.

    If this isn't a POST request, redirect to the main page.

    We only commit on success, to maintain consistency.  We also specifically
    rollback if there were errors processing the answers for this questionset.
    """
    if use_session:
        session_runcode = request.session.get('runcode', None)
        if session_runcode is not None:
            runcode = session_runcode

        session_qs = request.session.get('qs', None)
        if session_qs is not None:
            qs = session_qs

    # if runcode provided as query string, redirect to the proper page
    if not runcode:
        runcode = request.GET.get('runcode')
        if not runcode:
            return HttpResponseRedirect("/")
        else:
            if not use_session:
                args = [runcode, ]
            else:
                request.session['runcode'] = runcode
                args = []
            return HttpResponseRedirect(reverse("questionnaire", args=args))

    runinfo = get_runinfo(runcode)

    if not runinfo:
        transaction.commit()
        return HttpResponseRedirect('/')

    # let the runinfo have a piggy back ride on the request
    # so we can easily use the runinfo in places like the question processor
    # without passing it around
    request.runinfo = runinfo

    if not qs:
        # Only change the language to the subjects choice for the initial
        # questionnaire page (may be a direct link from an email)
        if hasattr(request, 'session'):
            request.session['django_language'] = runinfo.subject.language
            translation.activate(runinfo.subject.language)

    if 'lang' in request.GET:
        return set_language(request, runinfo, request.path)

    # --------------------------------
    # --- Handle non-POST requests ---
    # --------------------------------

    if request.method != "POST":
        if qs is not None:
            qs = get_object_or_404(QuestionSet, sortid=qs, questionnaire=runinfo.questionset.questionnaire)
            if runinfo.random.startswith('test:'):
                pass # ok for testing
            elif qs.sortid > runinfo.questionset.sortid:
                # you may jump back, but not forwards
                return redirect_to_qs(runinfo, request)
            runinfo.questionset = qs
            runinfo.save()
            transaction.commit()
        # no questionset id in URL, so redirect to the correct URL
        if qs is None:
            return redirect_to_qs(runinfo, request)
        questionset_start.send(sender=None, runinfo=runinfo, questionset=qs)
        return show_questionnaire(request, runinfo)

    # -------------------------------------
    # --- Process POST with QuestionSet ---
    # -------------------------------------

    # if the submitted page is different to what runinfo says, update runinfo
    # XXX - do we really want this?
    qs = request.POST.get('questionset_id', qs)
    try:
        qsobj = QuestionSet.objects.filter(pk=qs)[0]
        if qsobj.questionnaire == runinfo.questionset.questionnaire:
            if runinfo.questionset != qsobj:
                runinfo.questionset = qsobj
                runinfo.save()
    except:
        pass

    questionnaire = runinfo.questionset.questionnaire
    questionset = runinfo.questionset

    # to confirm that we have the correct answers
    expected = questionset.questions()

    items = request.POST.items()
    extra = {} # question_object => { "ANSWER" : "123", ... }

    # this will ensure that each question will be processed, even if we did not receive
    # any fields for it. Also works to ensure the user doesn't add extra fields in
    for x in expected:
        items.append( (u'question_%s_Trigger953' % x.number, None) )

    # generate the answer_dict for each question, and place in extra
    for item in items:
        key, value = item[0], item[1]
        if key.startswith('question_'):
            answer = key.split("_", 2)
            question = get_question(answer[1], questionnaire)
            if not question:
                logging.warn("Unknown question when processing: %s" % answer[1])
                continue
            extra[question] = ans = extra.get(question, {})
            if(len(answer) == 2):
                ans['ANSWER'] = value
            elif(len(answer) == 3):
                ans[answer[2]] = value
            else:
                logging.warn("Poorly formed form element name: %r" % answer)
                continue
            extra[question] = ans

    errors = {}
    for question, ans in extra.items():
        if not question_satisfies_checks(question, runinfo):
            continue
        if u"Trigger953" not in ans:
            logging.warn("User attempted to insert extra question (or it's a bug)")
            continue
        try:
            cd = question.getcheckdict()
            # requiredif is the new way
            depon = cd.get('requiredif',None) or cd.get('dependent',None)
            if depon:
                depparser = BooleanParser(dep_check, runinfo, extra)
                if not depparser.parse(depon):
                    # if check is not the same as answer, then we don't care
                    # about this question plus we should delete it from the DB
                    delete_answer(question, runinfo.subject, runinfo.runid)
                    if cd.get('store', False):
                        runinfo.set_cookie(question.number, None)
                    continue
            add_answer(runinfo, question, ans)
            if cd.get('store', False):
                runinfo.set_cookie(question.number, ans['ANSWER'])
        except AnswerException, e:
            errors[question.number] = e
        except Exception:
            logging.exception("Unexpected Exception")
            transaction.rollback()
            raise

    if len(errors) > 0:
        res = show_questionnaire(request, runinfo, errors=errors)
        transaction.rollback()
        return res

    questionset_done.send(sender=None,runinfo=runinfo,questionset=questionset)

    next = questionset.next()
    while next and not questionset_satisfies_checks(next, runinfo):
        next = next.next()
    runinfo.questionset = next
    runinfo.save()
    if use_session:
        request.session['prev_runcode'] = runinfo.random

    if next is None: # we are finished
        return finish_questionnaire(request, runinfo, questionnaire)

    transaction.commit()
    return redirect_to_qs(runinfo, request)

Example 18

Project: seantis-questionnaire
Source File: views.py
View license
def show_questionnaire(request, runinfo, errors={}):
    """
    Return the QuestionSet template

    Also add the javascript dependency code.
    """

    request.runinfo = runinfo
    if request.GET.get('show_all') == '1': # for debugging purposes.
        questions = runinfo.questionset.questionnaire.questions()
    else:
        questions = runinfo.questionset.questions()

    show_all = request.GET.get('show_all') == '1' # for debugging purposes in some cases we may want to show all questions on one screen.
    questionset = runinfo.questionset
    questions = questionset.questionnaire.questions() if show_all else questionset.questions()

    qlist = []
    jsinclude = []      # js files to include
    cssinclude = []     # css files to include
    jstriggers = []
    qvalues = {}

    # initialize qvalues
    cookiedict = runinfo.get_cookiedict()

    for k,v in cookiedict.items():
        qvalues[k] = v

    substitute_answer(qvalues, runinfo.questionset)

    for question in questions:
        # if we got here the questionset will at least contain one question
        # which passes, so this is all we need to check for
        question_visible = question_satisfies_checks(question, runinfo) or show_all

        Type = question.get_type()
        _qnum, _qalpha = split_numal(question.number)

        qdict = {
            'css_style': '' if question_visible else 'display:none;',
            'template' : 'questionnaire/%s.html' % (Type),
            'qnum' : _qnum,
            'qalpha' : _qalpha,
            'qtype' : Type,
            'qnum_class' : (_qnum % 2 == 0) and " qeven" or " qodd",
            'qalpha_class' : _qalpha and (ord(_qalpha[-1]) % 2 \
                                          and ' alodd' or ' aleven') or '',
        }

        # substitute answer texts
        substitute_answer(qvalues, question)

        # add javascript dependency checks
        cd = question.getcheckdict()
        depon = cd.get('requiredif',None) or cd.get('dependent',None)
        if depon:
            # extra args to BooleanParser are not required for toString
            parser = BooleanParser(dep_check)
            qdict['checkstring'] = ' checks="%s"' % parser.toString(depon)
            jstriggers.append('qc_%s' % question.number)
        if 'default' in cd and not question.number in cookiedict:
            qvalues[question.number] = cd['default']
        if Type in QuestionProcessors:
            qdict.update(QuestionProcessors[Type](request, question))
            if 'jsinclude' in qdict:
                if qdict['jsinclude'] not in jsinclude:
                    jsinclude.extend(qdict['jsinclude'])
            if 'cssinclude' in qdict:
                if qdict['cssinclude'] not in cssinclude:
                    cssinclude.extend(qdict['jsinclude'])
            if 'jstriggers' in qdict:
                jstriggers.extend(qdict['jstriggers'])
            if 'qvalue' in qdict and not question.number in cookiedict:
                qvalues[question.number] = qdict['qvalue']

        qlist.append( (question, qdict) )

    try:
        has_progress = settings.QUESTIONNAIRE_PROGRESS in ('async', 'default')
        async_progress = settings.QUESTIONNAIRE_PROGRESS == 'async'
    except AttributeError:
        has_progress = True
        async_progress = False

    if has_progress:
        if async_progress:
            progress = cache.get('progress' + runinfo.random, 1)
        else:
            progress = get_progress(runinfo)
    else:
        progress = 0

    if request.POST:
        for k,v in request.POST.items():
            if k.startswith("question_"):
                s = k.split("_")
                if len(s) == 4:
                    qvalues[s[1]+'_'+v] = '1' # evaluates true in JS
                elif len(s) == 3 and s[2] == 'comment':
                    qvalues[s[1]+'_'+s[2]] = v
                else:
                    qvalues[s[1]] = v

    if use_session:
        prev_url = reverse('redirect_to_prev_questionnaire')
    else:
        prev_url = 'javascript:history.back();'
    r = r2r("questionnaire/questionset.html", request,
        questionset=runinfo.questionset,
        runinfo=runinfo,
        errors=errors,
        qlist=qlist,
        progress=progress,
        triggers=jstriggers,
        qvalues=qvalues,
        jsinclude=jsinclude,
        cssinclude=cssinclude,
        async_progress=async_progress,
        async_url=reverse('progress', args=[runinfo.random]),
        prev_url=prev_url,
    )
    r['Cache-Control'] = 'no-cache'
    r['Expires'] = "Thu, 24 Jan 1980 00:00:00 GMT"
    return r

Example 19

Project: coursys
Source File: importer.py
View license
@transaction.atomic
def import_semester_info(verbose=False, dry_run=False, long_long_ago=False, bootstrap=False):
    """
    Update information on Semester objects from SIMS

    Finding the reference is tricky. Try Googling 'sfu calendar {{year}} "academic dates"'

    long_long_ago: import from the beginning of time
    bootstrap: don't assume Semester.current() will work, for bootstrapping test data creation
    """
    output = []
    semester_start = semester_first_day()
    semester_end = semester_last_day()
    sims_holidays = [(datetime.datetime.strptime(d, "%Y-%m-%d").date(), h) for d,h in all_holidays()]

    if not bootstrap:
        # we want semesters 5 years into the future: that's a realistic max horizon for grad promises
        current = Semester.current()
        strms = [current.offset_name(i) for i in range(15)]
    else:
        strms = []

    if long_long_ago:
        strms = sorted(list(set(strms) | set(semester_start.keys())))
    semesters = dict((s.name, s) for s in Semester.objects.filter(name__in=strms))

    semester_weeks = itertools.groupby(
                SemesterWeek.objects.filter(semester__name__in=strms).select_related('semester'),
                lambda sw: sw.semester.name)
    semester_weeks = dict((k,list(v)) for k,v in semester_weeks)

    holidays = itertools.groupby(
                Holiday.objects.filter(semester__name__in=strms, holiday_type='FULL').select_related('semester'),
                lambda h: h.semester.name)
    holidays = dict((k,list(v)) for k,v in holidays)

    for strm in strms:
        url = settings.BASE_ABS_URL + reverse('coredata.views.edit_semester', kwargs={'semester_name': strm})

        # Semester object
        try:
            semester = semesters[strm]
        except KeyError:
            semester = Semester(name=strm)
            semesters[strm] = semester
            output.append("Creating %s." % (strm,))

        # class start and end dates
        try:
            start = datetime.datetime.strptime(semester_start[strm], "%Y-%m-%d").date()
        except KeyError:
            # No data found about this semester: if there's a date already around, honour it
            # Otherwise, guess "same day as this semester last year" which is probably wrong but close.
            start = semester.start
            if not semester.start:
                lastyr = semesters[semester.offset_name(-3)]
                start = lastyr.start.replace(year=lastyr.start.year+1)
                output.append("Guessing start date for %s." % (strm,))

        try:
            end = datetime.datetime.strptime(semester_end[strm], "%Y-%m-%d").date()
        except KeyError:
            # no classes scheduled yet? Assume 13 weeks exactly
            end = start + datetime.timedelta(days=91)

        if semester.start != start:
            output.append("Changing start date for %s from %s to %s." % (strm, semester.start, start))
            semester.start = start
        if semester.end != end:
            output.append("Changing end date for %s from %s to %s." % (strm, semester.end, end))
            semester.end = end

        if not dry_run:
            semester.save()

        # SemesterWeeks
        weeks = semester_weeks.get(strm, [])
        if not weeks:
            sw = SemesterWeek(semester=semester, week=1, monday=first_monday(start))
            weeks.append(sw)
            assert sw.monday.weekday() == 0
            output.append("Creating week 1 for %s on %s." % (strm, sw.monday))
            if not dry_run:
                sw.save()
        elif weeks[0].monday != first_monday(start):
            sw = weeks[0]
            sw.monday = first_monday(start)
            output.append("Changing first Monday of %s to %s." % (strm, sw.monday))
            if not dry_run:
                sw.save()

        length = semester.end - semester.start
        if not bootstrap and length > datetime.timedelta(days=92) and len(weeks) < 2 \
                and semester.start - datetime.date.today() < datetime.timedelta(days=365):
            # semester is longer than 13 weeks: insist that the user specify reading week reasonably-soon before the semester starts
            message = "Semester %s is long (%s) but has no reading week specified. Please have a look here: %s\n\nYou probably want to enter the Monday of week 5/6/7/8 as the Monday after reading week, a week later than it would otherwise be." % (strm, length, url)
            if verbose:
                output.append('*** ' + message)
            else:
                import_admin_email(source='coredata.importer.import_semester_info', message=message)
        elif not bootstrap:
            # also check that the last day of classes is at a coherent time. Might reveal problems with reading week specification.
            endweek,_ = semester.week_weekday(semester.end, weeks=weeks)
            if endweek not in [12, 13, 14]:
                message = "Semester %s ends in week %i (should be 13 or 14). That's weird. Have a look here to see if things are coherent: %s" % (strm, endweek, url)
                if verbose:
                    output.append('*** ' + message)
                else:
                    import_admin_email(source='coredata.importer.import_semester_info', message=message)

        # Holidays
        hs = holidays.get(strm, [])
        h_start, h_end = Semester.start_end_dates(semester)
        for dt, desc in [(d,h) for d,h in sims_holidays if h_start <= d <= h_end]:
            existing = [h for h in hs if h.date == dt]
            if existing:
                holiday = existing[0]
            else:
                holiday = Holiday(semester=semester, date=dt, holiday_type='FULL')
                output.append("Adding holiday %s on %s." % (desc, dt))

            holiday.description = desc
            if not dry_run:
                holiday.save()



    if verbose:
        print '\n'.join(output)

Example 20

Project: coursys
Source File: views.py
View license
def _edit_pagefile(request, course_slug, page_label, kind):
    """
    View to create and edit pages
    """
    if request.method == 'POST' and 'delete' in request.POST and request.POST['delete'] == 'yes':
        return _delete_pagefile(request, course_slug, page_label, kind)
    with django.db.transaction.atomic():
        offering = get_object_or_404(CourseOffering, slug=course_slug)
        if page_label:
            page = get_object_or_404(Page, offering=offering, label=page_label)
            version = page.current_version()
            member = _check_allowed(request, offering, page.can_write, page.editdate())
            old_label = page.label
        else:
            page = None
            version = None
            member = _check_allowed(request, offering, offering.page_creators()) # users who can create pages
            old_label = None

        if isinstance(member, PagePermission):
            return ForbiddenResponse(request, 'Editing of pages by additional-permission holders is not implemented. Sorry')

        # make sure we're looking at the right "kind" (page/file)
        if not kind:
            kind = "file" if version.is_filepage() else "page"

        # get the form class we need
        if kind == "page":
            Form = EditPageForm
        else:
            Form = EditFileForm
        
        # check that we have an allowed member of the course (and can continue)
        if not member:
            return ForbiddenResponse(request, 'Not allowed to edit/create this '+kind+'.')
        restricted = False
        if member.role == 'STUD':
            # students get the restricted version of the form
            Form = Form.restricted_form
            restricted = True
        
        if request.method == 'POST':
            form = Form(instance=page, offering=offering, data=request.POST, files=request.FILES)
            if form.is_valid():
                instance = form.save(editor=member)
                
                # clean up weirdness from restricted form
                if 'label' not in form.cleaned_data:
                    # happens when student edits an existing page
                    instance.label = page.label
                if 'can_write' not in form.cleaned_data:
                    # happens only when students create a page
                    instance.can_write = 'STUD'
                
                if not restricted and 'releasedate' in form.cleaned_data:
                    instance.set_releasedate(form.cleaned_data['releasedate'])
                elif not restricted:
                    instance.set_releasedate(None)

                if not restricted and 'editdate' in form.cleaned_data:
                    instance.set_editdate(form.cleaned_data['editdate'])
                elif not restricted:
                    instance.set_editdate(None)

                instance.redirect = None

                if old_label and old_label != instance.label:
                    # page has been moved to a new URL: leave a redirect in its place
                    redir_page = Page(offering=instance.offering, label=old_label,
                                      can_read=instance.can_read, can_write=offering.page_creators())
                    redir_page.set_releasedate(instance.releasedate())
                    redir_page.set_editdate(instance.editdate())
                    redir_page.save()
                    redir_version = PageVersion(page=redir_page, title=version.title, redirect=instance.label,
                                                editor=member, comment='automatically generated on label change')
                    redir_version.set_redirect_reason('rename')
                    redir_version.save()
                    messages.info(request, 'Page label changed: the old location (%s) will redirect to this page.' % (old_label,))

                instance.save()
                
                #LOG EVENT#
                l = LogEntry(userid=request.user.username,
                      description="Edited page %s in %s." % (instance.label, offering),
                      related_object=instance)
                l.save()
                if page:
                    messages.success(request, "Edited "+kind+" \"%s\"." % (instance.label))
                else:
                    messages.success(request, "Created "+kind+" \"%s\"." % (instance.label))

                if not page and instance.label == 'Index' and not offering.url():
                    # new Index page but no existing course URL: set as course web page
                    url = settings.BASE_ABS_URL + instance.get_absolute_url()
                    offering.set_url(url)
                    offering.save()
                    messages.info(request, "Set course URL to new Index page.")
                
                return HttpResponseRedirect(reverse('pages.views.view_page', kwargs={'course_slug': course_slug, 'page_label': instance.label}))
        else:
            form = Form(instance=page, offering=offering)
            if 'label' in request.GET:
                label = request.GET['label']
                if label == 'Index':
                    form.initial['title'] = offering.name()
                    form.fields['label'].help_text += u'\u2014the label "Index" indicates the front page for this course.'
                elif label == MACRO_LABEL:
                    form.initial['can_read'] = 'INST'
                    form.initial['can_write'] = 'INST'
                    form.initial['title'] = MACRO_LABEL
                else:
                    form.initial['title'] = label.title()
                form.initial['label'] = label

        context = {
            'offering': offering,
            'page': page,
            'form': form,
            'kind': kind.title(),
            'is_macro_page': form.initial.get('title', None) == MACRO_LABEL,
        }
        return render(request, 'pages/edit_page.html', context)

Example 21

Project: coursys
Source File: views.py
View license
@retry_transaction()
@transaction.atomic
def _show_components_student(request, course_slug, activity_slug, userid=None, template="dashboard_student.html", staff=False):
    """
    Show all the component submission history of this activity
    """
    if userid == None:
        userid = request.user.username
    course = get_object_or_404(CourseOffering, slug=course_slug)
    activity = get_object_or_404(course.activity_set,slug=activity_slug, deleted=False)
    student = get_object_or_404(Person, find_userid_or_emplid(userid))
    cansubmit = True
    submission_configured = SubmissionComponent.objects.filter(activity_id=activity.id).exists()
    if not submission_configured:
        return NotFoundResponse(request)

    submission_info = SubmissionInfo(student=student, activity=activity)
    submission_info.get_most_recent_components()
    if activity.multisubmit():
        submission_info.get_all_components()

    any_submissions = bool(submission_info.submissions)

    if submission_info.submissions and activity.due_date and activity.due_date < submission_info.latest().created_at:
        late = submission_info.latest().created_at - activity.due_date
    else:
        late = 0
    
    if activity.group:
        gm = GroupMember.objects.filter(student__person=student, activity=activity, confirmed=True)
        if gm:
            group = gm[0].group
            member = gm[0].student
        else:
            group = None

    else:
        group = None

    # activity should be submitable
    cansubmit = cansubmit and activity.submitable()

    if not cansubmit:
        messages.add_message(request, messages.ERROR, "This activity is not submittable.")
        return render(request, "submission/" + template,
        {"course":course, "activity":activity, "submission_info": submission_info, 'any_submissions': any_submissions,
         "userid":userid, "late":late, "student":student, "group":group, "cansubmit":cansubmit})

    # get all components of activity
    component_list = select_all_components(activity)
    component_list.sort()
    component_form_list=[]

    if request.method == 'POST':
        component_form_list = make_form_from_list(component_list, request=request)
        submitted_comp = []    # list all components which has content submitted in the POST
        not_submitted_comp = [] #list allcomponents which has no content submitted in the POST
        if not activity.group:
            new_sub = StudentSubmission()   # the submission foreign key for newly submitted components
            new_sub.member = get_object_or_404(Member, offering__slug=course_slug, person__userid=request.user.username)
        elif gm:
            new_sub = GroupSubmission()
            new_sub.group = group
            new_sub.creator = member
        else:
            messages.add_message(request, messages.ERROR, "This is a group submission. You cannot submit since you aren't in a group.")
            return ForbiddenResponse(request)
        new_sub.activity = activity

        # begin validating uploaded data
        submitted_comp = []
        not_submitted_comp = []
        # validate forms one by one
        for data in component_form_list:
            component = data['comp']
            form = data['form']
            if form.is_valid():
                sub = form.save(commit=False)
                sub.component = component
                submitted_comp.append(sub)
            else:
                # hack to replace the "required" message to something more appropriate
                for k,v in form.errors.items():
                    for i,e in enumerate(v):
                        if e == "This field is required.":
                            v[i] = "Nothing submitted."

                not_submitted_comp.append(component)
        # check duplicate filenames here
        all_ok = False
        while not all_ok:
            all_ok = True
            d = {}
            if not activity.multisubmit():
                # single-submit logic: don't want to overrite filenames from earlier submissions that are still in-play
                for c,s in submission_info.components_and_submitted():
                    d[c] = s and s.get_filename()
            # filenames from this submission
            for s in submitted_comp:
                d[s.component] = s.get_filename()
            # a list holding all file names
            file_name_list = [a[1] for a in d.items() if a[1] is not None]
            to_be_removed = []
            for (i, s) in enumerate(submitted_comp):
                if file_name_list.count(s.get_filename()) > 1:
                    all_ok = False
                    to_be_removed.append(i)
                    not_submitted_comp.append(s.component)
                    #HACK: modify the 'errors' field in the form
                    for data in component_form_list:
                        if s.component == data['comp']:
                            # assume we have only one field for submission form
                            field_name = data['form'].fields.keys()[0]
                            data['form']._errors[field_name] = ErrorList([u"This file has the same name as another file in your submission."])
            # remove those has errors in submitted_comp
            to_be_removed.reverse()
            for t in to_be_removed:
                submitted_comp.pop(t)
        # all okay now
        # end validating, begin saving
        if len(submitted_comp) > 0:
            new_sub.save()    
        for sub in submitted_comp:
            sub.submission = new_sub
            sub.save()
            #LOG EVENT#
            if activity.group:
                group_str = " as a member of group %s" % new_sub.group.name
            else:
                group_str = ""
            l = LogEntry(userid=request.user.username,
                  description=u"submitted for %s %s%s" % (activity, sub.component.title, group_str),
                  related_object=sub)
            l.save()

        if len(not_submitted_comp) == 0:
            messages.add_message(request, messages.SUCCESS, "Your submission was successful.")
            return HttpResponseRedirect(reverse(show_components, args=[course_slug, activity_slug]))

        return render(request, "submission/submission_error.html",
            {"course":course, "activity":activity, "component_list":component_form_list,
            "submitted_comp":submitted_comp, "not_submitted_comp":not_submitted_comp})
    else: #not POST
        component_form_list = make_form_from_list(component_list)
        return render(request, "submission/" + template,
        {'component_form_list': component_form_list, "course": course, "activity": activity, "submission_info": submission_info,
         "userid":userid, "late":late, "student":student, "group":group,
         "cansubmit":cansubmit, "is_staff":staff, 'any_submissions': any_submissions})

Example 22

Project: django-templatesadmin
Source File: views.py
View license
@never_cache
@user_passes_test(lambda u: user_in_templatesadmin_group(u))
@login_required
def modify(request,
           path,
           template_name='templatesadmin/edit.html',
           base_form=TemplateForm,
           available_template_dirs=TEMPLATESADMIN_TEMPLATE_DIRS):

    template_path = _fixpath(path)

    # Check if file is within template-dirs
    if not any([template_path.startswith(templatedir) for templatedir in available_template_dirs]):
        request.user.message_set.create(message=_('Sorry, that file is not available for editing.'))
        return HttpResponseRedirect(reverse('templatesadmin-overview'))

    if request.method == 'POST':
        formclass = base_form
        for hook in TEMPLATESADMIN_EDITHOOKS:
            formclass.base_fields.update(hook.contribute_to_form(template_path))

        form = formclass(request.POST)
        if form.is_valid():
            content = form.cleaned_data['content']

            try:
                for hook in TEMPLATESADMIN_EDITHOOKS:
                    pre_save_notice = hook.pre_save(request, form, template_path)
                    if pre_save_notice:
                        request.user.message_set.create(message=pre_save_notice)
            except TemplatesAdminException, e:
                request.user.message_set.create(message=e.message)
                return HttpResponseRedirect(request.build_absolute_uri())

            # Save the template
            try:
                f = open(template_path, 'r')
                file_content = f.read()
                f.close()

                # browser tend to strip newlines from <textarea/>s before
                # HTTP-POSTing: re-insert them if neccessary

                # content is in dos-style lineending, will be converted in next step
                if (file_content[-1] == '\n' or file_content[:-2] == '\r\n') \
                   and content[:-2] != '\r\n':
                    content = u"%s\r\n" % content

                # Template is saved in unix-style, save in unix style.
                if None == search("\r\n", file_content):
                    content = content.replace("\r\n", "\n")

                f = codecs.open(template_path, 'w', 'utf-8')
                f.write(content)
                f.close()
            except IOError, e:
                request.user.message_set.create(
                    message=_('Template "%(path)s" has not been saved! Reason: %(errormsg)s' % {
                        'path': path,
                        'errormsg': e
                    })
                )
                return HttpResponseRedirect(request.build_absolute_uri())

            try:
                for hook in TEMPLATESADMIN_EDITHOOKS:
                    post_save_notice = hook.post_save(request, form, template_path)
                    if post_save_notice:
                        request.user.message_set.create(message=post_save_notice)
            except TemplatesAdminException, e:
                request.user.message_set.create(message=e.message)
                return HttpResponseRedirect(request.build_absolute_uri())

            request.user.message_set.create(
                message=_('Template "%s" was saved successfully.' % path)
            )
            return HttpResponseRedirect(reverse('templatesadmin-overview'))
    else:
        template_file = codecs.open(template_path, 'r', 'utf-8').read()

        formclass = TemplateForm
        for hook in TEMPLATESADMIN_EDITHOOKS:
            formclass.base_fields.update(hook.contribute_to_form(template_path))

        form = formclass(
            initial={'content': template_file}
        )

    template_context = {
        'messages': request.user.get_and_delete_messages(),
        'form': form,
        'short_path': path,
        'template_path': path,
        'template_writeable': os.access(template_path, os.W_OK),
        'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX,
    }

    return render_to_response(template_name, template_context,
                              RequestContext(request))

Example 23

Project: mybitbank
Source File: views.py
View license
@login_required
def send(request, selected_provider_id):
    '''
    handler for the transfers
    '''
    post_errors = []
    selected_provider_id = int(selected_provider_id)
    
    # set the request in the connector object
    connector.request = request
    
    if request.method == 'POST': 
        # we have a POST request
        form = forms.SendCurrencyForm(request.POST)
        
        if form.is_valid():
            # all validation rules pass
            from_account_identifier = form.cleaned_data['from_account']
            to_address = form.cleaned_data['to_address']
            to_account = form.cleaned_data['to_account']
            comment = form.cleaned_data['comment']
            comment_to = form.cleaned_data['comment_to']
            amount = form.cleaned_data['amount']
            provider_id = form.cleaned_data['provider_id']
            passphrase = form.cleaned_data['passphrase']
            
            # main exit flags
            move_exit = False
            sendfrom_exit = False
            
            # get from account details
            wallet = getWalletByProviderId(connector, selected_provider_id)
            list_of_accounts = wallet.listAccounts(gethidden=True, getarchived=True)
            from_account = None
            for account in list_of_accounts:
                if account['identifier'] == from_account_identifier:
                    from_account = account
                    break
            else:
                # account name not found, display error
                post_errors.append({'message': "The source account was not found!"})
                context = commonContext(request=request, selected_provider_id=provider_id, form=form, errors=post_errors)
                return render(request, 'transfer/index.html', context)
            
            # get to account details if there is one
            to_account = wallet.getAccountByAddress(to_address)
            # if to_account is set then it is a local move, do a move()
            if to_account:
                # this address/account is hosted locally, do a move
                move_exit = connector.moveAmount(
                                                 from_account=from_account['name'],
                                                 to_account=to_account['name'],
                                                 provider_id=provider_id,
                                                 amount=amount,
                                                 comment=comment
                                                )
                
                # if there are errors, show them in the UI
                if move_exit is not True:
                    post_errors.append({'message': move_exit['message']})
                    context = commonContext(request=request, selected_provider_id=provider_id, form=form, errors=post_errors)
                    return render(request, 'transfer/index.html', context)
                
            else:
                # otherwise do a sendfrom(), it is a regular transaction
                if passphrase:
                    # a passphrase was given, unlock wallet first
                    unlock_exit = connector.walletPassphrase(passphrase, provider_id)
                    
                    if unlock_exit is not True:
                        # show form with error
                        post_errors.append({'message': unlock_exit['message']})
                        context = commonContext(request=request, selected_provider_id=provider_id, form=form, errors=post_errors, show_passphrase=True)
                        return render(request, 'transfer/index.html', context)
                
                # to_address not local, do a send
                sendfrom_exit = connector.sendFrom(
                                                   from_account=from_account['name'],
                                                   to_address=to_address,
                                                   amount=amount,
                                                   provider_id=provider_id,
                                                   comment=comment,
                                                   comment_to=comment_to
                                                  )
                
                # if there are errors, show them in the UI
                if type(sendfrom_exit) is dict and sendfrom_exit['code'] < 0:
                    
                    # check if passphrase is needed
                    if sendfrom_exit['code'] == -13:
                        # passphrase is needed
                        show_passphrase = True
                    else:
                        show_passphrase = False
                    
                    if not request.is_secure() and show_passphrase:
                        show_warning_ssl = 1
                    elif request.is_secure() and show_passphrase:
                        show_warning_ssl = -1
                    else:
                        show_warning_ssl = 0
                    
                    # show form with error
                    post_errors.append({'message': sendfrom_exit['message']})
                    context = commonContext(request=request, selected_provider_id=provider_id, form=form, errors=post_errors, show_passphrase=show_passphrase, show_warning_ssl=show_warning_ssl)
                    return render(request, 'transfer/index.html', context)
                
            if passphrase:
                # lock wallet again
                connector.walletLock(provider_id)
                
            # process the data in form.cleaned_data
            if move_exit:
                messages.success(request, 'Local move of %s %s completed from account "%s" to "%s"' % (amount, connector.config[provider_id]['currency'].upper(), from_account['name'], to_account['name']), extra_tags="success")
                events.addEvent(request, 'Local move occurred from "%s" to "%s" in the amount of %s %s' % (from_account['name'], to_account['name'], amount, connector.config[provider_id]['currency'].upper()), 'info')
                return HttpResponseRedirect(reverse('transactions:index', kwargs={'selected_provider_id': selected_provider_id, 'page': '1'}))  # Redirect after POST
            elif sendfrom_exit:
                messages.success(request, 'Transfer of %s %s initialized with transaction id %s' % (amount, connector.config[provider_id]['currency'].upper(), sendfrom_exit), extra_tags="success")
                events.addEvent(request, 'Transfer initialized from "%s" to "%s" of %s %s' % (from_account['name'], to_address, amount, connector.config[provider_id]['currency'].upper()), 'info')
                return HttpResponseRedirect(reverse('transactions:details', kwargs={'provider_id': provider_id, 'txid':sendfrom_exit}))  # Redirect after POST
        
        else:
            # form not valid
            #messages.error(request, 'There were some errors processing this form!', extra_tags="error")
            print "Error processing form!"
            
    else:
        # request not a POST
        form = forms.SendCurrencyForm()
        
    context = commonContext(request=request, selected_provider_id=selected_provider_id, form=form)
    
    return render(request, 'transfer/index.html', context)

Example 24

Project: oioioi
Source File: tests.py
View license
    def test_add_problem_to_contest(self):
        ProblemInstance.objects.all().delete()

        contest = Contest.objects.get()
        contest.default_submissions_limit = 42
        contest.save()
        filename = get_test_filename('test_simple_package.zip')
        self.client.login(username='test_admin')
        # Add problem to problemset
        url = reverse('problemset_add_or_update')
        response = self.client.get(url, follow=True)
        url = response.redirect_chain[-1][0]
        self.assertEqual(response.status_code, 200)
        response = self.client.post(url,
                {'package_file': open(filename, 'rb')}, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(Problem.objects.count(), 1)
        self.assertEqual(ProblemInstance.objects.count(), 1)

        problem = Problem.objects.get()
        url_key = problem.problemsite.url_key

        # now, add problem to the contest
        url = reverse('add_or_update_problem',
                kwargs={'contest_id': contest.id}) + '?' + \
                        urllib.urlencode({'key': "problemset_source"})
        response = self.client.post(url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertIn('Add from Problemset', response.content)
        self.assertIn('Enter problem', response.content)
        self.assertIn('s secret key', response.content)
        self.assertIn('Choose problem from problemset', response.content)

        pi_number = 3
        for i in xrange(pi_number):
            url = reverse('add_or_update_problem',
                    kwargs={'contest_id': contest.id}) + '?' + \
                        urllib.urlencode({'key': "problemset_source"})
            response = self.client.get(url,
                       {'url_key': url_key}, follow=True)
            self.assertEqual(response.status_code, 200)
            self.assertIn(str(url_key), response.content)
            response = self.client.post(url,
                        {'url_key': url_key}, follow=True)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(ProblemInstance.objects.count(), 2 + i)

        # check submissions limit
        for pi in ProblemInstance.objects.filter(contest__isnull=False):
            self.assertEqual(pi.submissions_limit,
                             contest.default_submissions_limit)

        # add probleminstances to round
        for pi in ProblemInstance.objects.filter(contest__isnull=False):
            pi.round = Round.objects.get()
            pi.save()

        # we can see model solutions
        pi = ProblemInstance.objects.filter(contest__isnull=False)[0]
        self.check_models_for_simple_package(pi)

        # tests and models of every problem_instance are independent
        num_tests = pi.test_set.count()
        for test in pi.test_set.all():
            test.delete()
        pi.save()

        url = reverse('model_solutions', args=[pi.id])
        response = self.client.post(url, follow=True)
        self.assertEqual(response.status_code, 200)
        for test in ["0", "1a", "1b", "1c", "2"]:
            self.assertNotIn(">" + test + "</th>", response.content)

        for pi2 in ProblemInstance.objects.all():
            if pi2 != pi:
                self.assertEqual(pi2.test_set.count(), num_tests)
                self.check_models_for_simple_package(pi2)

        # reupload one ProblemInstance from problemset
        url = reverse('add_or_update_problem',
                kwargs={'contest_id': contest.id}) + '?' + \
                    urllib.urlencode({'key': "problemset_source",
                                      'problem': problem.id,
                                      'instance_id': pi.id})
        response = self.client.get(url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertIn(str(url_key), response.content)
        self.assertNotIn("Select", response.content)
        response = self.client.post(url, {'url_key': url_key}, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(ProblemInstance.objects.count(), pi_number + 1)
        self.assertTrue(pi.round)
        self.assertEqual(pi.test_set.count(), num_tests)
        self.check_models_for_simple_package(pi)
        self.assertIn("1 PROBLEM NEEDS REJUDGING", response.content)
        self.assertEqual(response.content
               .count("Rejudge all submissions for problem"), 1)

        # reupload problem in problemset
        url = reverse('problemset_add_or_update') + '?' + \
                    urllib.urlencode({'problem': problem.id})
        response = self.client.get(url, follow=True)
        url = response.redirect_chain[-1][0]
        self.assertEqual(response.status_code, 200)
        response = self.client.post(url,
                {'package_file': open(filename, 'rb')}, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(ProblemInstance.objects.count(), pi_number + 1)
        self.assertIn("3 PROBLEMS NEED REJUDGING", response.content)
        self.check_models_for_simple_package(pi)

        # rejudge one problem
        url = reverse('rejudge_all_submissions_for_problem', args=[pi.id])
        response = self.client.get(url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertIn("You are going to rejudge 1", response.content)
        response = self.client.post(url, {'submit': True}, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content
                 .count("Rejudge all submissions for problem"), pi_number - 1)
        self.assertIn("1 rejudge request received.", response.content)

Example 25

Project: SmartElect
Source File: test_end_to_end.py
View license
    def _read_dashboard(self, actual_stats):
        """ Read parts of the dashboard that contain data we're testing and fill in the
        provided dictionary with the stats we observe.

        This only supports a small subset of the stats on the dashboard.
        """

        # Process the office-specific election day screen
        for office_id in self.all_office_ids:
            url = reverse('vr_dashboard:election-day-office-n', args=(office_id,))
            rsp = self._request(url)
            actual_stats['by_office'][office_id]['summary'] = \
                self._parse_headline(rsp.context['headline'], has_inactive=True)
            for row in rsp.context['office_centers_table']:
                center_id = row['polling_center_code']
                assert center_id in actual_stats['by_center'], \
                    'Center id %s is unexpected (not one of %s)' % \
                    (center_id, actual_stats['by_center'].keys())
                if 'opened_today' in row:
                    open_dt = row['opened_today']
                    actual_stats['by_center'][center_id]['ed_open'] = open_dt
                if 'inactive_for_election' in row:
                    actual_stats['by_center'][center_id]['inactive'] = True
                    self.assertEqual(row['tr_class'], 'inactive_for_election')
                for period in ['1', '2', '3', '4']:
                    votes_reported_period = 'votes_reported_' + period
                    if votes_reported_period in row:
                        actual_stats['by_center'][center_id][votes_reported_period] = \
                            row[votes_reported_period]
                        actual_stats['by_office'][office_id][votes_reported_period] = \
                            row[votes_reported_period]
                    actual_stats['by_center'][center_id]['reported_period_' + period] = \
                        row['reported_period_' + period]

        # prelim vote counts
        url = reverse('vr_dashboard:election-day-preliminary')
        rsp = self._request(url)
        for office in rsp.context['offices']:
            if PRELIMINARY_VOTE_COUNTS in office:
                actual_stats['by_office'][office['office_id']]['prelim'] = {
                    key: intcomma(value)
                    for key, value in office[PRELIMINARY_VOTE_COUNTS].iteritems()
                }

        # process the sms screen
        url = reverse('vr_dashboard:sms')
        rsp = self._request(url)
        yesterday_str = rsp.context['sms_stats']['last_date']
        for stats in rsp.context['message_stats_by_type']:
            msg_type = stats['translated_sms_type']
            msg_yesterday_count = int(stats['last'])
            msg_total_count = int(stats['total'])
            actual_stats['message_stats'][msg_type] = {
                yesterday_str: msg_yesterday_count,
                'total': msg_total_count
            }

        # look at summary stats from main election_day page
        url = reverse('vr_dashboard:election-day')
        rsp = self._request(url)
        actual_stats['summary'] = self._parse_headline(rsp.context['headline'])
        for row in rsp.context['offices']:
            actual_office_stats = actual_stats['by_office'][row['office_id']]
            actual_office_stats['opened'] = row['opened']
            actual_office_stats['unopened'] = row['not_opened']
            actual_office_stats['closed'] = row['closed']
            actual_office_stats['not_reported_1'] = row['not_reported_1']
            actual_office_stats['not_reported_2'] = row['not_reported_2']
            actual_office_stats['not_reported_3'] = row['not_reported_3']
            actual_office_stats['not_reported_4'] = row['not_reported_4']

        # process the election day CSVs, testing something from each data row
        csv = self._request_csv(reverse('vr_dashboard:election-day'))
        # office data starts in 4th row, country-wide is last row
        for row in csv[3:-1]:
            office_id = int(row[0].split()[0])
            opened = int(row[2])
            # already grabbed from normal view, so make sure it matches
            self.assertEquals(actual_stats['by_office'][office_id]['opened'], opened)

        csv = self._request_csv(reverse('vr_dashboard:election-day-center'))
        # center data starts in 4th row
        for row in csv[3:]:
            center_id = int(row[1])
            total_regs = '' if not row[3] else int(row[3])  # '' for copy center
            actual_stats['by_center'][center_id]['registrations'] = total_regs
            # inactive already read from election-day-office-n; make sure it matches
            active_flag = 'No' if 'inactive' in actual_stats['by_center'][center_id] else 'Yes'
            self.assertEqual(row[5], active_flag)
            actual_stats['by_center'][center_id]['opened_hm'] = row[6] if row[6] else None
            actual_stats['by_center'][center_id]['is_closed'] = row[11]
            # votes_reported_N already read from election-day-office-n; make sure it matches
            for period, where_in_row in (('1', 7), ('2', 8), ('3', 9), ('4', 10)):
                period_key = 'votes_reported_' + period
                if row[where_in_row]:
                    self.assertEquals(actual_stats['by_center'][center_id][period_key],
                                      int(row[where_in_row]))
                else:
                    self.assertNotIn(period_key, actual_stats['by_center'][center_id])

        for office_id in self.all_office_ids:
            csv = self._request_csv(reverse('vr_dashboard:election-day-office-n',
                                            args=[office_id]))
            # The center open time has already been read from the HTML, so just
            # make sure that it is consistent in the CSV.
            # Note that if there's no CenterOpen, the context will have None but
            # the screen and CSV will have '-'.
            center_id = int(csv[3][1])
            open_dt = csv[3][3]
            self.assertEqual(
                actual_stats['by_center'][center_id]['ed_open'] or '-',
                open_dt,
                'Open for center %d different between HTML and CSV (%s, %s)' % (
                    center_id, actual_stats['by_center'][center_id]['ed_open'], open_dt
                )
            )
            for row in csv[3:]:
                center_id = int(row[1])
                # inactive already read from election-day-office-n; make sure it matches
                active_flag = 'No' if 'inactive' in actual_stats['by_center'][center_id] else 'Yes'
                self.assertEqual(row[2], active_flag)

        for center in self.all_centers:
            center_id = center.center_id
            rsp = self._request(reverse('vr_dashboard:election-day-center-n',
                                        args=[center_id]))
            stats = rsp.context['stats']
            actual_center_stats = actual_stats['by_center'][center_id]
            # The last opened time was already read (set to None if it didn't open);
            # make sure it matches the form on this page, which uses 'Not Opened'
            # instead of None for unopened.
            self.assertEqual(
                actual_center_stats['ed_open'] or 'Not Opened',
                stats['last_opened'],
                'Open for center %d different between by-office and by-center pages (%s, %s)' % (
                    center_id, actual_center_stats['ed_open'], stats['last_opened']
                )
            )
            actual_center_stats['last_report'] = stats['last_report']
            for period in ('1', '2', '3', '4'):
                # votes for period is either '' or string form of number
                orig_key = 'reported_period_' + period
                new_key = 'reported_period_' + period + '_count'
                actual_center_stats[new_key] = \
                    self._extract_int_from_span(stats[orig_key]) if stats[orig_key] else 0
            # consistency between what was already extracted for 'inactive' and this response?
            self.assertEqual(
                'inactive' in actual_stats['by_center'][center_id],
                'inactive_for_election' in rsp.context['center']
            )

        # messages from staff phone
        history = self._request(
            reverse('vr_dashboard:phone-history') + '?phone=%s' % self.staff_phone_number
        )
        actual_stats['phone_history'][self.staff_phone_number] = {
            'message_count': len(history.context['sms_messages']),
        }

Example 26

Project: cartridge
Source File: views.py
View license
@never_cache
def checkout_steps(request, form_class=OrderForm, extra_context=None):
    """
    Display the order form and handle processing of each step.
    """

    # Do the authentication check here rather than using standard
    # login_required decorator. This means we can check for a custom
    # LOGIN_URL and fall back to our own login view.
    authenticated = request.user.is_authenticated()
    if settings.SHOP_CHECKOUT_ACCOUNT_REQUIRED and not authenticated:
        url = "%s?next=%s" % (settings.LOGIN_URL, reverse("shop_checkout"))
        return redirect(url)

    try:
        settings.SHOP_CHECKOUT_FORM_CLASS
    except AttributeError:
        pass
    else:
        from warnings import warn
        warn("The SHOP_CHECKOUT_FORM_CLASS setting is deprecated - please "
             "define your own urlpattern for the checkout_steps view, "
             "passing in your own form_class argument.")
        form_class = import_dotted_path(settings.SHOP_CHECKOUT_FORM_CLASS)

    initial = checkout.initial_order_data(request, form_class)
    step = int(request.POST.get("step", None) or
               initial.get("step", None) or
               checkout.CHECKOUT_STEP_FIRST)
    form = form_class(request, step, initial=initial)
    data = request.POST
    checkout_errors = []

    if request.POST.get("back") is not None:
        # Back button in the form was pressed - load the order form
        # for the previous step and maintain the field values entered.
        step -= 1
        form = form_class(request, step, initial=initial)
    elif request.method == "POST" and request.cart.has_items():
        form = form_class(request, step, initial=initial, data=data)
        if form.is_valid():
            # Copy the current form fields to the session so that
            # they're maintained if the customer leaves the checkout
            # process, but remove sensitive fields from the session
            # such as the credit card fields so that they're never
            # stored anywhere.
            request.session["order"] = dict(form.cleaned_data)
            sensitive_card_fields = ("card_number", "card_expiry_month",
                                     "card_expiry_year", "card_ccv")
            for field in sensitive_card_fields:
                if field in request.session["order"]:
                    del request.session["order"][field]

            # FIRST CHECKOUT STEP - handle discount code. This needs to
            # be set before shipping, to allow for free shipping to be
            # first set by a discount code.
            if step == checkout.CHECKOUT_STEP_FIRST:
                form.set_discount()

            # ALL STEPS - run billing/tax handlers. These are run on
            # all steps, since all fields (such as address fields) are
            # posted on each step, even as hidden inputs when not
            # visible in the current step.
            try:
                billship_handler(request, form)
                tax_handler(request, form)
            except checkout.CheckoutError as e:
                checkout_errors.append(e)

            # FINAL CHECKOUT STEP - run payment handler and process order.
            if step == checkout.CHECKOUT_STEP_LAST and not checkout_errors:
                # Create and save the initial order object so that
                # the payment handler has access to all of the order
                # fields. If there is a payment error then delete the
                # order, otherwise remove the cart items from stock
                # and send the order receipt email.
                order = form.save(commit=False)
                order.setup(request)
                # Try payment.
                try:
                    transaction_id = payment_handler(request, form, order)
                except checkout.CheckoutError as e:
                    # Error in payment handler.
                    order.delete()
                    checkout_errors.append(e)
                    if settings.SHOP_CHECKOUT_STEPS_CONFIRMATION:
                        step -= 1
                else:
                    # Finalize order - ``order.complete()`` performs
                    # final cleanup of session and cart.
                    # ``order_handler()`` can be defined by the
                    # developer to implement custom order processing.
                    # Then send the order email to the customer.
                    order.transaction_id = transaction_id
                    order.complete(request)
                    order_handler(request, form, order)
                    checkout.send_order_email(request, order)
                    # Set the cookie for remembering address details
                    # if the "remember" checkbox was checked.
                    response = redirect("shop_complete")
                    if form.cleaned_data.get("remember"):
                        remembered = "%s:%s" % (sign(order.key), order.key)
                        set_cookie(response, "remember", remembered,
                                   secure=request.is_secure())
                    else:
                        response.delete_cookie("remember")
                    return response

            # If any checkout errors, assign them to a new form and
            # re-run is_valid. If valid, then set form to the next step.
            form = form_class(request, step, initial=initial, data=data,
                              errors=checkout_errors)
            if form.is_valid():
                step += 1
                form = form_class(request, step, initial=initial)

    # Update the step so that we don't rely on POST data to take us back to
    # the same point in the checkout process.
    try:
        request.session["order"]["step"] = step
        request.session.modified = True
    except KeyError:
        pass

    step_vars = checkout.CHECKOUT_STEPS[step - 1]
    template = "shop/%s.html" % step_vars["template"]
    context = {"CHECKOUT_STEP_FIRST": step == checkout.CHECKOUT_STEP_FIRST,
               "CHECKOUT_STEP_LAST": step == checkout.CHECKOUT_STEP_LAST,
               "CHECKOUT_STEP_PAYMENT": (settings.SHOP_PAYMENT_STEP_ENABLED and
                   step == checkout.CHECKOUT_STEP_PAYMENT),
               "step_title": step_vars["title"], "step_url": step_vars["url"],
               "steps": checkout.CHECKOUT_STEPS, "step": step, "form": form}
    context.update(extra_context or {})
    return TemplateResponse(request, template, context)

Example 27

Project: django-forms-builder
Source File: forms.py
View license
    def rows(self, csv=False):
        """
        Returns each row based on the selected criteria.
        """

        # Store the index of each field against its ID for building each
        # entry row with columns in the correct order. Also store the IDs of
        # fields with a type of FileField or Date-like for special handling of
        # their values.
        field_indexes = {}
        file_field_ids = []
        date_field_ids = []
        for field in self.form_fields:
            if self.posted_data("field_%s_export" % field.id):
                field_indexes[field.id] = len(field_indexes)
                if field.is_a(fields.FILE):
                    file_field_ids.append(field.id)
                elif field.is_a(*fields.DATES):
                    date_field_ids.append(field.id)
        num_columns = len(field_indexes)
        include_entry_time = self.posted_data("field_0_export")
        if include_entry_time:
            num_columns += 1

        # Get the field entries for the given form and filter by entry_time
        # if specified.
        model = self.fieldentry_model
        field_entries = model.objects.filter(entry__form=self.form
            ).order_by("-entry__id").select_related("entry")
        if self.posted_data("field_0_filter") == FILTER_CHOICE_BETWEEN:
            time_from = self.posted_data("field_0_from")
            time_to = self.posted_data("field_0_to")
            if time_from and time_to:
                field_entries = field_entries.filter(
                    entry__entry_time__range=(time_from, time_to))

        # Loop through each field value ordered by entry, building up each
        # entry as a row. Use the ``valid_row`` flag for marking a row as
        # invalid if it fails one of the filtering criteria specified.
        current_entry = None
        current_row = None
        valid_row = True
        for field_entry in field_entries:
            if field_entry.entry_id != current_entry:
                # New entry, write out the current row and start a new one.
                if valid_row and current_row is not None:
                    if not csv:
                        current_row.insert(0, current_entry)
                    yield current_row
                current_entry = field_entry.entry_id
                current_row = [""] * num_columns
                valid_row = True
                if include_entry_time:
                    current_row[-1] = field_entry.entry.entry_time
            field_value = field_entry.value or ""
            # Check for filter.
            field_id = field_entry.field_id
            filter_type = self.posted_data("field_%s_filter" % field_id)
            filter_args = None
            if filter_type:
                if filter_type == FILTER_CHOICE_BETWEEN:
                    f, t = "field_%s_from" % field_id, "field_%s_to" % field_id
                    filter_args = [self.posted_data(f), self.posted_data(t)]
                else:
                    field_name = "field_%s_contains" % field_id
                    filter_args = self.posted_data(field_name)
                    if filter_args:
                        filter_args = [filter_args]
            if filter_args:
                # Convert dates before checking filter.
                if field_id in date_field_ids:
                    try:
                        y, m, d = field_value.split(" ")[0].split("-")
                    except ValueError:
                        filter_args.append(field_value)
                    else:
                        dte = date(int(y), int(m), int(d))
                        filter_args.append(dte)
                else:
                    filter_args.append(field_value)
                filter_func = FILTER_FUNCS[filter_type]
                if not filter_func(*filter_args):
                    valid_row = False
            # Create download URL for file fields.
            if field_entry.value and field_id in file_field_ids:
                url = reverse("admin:form_file", args=(field_entry.id,))
                field_value = self.request.build_absolute_uri(url)
                if not csv:
                    parts = (field_value, split(field_entry.value)[1])
                    field_value = mark_safe("<a href=\"%s\">%s</a>" % parts)
            # Only use values for fields that were selected.
            try:
                current_row[field_indexes[field_id]] = field_value
            except KeyError:
                pass
        # Output the final row.
        if valid_row and current_row is not None:
            if not csv:
                current_row.insert(0, current_entry)
            yield current_row

Example 28

Project: filebrowser-safe
Source File: views.py
View license
@xframe_options_sameorigin
def browse(request):
    """
    Browse Files/Directories.
    """

    # QUERY / PATH CHECK
    query = request.GET.copy()
    path = get_path(query.get('dir', ''))
    directory = get_path('')

    if path is None:
        msg = _('The requested Folder does not exist.')
        messages.add_message(request, messages.ERROR, msg)
        if directory is None:
            # The directory returned by get_directory() does not exist, raise an error to prevent eternal redirecting.
            raise ImproperlyConfigured(_("Error finding Upload-Folder. Maybe it does not exist?"))
        redirect_url = reverse("fb_browse") + query_helper(query, "", "dir")
        return HttpResponseRedirect(redirect_url)
    abs_path = os.path.join(get_directory(), path)

    # INITIAL VARIABLES
    results_var = {'results_total': 0, 'results_current': 0, 'delete_total': 0, 'images_total': 0, 'select_total': 0}
    counter = {}
    for k, v in EXTENSIONS.items():
        counter[k] = 0

    dir_list, file_list = default_storage.listdir(abs_path)
    files = []
    for file in dir_list + file_list:

        # EXCLUDE FILES MATCHING ANY OF THE EXCLUDE PATTERNS
        filtered = not file or file.startswith('.')
        for re_prefix in filter_re:
            if re_prefix.search(file):
                filtered = True
        if filtered:
            continue
        results_var['results_total'] += 1

        # CREATE FILEOBJECT
        url_path = "/".join([s.strip("/") for s in
                            [get_directory(), path, file] if s.strip("/")])
        fileobject = FileObject(url_path)

        # FILTER / SEARCH
        append = False
        if fileobject.filetype == request.GET.get('filter_type', fileobject.filetype) and get_filterdate(request.GET.get('filter_date', ''), fileobject.date):
            append = True
        if request.GET.get('q') and not re.compile(request.GET.get('q').lower(), re.M).search(file.lower()):
            append = False

        # APPEND FILE_LIST
        if append:
            try:
                # COUNTER/RESULTS
                if fileobject.filetype == 'Image':
                    results_var['images_total'] += 1
                if fileobject.filetype != 'Folder':
                    results_var['delete_total'] += 1
                elif fileobject.filetype == 'Folder' and fileobject.is_empty:
                    results_var['delete_total'] += 1
                if query.get('type') and query.get('type') in SELECT_FORMATS and fileobject.filetype in SELECT_FORMATS[query.get('type')]:
                    results_var['select_total'] += 1
                elif not query.get('type'):
                    results_var['select_total'] += 1
            except OSError:
                # Ignore items that have problems
                continue
            else:
                files.append(fileobject)
                results_var['results_current'] += 1

        # COUNTER/RESULTS
        if fileobject.filetype:
            counter[fileobject.filetype] += 1

    # SORTING
    query['o'] = request.GET.get('o', DEFAULT_SORTING_BY)
    query['ot'] = request.GET.get('ot', DEFAULT_SORTING_ORDER)
    defaultValue = ''
    if query['o'] in ['date', 'filesize']:
        defaultValue = 0.0
    files = sorted(files, key=lambda f: getattr(f, query['o']) or defaultValue)
    if not request.GET.get('ot') and DEFAULT_SORTING_ORDER == "desc" or request.GET.get('ot') == "desc":
        files.reverse()

    p = Paginator(files, LIST_PER_PAGE)
    try:
        page_nr = request.GET.get('p', '1')
    except:
        page_nr = 1
    try:
        page = p.page(page_nr)
    except (EmptyPage, InvalidPage):
        page = p.page(p.num_pages)

    return render(request, 'filebrowser/index.html', {
        'dir': path,
        'p': p,
        'page': page,
        'results_var': results_var,
        'counter': counter,
        'query': query,
        'title': _(u'Media Library'),
        'settings_var': get_settings_var(),
        'breadcrumbs': get_breadcrumbs(query, path),
        'breadcrumbs_title': ""
    })

Example 29

Project: mezzanine
Source File: mezzanine_tags.py
View license
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``.
    Returns a list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}

    # Model or view --> (group index, group title, item index, item title).
    menu_order = {}
    for (group_index, group) in enumerate(settings.ADMIN_MENU_ORDER):
        group_title, items = group
        for (item_index, item) in enumerate(items):
            if isinstance(item, (tuple, list)):
                item_title, item = item
            else:
                item_title = None
            menu_order[item] = (group_index, group_title,
                                item_index, item_title)

    # Add all registered models, using group and title from menu order.
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if hasattr(model_admin, "in_menu"):
            import warnings
            warnings.warn(
                'ModelAdmin.in_menu() has been replaced with '
                'ModelAdmin.has_module_permission(request). See '
                'https://docs.djangoproject.com/en/stable/ref/contrib/admin/'
                '#django.contrib.admin.ModelAdmin.has_module_permission.',
                DeprecationWarning)
        in_menu = in_menu and model_admin.has_module_permission(request)
        if in_menu and request.user.has_module_perms(opts.app_label):
            admin_url_name = ""
            if model_admin.has_change_permission(request):
                admin_url_name = "changelist"
                change_url = admin_url(model, admin_url_name)
            else:
                change_url = None
            if model_admin.has_add_permission(request):
                admin_url_name = "add"
                add_url = admin_url(model, admin_url_name)
            else:
                add_url = None
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                try:
                    app_index, app_title, model_index, model_title = \
                        menu_order[model_label]
                except KeyError:
                    app_index = None
                    try:
                        app_title = opts.app_config.verbose_name.title()
                    except AttributeError:
                        # Third party admin classes doing weird things.
                        # See GH #1628
                        app_title = ""
                    model_index = None
                    model_title = None
                else:
                    del menu_order[model_label]

                if not model_title:
                    model_title = capfirst(model._meta.verbose_name_plural)

                if app_title not in app_dict:
                    app_dict[app_title] = {
                        "index": app_index,
                        "name": app_title,
                        "models": [],
                    }
                app_dict[app_title]["models"].append({
                    "index": model_index,
                    "perms": model_admin.get_model_perms(request),
                    "name": model_title,
                    "object_name": opts.object_name,
                    "admin_url": change_url,
                    "add_url": add_url
                })

    # Menu may also contain view or url pattern names given as (title, name).
    for (item_url, item) in menu_order.items():
        app_index, app_title, item_index, item_title = item
        try:
            item_url = reverse(item_url)
        except NoReverseMatch:
            continue
        if app_title not in app_dict:
            app_dict[app_title] = {
                "index": app_index,
                "name": app_title,
                "models": [],
            }
        app_dict[app_title]["models"].append({
            "index": item_index,
            "perms": {"custom": True},
            "name": item_title,
            "admin_url": item_url,
        })

    app_list = list(app_dict.values())
    sort = lambda x: (x["index"] if x["index"] is not None else 999, x["name"])
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list

Example 30

Project: amy
Source File: test_event.py
View license
    def setUp(self):
        self._setUpOrganizations()
        self._setUpAirports()
        self._setUpBadges()
        self._setUpLessons()
        self._setUpRoles()
        self._setUpInstructors()
        self._setUpUsersAndLogin()
        self._setUpTags()
        self._setUpLanguages()

        today = date.today()
        tomorrow = today + timedelta(days=1)

        # Add full-blown events so that we can test merging of everything.
        # Random data such as contact, venue, address, lat/long, URLs or notes
        # were generated with faker (see `fake_database.py` for details).
        self.event_a = Event.objects.create(
            slug='event-a', completed=True, assigned_to=self.harry,
            start=today, end=tomorrow,
            host=self.org_alpha, administrator=self.org_alpha,
            url='http://reichel.com/event-a', language=self.french,
            reg_key='123456',
            admin_fee=2500, invoice_status='not-invoiced',
            attendance=30, contact='[email protected]', country='US',
            venue='Modi', address='876 Dot Fork',
            latitude=59.987509, longitude=-51.507076,
            learners_pre='http://reichel.com/learners_pre',
            learners_post='http://reichel.com/learners_post',
            instructors_pre='http://reichel.com/instructors_pre',
            instructors_post='http://reichel.com/instructors_post',
            learners_longterm='http://reichel.com/learners_longterm',
            notes='Voluptates hic aspernatur non aut.'
        )
        self.event_a.tags = Tag.objects.filter(name__in=['LC', 'DC'])
        self.event_a.task_set.create(person=self.harry,
                                     role=Role.objects.get(name='instructor'))
        self.event_a.todoitem_set.create(completed=False,
                                         title='Find instructors', due=today)

        self.event_b = Event.objects.create(
            slug='event-b', completed=False, assigned_to=self.hermione,
            start=today, end=tomorrow + timedelta(days=1),
            host=self.org_beta, administrator=self.org_beta,
            url='http://www.cummings.biz/event-b', language=self.english,
            reg_key='654321',
            admin_fee=2500, invoice_status='not-invoiced',
            attendance=40, contact='[email protected]',
            country='GB', venue='Nisi', address='59747 Fernanda Cape',
            latitude=-29.545137, longitude=32.417491,
            learners_pre='http://www.cummings.biz/learners_pre',
            learners_post='http://www.cummings.biz/learners_post',
            instructors_pre='http://www.cummings.biz/instructors_pre',
            instructors_post='http://www.cummings.biz/instructors_post',
            learners_longterm='http://www.cummings.biz/learners_longterm',
            notes='Est qui iusto sapiente possimus consectetur rerum et.'
        )
        self.event_b.tags = Tag.objects.filter(name='SWC')
        # no tasks for this event
        self.event_b.todoitem_set.create(completed=True, title='Test merging',
                                         due=today)

        # some "random" strategy for testing
        self.strategy = {
            'event_a': self.event_a.pk,
            'event_b': self.event_b.pk,
            'id': 'obj_b',
            'slug': 'obj_a',
            'completed': 'obj_b',
            'assigned_to': 'obj_a',
            'start': 'obj_b',
            'end': 'obj_a',
            'host': 'obj_b',
            'administrator': 'obj_a',
            'url': 'obj_b',
            'language': 'obj_b',
            'reg_key': 'obj_a',
            'admin_fee': 'obj_b',
            'invoice_status': 'obj_a',
            'attendance': 'obj_b',
            'country': 'obj_a',
            'latitude': 'obj_b',
            'longitude': 'obj_a',
            'learners_pre': 'obj_b',
            'learners_post': 'obj_a',
            'instructors_pre': 'obj_b',
            'instructors_post': 'obj_a',
            'learners_longterm': 'obj_b',
            'contact': 'obj_a',
            'venue': 'obj_b',
            'address': 'combine',
            'notes': 'obj_a',
            'tags': 'combine',
            'task_set': 'obj_b',
            'todoitem_set': 'obj_a',
        }
        base_url = reverse('events_merge')
        query = urlencode({
            'event_a_0': self.event_a.slug,
            'event_b_0': self.event_b.slug
        })
        self.url = '{}?{}'.format(base_url, query)

Example 31

Project: taiga-back
Source File: test_issues.py
View license
def test_api_filters_data(client):
    project = f.ProjectFactory.create()
    user1 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user1, project=project)
    user2 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user2, project=project)
    user3 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user3, project=project)

    status0 = f.IssueStatusFactory.create(project=project)
    status1 = f.IssueStatusFactory.create(project=project)
    status2 = f.IssueStatusFactory.create(project=project)
    status3 = f.IssueStatusFactory.create(project=project)

    type1 = f.IssueTypeFactory.create(project=project)
    type2 = f.IssueTypeFactory.create(project=project)

    severity0 = f.SeverityFactory.create(project=project)
    severity1 = f.SeverityFactory.create(project=project)
    severity2 = f.SeverityFactory.create(project=project)
    severity3 = f.SeverityFactory.create(project=project)

    priority0 = f.PriorityFactory.create(project=project)
    priority1 = f.PriorityFactory.create(project=project)
    priority2 = f.PriorityFactory.create(project=project)
    priority3 = f.PriorityFactory.create(project=project)

    tag0 = "test1test2test3"
    tag1 = "test1"
    tag2 = "test2"
    tag3 = "test3"

    # ------------------------------------------------------------------------------------------------
    # | Issue |  Owner | Assigned To | Status  | Type  | Priority  | Severity  | Tags                |
    # |-------#--------#-------------#---------#-------#-----------#-----------#---------------------|
    # | 0     |  user2 | None        | status3 | type1 | priority2 | severity1 |      tag1           |
    # | 1     |  user1 | None        | status3 | type2 | priority2 | severity1 |           tag2      |
    # | 2     |  user3 | None        | status1 | type1 | priority3 | severity2 |      tag1 tag2      |
    # | 3     |  user2 | None        | status0 | type2 | priority3 | severity1 |                tag3 |
    # | 4     |  user1 | user1       | status0 | type1 | priority2 | severity3 |      tag1 tag2 tag3 |
    # | 5     |  user3 | user1       | status2 | type2 | priority3 | severity2 |                tag3 |
    # | 6     |  user2 | user1       | status3 | type1 | priority2 | severity0 |      tag1 tag2      |
    # | 7     |  user1 | user2       | status0 | type2 | priority1 | severity3 |                tag3 |
    # | 8     |  user3 | user2       | status3 | type1 | priority0 | severity1 |      tag1           |
    # | 9     |  user2 | user3       | status1 | type2 | priority0 | severity2 | tag0                |
    # ------------------------------------------------------------------------------------------------

    issue0 = f.IssueFactory.create(project=project, owner=user2, assigned_to=None,
                                   status=status3, type=type1, priority=priority2, severity=severity1,
                                   tags=[tag1])
    issue1 = f.IssueFactory.create(project=project, owner=user1, assigned_to=None,
                                   status=status3, type=type2, priority=priority2, severity=severity1,
                                   tags=[tag2])
    issue2 = f.IssueFactory.create(project=project, owner=user3, assigned_to=None,
                                   status=status1, type=type1, priority=priority3, severity=severity2,
                                   tags=[tag1, tag2])
    issue3 = f.IssueFactory.create(project=project, owner=user2, assigned_to=None,
                                   status=status0, type=type2, priority=priority3, severity=severity1,
                                   tags=[tag3])
    issue4 = f.IssueFactory.create(project=project, owner=user1, assigned_to=user1,
                                   status=status0, type=type1, priority=priority2, severity=severity3,
                                   tags=[tag1, tag2, tag3])
    issue5 = f.IssueFactory.create(project=project, owner=user3, assigned_to=user1,
                                   status=status2, type=type2, priority=priority3, severity=severity2,
                                   tags=[tag3])
    issue6 = f.IssueFactory.create(project=project, owner=user2, assigned_to=user1,
                                   status=status3, type=type1, priority=priority2, severity=severity0,
                                   tags=[tag1, tag2])
    issue7 = f.IssueFactory.create(project=project, owner=user1, assigned_to=user2,
                                   status=status0, type=type2, priority=priority1, severity=severity3,
                                   tags=[tag3])
    issue8 = f.IssueFactory.create(project=project, owner=user3, assigned_to=user2,
                                   status=status3, type=type1, priority=priority0, severity=severity1,
                                   tags=[tag1])
    issue9 = f.IssueFactory.create(project=project, owner=user2, assigned_to=user3,
                                   status=status1, type=type2, priority=priority0, severity=severity2,
                                   tags=[tag0])

    url = reverse("issues-filters-data") + "?project={}".format(project.id)

    client.login(user1)

    ## No filter
    response = client.get(url)
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 3

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 4

    assert next(filter(lambda i: i['id'] == type1.id, response.data["types"]))["count"] == 5
    assert next(filter(lambda i: i['id'] == type2.id, response.data["types"]))["count"] == 5

    assert next(filter(lambda i: i['id'] == priority0.id, response.data["priorities"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == priority1.id, response.data["priorities"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == priority2.id, response.data["priorities"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == priority3.id, response.data["priorities"]))["count"] == 3

    assert next(filter(lambda i: i['id'] == severity0.id, response.data["severities"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == severity1.id, response.data["severities"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == severity2.id, response.data["severities"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == severity3.id, response.data["severities"]))["count"] == 2

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 1
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 5
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 4

    ## Filter ((status0 or status3) and type1)
    response = client.get(url + "&status={},{}&type={}".format(status3.id, status0.id, type1.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 3

    assert next(filter(lambda i: i['id'] == type1.id, response.data["types"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == type2.id, response.data["types"]))["count"] == 3

    assert next(filter(lambda i: i['id'] == priority0.id, response.data["priorities"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == priority1.id, response.data["priorities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == priority2.id, response.data["priorities"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == priority3.id, response.data["priorities"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == severity0.id, response.data["severities"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == severity1.id, response.data["severities"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == severity2.id, response.data["severities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == severity3.id, response.data["severities"]))["count"] == 1

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 1

    ## Filter ((tag1 and tag2) and (user1 or user2))
    response = client.get(url + "&tags={},{}&owner={},{}".format(tag1, tag2, user1.id, user2.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == type1.id, response.data["types"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == type2.id, response.data["types"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == priority0.id, response.data["priorities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == priority1.id, response.data["priorities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == priority2.id, response.data["priorities"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == priority3.id, response.data["priorities"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == severity0.id, response.data["severities"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == severity1.id, response.data["severities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == severity2.id, response.data["severities"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == severity3.id, response.data["severities"]))["count"] == 1

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 1

Example 32

Project: taiga-back
Source File: test_tasks.py
View license
def test_api_filters_data(client):
    project = f.ProjectFactory.create()
    user1 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user1, project=project)
    user2 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user2, project=project)
    user3 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user3, project=project)

    status0 = f.TaskStatusFactory.create(project=project)
    status1 = f.TaskStatusFactory.create(project=project)
    status2 = f.TaskStatusFactory.create(project=project)
    status3 = f.TaskStatusFactory.create(project=project)

    tag0 = "test1test2test3"
    tag1 = "test1"
    tag2 = "test2"
    tag3 = "test3"

    # ------------------------------------------------------
    # | Task  |  Owner | Assigned To | Tags                |
    # |-------#--------#-------------#---------------------|
    # | 0     |  user2 | None        |      tag1           |
    # | 1     |  user1 | None        |           tag2      |
    # | 2     |  user3 | None        |      tag1 tag2      |
    # | 3     |  user2 | None        |                tag3 |
    # | 4     |  user1 | user1       |      tag1 tag2 tag3 |
    # | 5     |  user3 | user1       |                tag3 |
    # | 6     |  user2 | user1       |      tag1 tag2      |
    # | 7     |  user1 | user2       |                tag3 |
    # | 8     |  user3 | user2       |      tag1           |
    # | 9     |  user2 | user3       | tag0                |
    # ------------------------------------------------------

    task0 = f.TaskFactory.create(project=project, owner=user2, assigned_to=None,
                                            status=status3, tags=[tag1])
    task1 = f.TaskFactory.create(project=project, owner=user1, assigned_to=None,
                                            status=status3, tags=[tag2])
    task2 = f.TaskFactory.create(project=project, owner=user3, assigned_to=None,
                                            status=status1, tags=[tag1, tag2])
    task3 = f.TaskFactory.create(project=project, owner=user2, assigned_to=None,
                                            status=status0, tags=[tag3])
    task4 = f.TaskFactory.create(project=project, owner=user1, assigned_to=user1,
                                            status=status0, tags=[tag1, tag2, tag3])
    task5 = f.TaskFactory.create(project=project, owner=user3, assigned_to=user1,
                                            status=status2, tags=[tag3])
    task6 = f.TaskFactory.create(project=project, owner=user2, assigned_to=user1,
                                            status=status3, tags=[tag1, tag2])
    task7 = f.TaskFactory.create(project=project, owner=user1, assigned_to=user2,
                                            status=status0, tags=[tag3])
    task8 = f.TaskFactory.create(project=project, owner=user3, assigned_to=user2,
                                            status=status3, tags=[tag1])
    task9 = f.TaskFactory.create(project=project, owner=user2, assigned_to=user3,
                                            status=status1, tags=[tag0])

    url = reverse("tasks-filters-data") + "?project={}".format(project.id)

    client.login(user1)

    ## No filter
    response = client.get(url)
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 3

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 4

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 1
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 5
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 4

    ## Filter ((status0 or status3)
    response = client.get(url + "&status={},{}".format(status3.id, status0.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 4

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 3
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 3

    ## Filter ((tag1 and tag2) and (user1 or user2))
    response = client.get(url + "&tags={},{}&owner={},{}".format(tag1, tag2, user1.id, user2.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == None, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 1

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 1

Example 33

Project: taiga-back
Source File: test_userstories.py
View license
def test_api_filters_data(client):
    project = f.ProjectFactory.create()
    user1 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user1, project=project)
    user2 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user2, project=project)
    user3 = f.UserFactory.create(is_superuser=True)
    f.MembershipFactory.create(user=user3, project=project)

    status0 = f.UserStoryStatusFactory.create(project=project)
    status1 = f.UserStoryStatusFactory.create(project=project)
    status2 = f.UserStoryStatusFactory.create(project=project)
    status3 = f.UserStoryStatusFactory.create(project=project)

    epic0 = f.EpicFactory.create(project=project)
    epic1 = f.EpicFactory.create(project=project)
    epic2 = f.EpicFactory.create(project=project)

    tag0 = "test1test2test3"
    tag1 = "test1"
    tag2 = "test2"
    tag3 = "test3"

    # ------------------------------------------------------------------------------
    # | US    | Status  |  Owner | Assigned To | Tags                | Epic        |
    # |-------#---------#--------#-------------#---------------------#--------------
    # | 0     | status3 |  user2 | None        |      tag1           | epic0       |
    # | 1     | status3 |  user1 | None        |           tag2      | None        |
    # | 2     | status1 |  user3 | None        |      tag1 tag2      | epic1       |
    # | 3     | status0 |  user2 | None        |                tag3 | None        |
    # | 4     | status0 |  user1 | user1       |      tag1 tag2 tag3 | epic0       |
    # | 5     | status2 |  user3 | user1       |                tag3 | None        |
    # | 6     | status3 |  user2 | user1       |      tag1 tag2      | epic0 epic2 |
    # | 7     | status0 |  user1 | user2       |                tag3 | None        |
    # | 8     | status3 |  user3 | user2       |      tag1           | epic2       |
    # | 9     | status1 |  user2 | user3       | tag0                | None        |
    # ------------------------------------------------------------------------------

    us0 = f.UserStoryFactory.create(project=project, owner=user2, assigned_to=None,
                              status=status3, tags=[tag1])
    f.RelatedUserStory.create(user_story=us0, epic=epic0)
    us1 = f.UserStoryFactory.create(project=project, owner=user1, assigned_to=None,
                              status=status3, tags=[tag2])
    us2 = f.UserStoryFactory.create(project=project, owner=user3, assigned_to=None,
                              status=status1, tags=[tag1, tag2])
    f.RelatedUserStory.create(user_story=us2, epic=epic1)
    us3 = f.UserStoryFactory.create(project=project, owner=user2, assigned_to=None,
                              status=status0, tags=[tag3])
    us4 = f.UserStoryFactory.create(project=project, owner=user1, assigned_to=user1,
                              status=status0, tags=[tag1, tag2, tag3])
    f.RelatedUserStory.create(user_story=us4, epic=epic0)
    us5 = f.UserStoryFactory.create(project=project, owner=user3, assigned_to=user1,
                              status=status2, tags=[tag3])
    us6 = f.UserStoryFactory.create(project=project, owner=user2, assigned_to=user1,
                              status=status3, tags=[tag1, tag2])
    f.RelatedUserStory.create(user_story=us6, epic=epic0)
    f.RelatedUserStory.create(user_story=us6, epic=epic2)
    us7 = f.UserStoryFactory.create(project=project, owner=user1, assigned_to=user2,
                              status=status0, tags=[tag3])
    us8 = f.UserStoryFactory.create(project=project, owner=user3, assigned_to=user2,
                              status=status3, tags=[tag1])
    f.RelatedUserStory.create(user_story=us8, epic=epic2)
    us9 = f.UserStoryFactory.create(project=project, owner=user2, assigned_to=user3,
                              status=status1, tags=[tag0])

    url = reverse("userstories-filters-data") + "?project={}".format(project.id)

    client.login(user1)

    # No filter
    response = client.get(url)
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 3

    assert next(filter(lambda i: i['id'] is None, response.data["assigned_to"]))["count"] == 4
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 1

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 4

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 1
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 5
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 4

    assert next(filter(lambda i: i['id'] is None, response.data["epics"]))["count"] == 5
    assert next(filter(lambda i: i['id'] == epic0.id, response.data["epics"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == epic1.id, response.data["epics"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == epic2.id, response.data["epics"]))["count"] == 2

    # Filter ((status0 or status3)
    response = client.get(url + "&status={},{}".format(status3.id, status0.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] is None, response.data["assigned_to"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 4

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 3
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 3

    assert next(filter(lambda i: i['id'] is None, response.data["epics"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == epic0.id, response.data["epics"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == epic1.id, response.data["epics"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == epic2.id, response.data["epics"]))["count"] == 2

    # Filter ((tag1 and tag2) and (user1 or user2))
    response = client.get(url + "&tags={},{}&owner={},{}".format(tag1, tag2, user1.id, user2.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] is None, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 1

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 1

    assert next(filter(lambda i: i['id'] is None, response.data["epics"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == epic0.id, response.data["epics"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == epic1.id, response.data["epics"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == epic2.id, response.data["epics"]))["count"] == 1

    # Filter (epic0 epic2)
    response = client.get(url + "&epic={},{}".format(epic0.id, epic2.id))
    assert response.status_code == 200

    assert next(filter(lambda i: i['id'] == user1.id, response.data["owners"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user2.id, response.data["owners"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user3.id, response.data["owners"]))["count"] == 1

    assert next(filter(lambda i: i['id'] is None, response.data["assigned_to"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user1.id, response.data["assigned_to"]))["count"] == 2
    assert next(filter(lambda i: i['id'] == user2.id, response.data["assigned_to"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == user3.id, response.data["assigned_to"]))["count"] == 0

    assert next(filter(lambda i: i['id'] == status0.id, response.data["statuses"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == status1.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status2.id, response.data["statuses"]))["count"] == 0
    assert next(filter(lambda i: i['id'] == status3.id, response.data["statuses"]))["count"] == 3

    assert next(filter(lambda i: i['name'] == tag0, response.data["tags"]))["count"] == 0
    assert next(filter(lambda i: i['name'] == tag1, response.data["tags"]))["count"] == 4
    assert next(filter(lambda i: i['name'] == tag2, response.data["tags"]))["count"] == 2
    assert next(filter(lambda i: i['name'] == tag3, response.data["tags"]))["count"] == 1

    assert next(filter(lambda i: i['id'] is None, response.data["epics"]))["count"] == 5
    assert next(filter(lambda i: i['id'] == epic0.id, response.data["epics"]))["count"] == 3
    assert next(filter(lambda i: i['id'] == epic1.id, response.data["epics"]))["count"] == 1
    assert next(filter(lambda i: i['id'] == epic2.id, response.data["epics"]))["count"] == 2

Example 34

Project: tendenci
Source File: views.py
View license
@ssl_required
def register(request, success_url=None,
             form_class=RegistrationForm, profile_callback=None,
             template_name='registration/registration_form.html',
             event_id=None,
             extra_context=None):
    """
    Allow a new user to register an account.

    Following successful registration, issue a redirect; by default,
    this will be whatever URL corresponds to the named URL pattern
    ``registration_complete``, which will be
    ``/accounts/register/complete/`` if using the included URLConf. To
    change this, point that named pattern at another URL, or pass your
    preferred URL as the keyword argument ``success_url``.

    By default, ``registration.forms.RegistrationForm`` will be used
    as the registration form; to change this, pass a different form
    class as the ``form_class`` keyword argument. The form class you
    specify must have a method ``save`` which will create and return
    the new ``User``, and that method must accept the keyword argument
    ``profile_callback`` (see below).

    To enable creation of a site-specific user profile object for the
    new user, pass a function which will create the profile object as
    the keyword argument ``profile_callback``. See
    ``RegistrationManager.create_inactive_user`` in the file
    ``models.py`` for details on how to write this function.

    By default, use the template
    ``registration/registration_form.html``; to change this, pass the
    name of a template as the keyword argument ``template_name``.

    **Required arguments**

    None.

    **Optional arguments**

    ``form_class``
        The form class to use for registration.

    ``extra_context``
        A dictionary of variables to add to the template context. Any
        callable object in this dictionary will be called to produce
        the end result which appears in the context.

    ``profile_callback``
        A function which will be used to create a site-specific
        profile instance for the new ``User``.

    ``success_url``
        The URL to redirect to on successful registration.

    ``template_name``
        A custom template to use.

    **Context:**

    ``form``
        The registration form.

    Any extra variables supplied in the ``extra_context`` argument
    (see above).

    **Template:**

    registration/registration_form.html or ``template_name`` keyword
    argument.

    """
    # check if this site allows self registration, if not, redirect to login page
    allow_self_registration = get_setting('module', 'users', 'selfregistration')
    if not allow_self_registration:
        return HttpResponseRedirect(reverse('auth_login'))

    form_params = {}
    if request.session.get('form_params', None):
        form_params = request.session.pop('form_params')

    if request.method == 'POST':
        form = form_class(data=request.POST, files=request.FILES, **form_params)
        if form.is_valid():
            # This is for including a link in the reg email back to the event viewed
            event = None
            if event_id: # the user signed up via an event
                from tendenci.apps.events.models import Event
                event = get_object_or_404(Event, pk=event_id)

            new_user = form.save(profile_callback=profile_callback, event=event)
            # success_url needs to be dynamically generated here; setting a
            # a default value using reverse() will cause circular-import
            # problems with the default URLConf for this application, which
            # imports this file.

            # add to the default group(s)
            default_user_groups =[g.strip() for g in (get_setting('module', 'users', 'defaultusergroup')).split(',')]
            if default_user_groups:
                from tendenci.apps.user_groups.models import Group, GroupMembership
                from django.db.models import Q
                for group_name in default_user_groups:
                    groups = Group.objects.filter(Q(name=group_name) | Q(label=group_name)).filter(allow_self_add=1, status=1, status_detail='active')
                    if groups:
                        group = groups[0]
                    else:
                        # group doesnot exist, so create the group
                        group = Group()
                        group.name  = group_name
                        group.label = group_name
                        group.type = 'distribution'
                        group.show_as_option = 1
                        group.allow_self_add = 1
                        group.allow_self_remove = 1
                        group.creator = new_user
                        group.creator_username = new_user.username
                        group.owner =  new_user
                        group.owner_username = new_user.username
                        try:
                            group.save()
                        except:
                            group = None

                    if group:
                        gm = GroupMembership()
                        gm.group = group
                        gm.member = new_user
                        gm.creator_id = new_user.id
                        gm.creator_username = new_user.username
                        gm.owner_id =  new_user.id
                        gm.owner_username = new_user.username
                        gm.save()


            EventLog.objects.log(instance=new_user)

            return HttpResponseRedirect(success_url or reverse('registration_complete'))
        elif form.similar_email_found:
            messages.add_message(
                request, messages.INFO,
                _(u"An account already exists for the email %(email)s." % {
                    'email': request.POST.get('email_0') or request.POST.get('email_1')}))

            querystring = 'registration=True'
            return HttpResponseRedirect(reverse('auth_password_reset')+ "?%s" % querystring)

    else:
        allow_same_email = request.GET.get('registration_approved', False)
        form_params = {'allow_same_email' : allow_same_email }
        request.session['form_params'] = form_params
        form = form_class(**form_params)

    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
    return render_to_response(template_name,
                              { 'form': form },
                              context_instance=context)

Example 35

Project: tendenci
Source File: views.py
View license
def index(request, form_class=SubmitContactForm, template_name="form.html"):

    if request.method == "GET":
        # event-log view
        EventLog.objects.log(instance=Contact(), action='viewed')

    if request.method == "POST":
        event_log_dict = {}
        form = form_class(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            first_name = form.cleaned_data.get('first_name')
            last_name = form.cleaned_data.get('last_name')

            if listed_in_email_block(email):
                # listed in the email blocks - it's a spam email we want to block
                # log the spam
                EventLog.objects.log()

                # redirect normally so they don't suspect
                return HttpResponseRedirect(reverse('form.confirmation'))

            address = form.cleaned_data.get('address')
            city = form.cleaned_data.get('city')
            state = form.cleaned_data.get('state')
            zipcode = form.cleaned_data.get('zipcode')
            country = form.cleaned_data.get('country')
            phone = form.cleaned_data.get('phone')
            url = form.cleaned_data.get('url')
            message = form.cleaned_data.get('message')

            exists = User.objects.filter(
                first_name__iexact=first_name,
                last_name__iexact=last_name,
                email__iexact=email,
            ).exists()

            if request.user.is_anonymous():
                username = first_name.replace(' ', '')
                if last_name:
                    username = username + '_' + last_name.replace(' ', '')
                username = username.lower()
                try:
                    User.objects.get(username=username)
                    x = User.objects.filter(first_name=first_name).count()
                    username = username + '_' + unicode(x)
                except User.DoesNotExist:
                    pass

                contact_user = User(
                    username=username,
                    email=email,
                    first_name=first_name,
                    last_name=last_name,
                )

                contact_user.is_active = False
                contact_user.save()
                profile = Profile(user=contact_user, owner=contact_user, creator=User.objects.get(pk=1),
                                  address=address, country=country, city=city, state=state,
                                  url=url, phone=phone, zipcode=zipcode)
                profile.save()
                sf_id = create_salesforce_contact(profile)

                # if exists:
                #     event_log_dict['description'] = 'logged-out submission as existing user'
                # else:
                event_log_dict['description'] = 'logged-out submission as new user'

            else:  # logged in user
                self_submit = all([
                    request.user.first_name.lower().strip() == first_name.lower().strip(),
                    request.user.last_name.lower().strip() == last_name.lower().strip(),
                    request.user.email.lower().strip() == email.lower().strip(),
                ])

                contact_user = request.user

                if exists:
                    if self_submit:
                        event_log_dict['description'] = 'logged-in submission as self'
                    else:
                        event_log_dict['description'] = 'logged-in submission as existing user'
                else:
                    event_log_dict['description'] = 'logged-in submission as non-existing user'

            contact_kwargs = {
                'first_name': first_name,
                'last_name': last_name,
                'message': message,
                'user': contact_user,
            }

            contact = Contact(**contact_kwargs)
            contact.allow_anonymous_view = False
            contact.save()

            if address or city or state or zipcode or country:
                address_kwargs = {
                    'address': address,
                    'city': city,
                    'state': state,
                    'zipcode': zipcode,
                    'country': country,
                }
                obj_address = Address(**address_kwargs)
                obj_address.save()  # saves object
                contact.addresses.add(obj_address)  # saves relationship

            if phone:
                obj_phone = Phone(number=phone)
                obj_phone.save()  # saves object
                contact.phones.add(obj_phone)  # saves relationship

            if email:
                obj_email = Email(email=email)
                obj_email.save()  # saves object
                contact.emails.add(obj_email)  # saves relationship

            if url:
                obj_url = URL(url=url)
                obj_url.save()  # saves object
                contact.urls.add(obj_url)  # saves relationship

            site_name = get_setting('site', 'global', 'sitedisplayname')
            message_link = get_setting('site', 'global', 'siteurl')

            # send notification to administrators
            # get admin notice recipients
            recipients = get_notice_recipients('module', 'contacts', 'contactrecipients')
            if recipients:
                if notification:
                    extra_context = {
                    'reply_to': email,
                    'contact': contact,
                    'first_name': first_name,
                    'last_name': last_name,
                    'address': address,
                    'city': city,
                    'state': state,
                    'zipcode': zipcode,
                    'country': country,
                    'phone': phone,
                    'email': email,
                    'url': url,
                    'message': message,
                    'message_link': message_link,
                    'site_name': site_name,
                    }
                    notification.send_emails(recipients, 'contact_submitted', extra_context)

            # event-log (logged in)
            event_log = EventLog.objects.log(
                instance=contact,
                user=contact_user,
                action='submitted',
                **event_log_dict
            )

            event_log.url = contact.get_absolute_url()
            event_log.save()

            return HttpResponseRedirect(reverse('form.confirmation'))
        else:
            return render_to_response(template_name, {'form': form},
                context_instance=RequestContext(request))

    form = form_class()
    return render_to_response(template_name, {'form': form},
        context_instance=RequestContext(request))

Example 36

View license
    def handle(self, *args, **options):
        verbosity = 1
        if 'verbosity' in options:
            verbosity = options['verbosity']
        # first test if we have notices set up
        from tendenci.apps.corporate_memberships.models import Notice
        if not Notice.objects.filter(status=True,
                                     status_detail='active'
                                    ).exclude(
                                    notice_time='attimeof'
                                    ).exists():
            if verbosity > 1:
                print('No notices set up...existing...')
            # no active notices to process. stop here
            return

        from tendenci.apps.corporate_memberships.models import (
            CorpMembership, CorpMembershipApp,
            NoticeLog,
            NoticeLogRecord)
        from tendenci.apps.notifications import models as notification
        from tendenci.apps.base.utils import fieldify
        from tendenci.apps.site_settings.utils import get_setting

        site_display_name = get_setting('site', 'global', 'sitedisplayname')
        site_contact_name = get_setting('site', 'global', 'sitecontactname')
        site_contact_email = get_setting('site', 'global', 'sitecontactemail')
        site_url = get_setting('site', 'global', 'siteurl')

        email_context = {
            'sender':get_setting('site', 'global', 'siteemailnoreplyaddress'),
            'sender_display':site_display_name,
            'reply_to':site_contact_email}

        now = datetime.now()
        nowstr = time.strftime("%d-%b-%y %I:%M %p", now.timetuple())

        def email_admins_recap(notices, total_sent):
            """Send admins recap after the notices were processed.
            """
            recap_recipient = get_admin_emails()
            if recap_recipient:
                template_name = "corporate_memberships/notices/email_recap.html"
                try:
                    recap_email_content = render_to_string(
                               template_name,
                               {'notices': notices,
                              'total_sent': total_sent,
                              'site_url': site_url,
                              'site_display_name': site_display_name,
                              'site_contact_name': site_contact_name,
                              'site_contact_email': site_contact_email})
                    recap_subject = '%s Corporate Membership Notices Distributed' % (
                                                    site_display_name)
                    email_context.update({
                        'subject':recap_subject,
                        'content': recap_email_content,
                        'content_type':"html"})

                    notification.send_emails(recap_recipient, 'corp_memb_notice_email',
                                             email_context)
                except TemplateDoesNotExist:
                    pass

        def email_script_errors(err_msg):
            """Send error message to us if any.
            """
            script_recipient = get_script_support_emails()
            if script_recipient:
                email_context.update({
                    'subject':'Error Processing Corporate Membership Notices on %s' % (
                                                            site_url),
                    'content':'%s \n\nTime Submitted: %s\n' % (err_msg, nowstr),
                    'content_type':"text"})

                notification.send_emails(script_recipient, 'corp_memb_notice_email',
                                         email_context)

        def get_script_support_emails():
            admins = getattr(settings, 'ADMINS', None)
            if admins:
                recipients_list = [admin[1] for admin in admins]
                return recipients_list
            return None

        def get_admin_emails():
            admin_emails = get_setting('module', 'corporate_memberships',
                                       'corporatemembershiprecipients').strip()
            if admin_emails:
                admin_emails = admin_emails.split(',')
            if not admin_emails:
                admin_emails = (get_setting('site', 'global',
                                            'admincontactemail'
                                            ).strip()).split(',')
            return admin_emails

        def process_notice(notice):
            notice.members_sent = []
            num_sent = 0
            if notice.notice_time == 'before':
                start_dt = now + timedelta(days=notice.num_days)
            else:
                start_dt = now - timedelta(days=notice.num_days)

            if notice.notice_type == 'disapprove':
                status_detail_list = ['inactive']
            else:
                status_detail_list = ['active', 'expired']

            memberships = CorpMembership.objects.filter(
                                    status=True,
                                    status_detail__in=status_detail_list
                                    )
            if notice.notice_type in ['approve_join', 'disapprove_join'
                                      'approve_renewal', 'disapprove_renewal']:
                filters = {'approved_denied_dt__year': start_dt.year,
                           'approved_denied_dt__month': start_dt.month,
                           'approved_denied_dt__day': start_dt.day,
                           'renewal': False,
                           'approved': True
                           }
                if notice.notice_type in ['approve_renewal',
                                          'disapprove_renewal']:
                    filters.update({'renewal': True})
                if notice.notice_type in ['disapprove_join',
                                          'disapprove_renewal']:
                    filters.update({'approved': False})

                memberships = memberships.filter(**filters)
            else:  # 'expire'
                memberships = memberships.filter(
                    expiration_dt__year=start_dt.year,
                    expiration_dt__month=start_dt.month,
                    expiration_dt__day=start_dt.day)

            # filter by membership type
            if notice.corporate_membership_type:
                memberships = memberships.filter(
                                corporate_membership_type=notice.corporate_membership_type)

            memberships_count = memberships.count()

            if memberships_count > 0:
                email_context.update({'content_type':notice.content_type})

                global_context = {'site_display_name': site_display_name,
                                  'site_contact_name': site_contact_name,
                                  'site_contact_email': site_contact_email,
                                  'time_submitted': nowstr,
                                  }

                # log notice sent
                notice_log = NoticeLog(notice=notice,
                                       num_sent=0)
                notice_log.save()
                notice.log = notice_log
                notice.err = ''

                for membership in memberships:
                    try:
                        num_sent += email_member(notice, membership, global_context)
                        if memberships_count <= 50:
                            notice.members_sent.append(membership)

                        # log record
                        notice_log_record = NoticeLogRecord(
                            notice_log=notice_log,
                            corp_membership=membership)
                        notice_log_record.save()
                    except:
                        # catch the exception and email
                        notice.err += traceback.format_exc()
                        print traceback.format_exc()

                if num_sent > 0:
                    notice_log.num_sent = num_sent
                    notice_log.save()

            return num_sent

        def email_member(notice, membership, global_context):
            corp_profile = membership.corp_profile
            representatives = corp_profile.reps.filter(Q(is_dues_rep=True)|(Q(is_member_rep=True)))
            sent = 0

            corp_app = CorpMembershipApp.objects.current_app()
            authentication_info = render_to_string(
                'notification/corp_memb_notice_email/auth_info.html',
                {'corp_membership': membership,
                 'corp_app': corp_app})
            individuals_join_url = '%s%s' % (site_url,
                                             reverse('membership_default.corp_pre_add',
                                                     args=[membership.id]))
            if membership.expiration_dt:
                expire_dt = time.strftime("%d-%b-%y %I:%M %p",
                                          membership.expiration_dt.timetuple())
            else:
                expire_dt = ''

            if membership.payment_method:
                payment_method = membership.payment_method.human_name
            else:
                payment_method = ''

            if membership.renewal:
                renewed_individuals_list = render_to_string(
                    'notification/corp_memb_notice_email/renew_list.html',
                    {'corp_membership': membership})
                total_individuals_renewed = membership.indivmembershiprenewentry_set.count()
            else:
                renewed_individuals_list = ''
                total_individuals_renewed = ''

            if membership.invoice:
                invoice_link = '%s%s' % (site_url,
                                         membership.invoice.get_absolute_url())
            else:
                invoice_link = ''

            global_context.update({
                'name': corp_profile.name,
                'email': corp_profile.email,
                'expire_dt': expire_dt,
                'payment_method': payment_method,
                'renewed_individuals_list': renewed_individuals_list,
                'total_individuals_renewed': total_individuals_renewed,
                'view_link': "%s%s" % (site_url, membership.get_absolute_url()),
                'renew_link': "%s%s" % (site_url, membership.get_renewal_url()),
                'invoice_link': invoice_link,
                'authentication_info': authentication_info,
                'individuals_join_url': individuals_join_url,
            })

            for recipient in representatives:
                body = notice.email_content
                context = membership.get_field_items()
                context['membership'] = membership
                context.update(global_context)

                context.update({
                    'rep_first_name': recipient.user.first_name,
                })

                body = fieldify(body)

                body = '%s <br /><br />%s' % (body, get_footer())

                context = Context(context)
                template = Template(body)
                body = template.render(context)

                email_recipient = recipient.user.email
                subject = notice.subject.replace('(name)',
                                            corp_profile.name)
                template = Template(subject)
                subject = template.render(context)

                email_context.update({
                    'subject':subject,
                    'content':body})

                if notice.sender:
                    email_context.update({
                        'sender':notice.sender,
                        'reply_to':notice.sender})
                if notice.sender_display:
                    email_context.update({'sender_display':notice.sender_display})

                notification.send_emails([email_recipient], 'corp_memb_notice_email',
                                         email_context)
                sent += 1
                if verbosity > 1:
                    print 'To ', email_recipient, subject
            return sent

        def get_footer():
            return """
                    This e-mail was generated by Tendenci&reg; Software -
                    a web based membership management software solution
                    www.tendenci.com developed by Schipul - The Web
                    Marketing Company
                    """

        exception_str = ""

        notices = Notice.objects.filter(status=True, status_detail='active'
                                    ).exclude(notice_time='attimeof')

        if notices:
            if verbosity > 1:
                print "Start sending out notices to members:"
            total_notices = 0
            total_sent = 0
            for notice in notices:
                total_notices += 1
                total_sent += process_notice(notice)
                if hasattr(notice, 'err'):
                    exception_str += notice.err

            if total_sent > 0:
                processed_notices = [notice for notice in notices if hasattr(
                                        notice, 'log'
                                        ) and notice.log.num_sent > 0]
                email_admins_recap(processed_notices, total_sent)

            # if there is any error, notify us
            if exception_str:
                email_script_errors(exception_str)

            if verbosity > 1:
                print 'Total notice processed: %d' % (total_notices)
                print 'Total email sent: %d' % (total_sent)
                print "Done"
        else:
            if verbosity > 1:
                print "No notices on the site."

Example 37

Project: tendenci
Source File: views.py
View license
@is_enabled('jobs')
@login_required
def add(request, form_class=JobForm, template_name="jobs/add.html",
        object_type=Job, success_redirect='job', thankyou_redirect='job.thank_you'):

    require_payment = get_setting('module', 'jobs',
                                    'jobsrequirespayment')

    can_add_active = has_perm(request.user, 'jobs.add_job')

    content_type = get_object_or_404(
        ContentType,
        app_label=object_type._meta.app_label,
        model=object_type._meta.model_name
    )

    if request.user.profile.is_superuser:
        category_form_class = CategoryForm
    else:
        category_form_class = CategoryForm2

    form = form_class(request.POST or None, request.FILES or None, user=request.user)
    # adjust the fields depending on user type
    if not require_payment:
        del form.fields['payment_method']
        del form.fields['list_type']

    if request.method == "POST":
        if require_payment:
            is_free = is_free_listing(request.user,
                               request.POST.get('pricing', 0),
                               request.POST.get('list_type'))
            if is_free:
                del form.fields['payment_method']

        categoryform = category_form_class(
                        content_type,
                        request.POST,)

        if form.is_valid() and categoryform.is_valid():
            job = form.save(commit=False)
            pricing = form.cleaned_data['pricing']

            if require_payment and is_free:
                job.payment_method = 'paid - cc'

            # set it to pending if the user is anonymous or not an admin
            if not can_add_active:
                #job.status = 1
                job.status_detail = 'pending'

            # list types and duration
            if not job.requested_duration:
                job.requested_duration = 30
            if not job.list_type:
                job.list_type = 'regular'

            # set up all the times
            now = datetime.now()
            job.activation_dt = now
            if not job.post_dt:
                job.post_dt = now

            # set the expiration date
            job.expiration_dt = job.activation_dt + timedelta(
                                        days=job.requested_duration)

            # semi-anon job posts don't get a slug field on the form
            # see __init__ method in JobForm
            if not job.slug:
                #job.slug = get_job_unique_slug(slugify(job.title))
                job.slug = '%s-%s' % (slugify(job.title),
                                        object_type.objects.count())

            job = update_perms_and_save(request, form, job)

            # create invoice
            job_set_inv_payment(request.user, job, pricing)

            #setup categories
            category = Category.objects.get_for_object(job, 'category')
            sub_category = Category.objects.get_for_object(
                                                job, 'sub_category')

            ## update the category of the job
            category_removed = False
            category = categoryform.cleaned_data['category']
            if category != '0':
                Category.objects.update(job, category, 'category')
            else:  # remove
                category_removed = True
                Category.objects.remove(job, 'category')
                Category.objects.remove(job, 'sub_category')

            if not category_removed:
                # update the sub category of the job
                sub_category = categoryform.cleaned_data['sub_category']
                if sub_category != '0':
                    Category.objects.update(job, sub_category,
                                                'sub_category')
                else:  # remove
                    Category.objects.remove(job,'sub_category')

            #save relationships
            job.save()
            msg_string = 'Successfully added %s' % job
            messages.add_message(request, messages.SUCCESS,_(msg_string))

            # send notification to administrators
            recipients = get_notice_recipients(
                            'module', 'jobs', 'jobrecipients')
            if recipients:
                if notification:
                    extra_context = {
                        'object': job,
                        'request': request,
                    }
                    notification.send_emails(recipients, 'job_added',
                                                extra_context)

            # send user to the payment page if payment is required
            if require_payment:
                if job.payment_method.lower() in ['credit card', 'cc']:
                    if job.invoice and job.invoice.balance > 0:
                        return HttpResponseRedirect(reverse(
                            'payment.pay_online',
                            args=[job.invoice.id, job.invoice.guid])
                        )

            # send user to thank you or view page
            if request.user.profile.is_superuser:
                return HttpResponseRedirect(
                        reverse(success_redirect, args=[job.slug]))
            else:
                return HttpResponseRedirect(reverse(thankyou_redirect))
    else:
        # Redirect user w/perms to create pricing if none exist
        pricings = JobPricing.objects.all()
        if not pricings and has_perm(request.user, 'jobs.add_jobpricing'):
            msg_string = 'You need to add a %s Pricing before you can add a %s.' % (get_setting('module', 'jobs', 'label_plural'),get_setting('module', 'jobs', 'label'))
            messages.add_message(request, messages.WARNING, _(msg_string))
            return HttpResponseRedirect(reverse('job_pricing.add'))

        initial_category_form_data = {
            'app_label': 'jobs',
            'model': 'job',
            'pk': 0, #not used for this view but is required for the form
        }
        categoryform = category_form_class(
                        content_type,
                        initial=initial_category_form_data,)

    return render_to_response(template_name,
            {'form': form,
             'require_payment': require_payment,
             'categoryform': categoryform},
            context_instance=RequestContext(request))

Example 38

Project: tendenci
Source File: send_membership_notices.py
View license
    def handle(self, *args, **options):
        verbosity = 1
        if 'verbosity' in options:
            verbosity = options['verbosity']

        from django.conf import settings
        from tendenci.apps.memberships.models import (Notice,
                                                        MembershipDefault,
                                                        NoticeLog,
                                                        NoticeDefaultLogRecord)
        from tendenci.apps.base.utils import fieldify
        from tendenci.apps.notifications import models as notification
        from tendenci.apps.site_settings.utils import get_setting

        site_display_name = get_setting('site', 'global', 'sitedisplayname')
        site_contact_name = get_setting('site', 'global', 'sitecontactname')
        site_contact_email = get_setting('site', 'global', 'sitecontactemail')
        site_url = get_setting('site', 'global', 'siteurl')

        corp_replace_str = """
                            <br /><br />
                            <font color="#FF0000">
                            Organizational Members, please contact your company
                            Membership coordinator
                            to ensure that your membership is being renewed.
                            </font>
                            """

        email_context = {
            'sender':get_setting('site', 'global', 'siteemailnoreplyaddress'),
            'sender_display':site_display_name,
            'reply_to':site_contact_email}

        now = datetime.now()
        nowstr = time.strftime("%d-%b-%y %I:%M %p", now.timetuple())

        def email_admins_recap(notices, total_sent):
            """Send admins recap after the notices were processed.
            """
            recap_recipient = get_admin_emails()
            if recap_recipient:
                template_name = "memberships/notices/email_recap.html"
                try:
                    recap_email_content = render_to_string(
                               template_name,
                               {'notices': notices,
                              'total_sent': total_sent,
                              'site_url': site_url,
                              'site_display_name': site_display_name,
                              'site_contact_name': site_contact_name,
                              'site_contact_email': site_contact_email})
                    recap_subject = '%s Membership Notices Distributed' % (
                                                    site_display_name)
                    email_context.update({
                        'subject':recap_subject,
                        'content': recap_email_content,
                        'content_type':"html"})

                    notification.send_emails(recap_recipient, 'membership_notice_email',
                                             email_context)
                except TemplateDoesNotExist:
                    pass

        def email_script_errors(err_msg):
            """Send error message to us if any.
            """
            script_recipient = get_script_support_emails()
            if script_recipient:
                email_context.update({
                    'subject':'Error Processing Membership Notices on %s' % (
                                                            site_url),
                    'content':'%s \n\nTime Submitted: %s\n' % (err_msg, nowstr),
                    'content_type':"text"})

                notification.send_emails(script_recipient, 'membership_notice_email',
                                         email_context)

        def get_script_support_emails():
            admins = getattr(settings, 'ADMINS', None)
            if admins:
                recipients_list = [admin[1] for admin in admins]
                return recipients_list

            return None

        def get_admin_emails():
            admin_emails = get_setting('module', 'memberships',
                                       'membershiprecipients').strip()
            if admin_emails:
                admin_emails = admin_emails.split(',')
            if not admin_emails:
                admin_emails = (get_setting('site', 'global',
                                            'admincontactemail'
                                            ).strip()).split(',')
            return admin_emails

        def process_notice(notice):
            notice.members_sent = []
            num_sent = 0
            if notice.notice_time == 'before':
                start_dt = now + timedelta(days=notice.num_days)
            else:
                start_dt = now - timedelta(days=notice.num_days)

            if notice.notice_type == 'disapprove':
                status_detail_list = ['disapproved']
            else:
                status_detail_list = ['active', 'expired']
            memberships = MembershipDefault.objects.filter(
                                    status=True,
                                    status_detail__in=status_detail_list
                                    )
            if notice.notice_type == 'join':
                memberships = memberships.filter(
                                    join_dt__year=start_dt.year,
                                    join_dt__month=start_dt.month,
                                    join_dt__day=start_dt.day,
                                    renewal=False)
            elif notice.notice_type == 'renewal':
                memberships = memberships.filter(
                                    renew_dt__year=start_dt.year,
                                    renew_dt__month=start_dt.month,
                                    renew_dt__day=start_dt.day,
                                    renewal=True)
            elif notice.notice_type == 'approve':
                memberships = memberships.filter(
                                    application_approved_denied_dt__year=start_dt.year,
                                    application_approved_denied_dt__month=start_dt.month,
                                    application_approved_denied_dt__day=start_dt.day,
                                    application_approved=True)
            elif notice.notice_type == 'disapprove':
                memberships = memberships.filter(
                                    application_approved_denied_dt__year=start_dt.year,
                                    application_approved_denied_dt__month=start_dt.month,
                                    application_approved_denied_dt__day=start_dt.day,
                                    application_approved=False)
            else:  # 'expire'
                memberships = memberships.filter(
                                    expire_dt__year=start_dt.year,
                                    expire_dt__month=start_dt.month,
                                    expire_dt__day=start_dt.day)
                if get_setting('module', 'memberships', 'renewalreminderexcludecorpmembers'):
                    # exclude corp members
                    memberships = memberships.exclude(corporate_membership_id__gt=0)

            # filter by membership type
            if notice.membership_type:
                memberships = memberships.filter(
                                membership_type=notice.membership_type)

            memberships_count = memberships.count()

            if memberships_count > 0:
                email_context.update({'content_type':notice.content_type})

                # password
                passwd_str = """
                        If you've forgotten your password or need to reset
                        the auto-generated one, click <a href="%s%s">here</a>
                        and follow the instructions on the page to
                        reset your password.
                        """ % (site_url, reverse('auth_password_reset'))

                global_context = {'site_display_name': site_display_name,
                                  'site_contact_name': site_contact_name,
                                  'site_contact_email': site_contact_email,
                                  'time_submitted': nowstr,
                                  'sitedisplayname': site_display_name,
                                  'sitecontactname': site_contact_name,
                                  'sitecontactemail': site_contact_email,
                                  'timesubmitted': nowstr,
                                  'password': passwd_str
                                  }

                # log notice sent
                notice_log = NoticeLog(notice=notice,
                                       num_sent=0)
                notice_log.save()
                notice.log = notice_log
                notice.err = ''

                for membership in memberships:
                    try:
                        email_member(notice, membership, global_context)
                        if memberships_count <= 50:
                            notice.members_sent.append(membership)
                        num_sent += 1

                        # log record
                        notice_log_record = NoticeDefaultLogRecord(
                                                notice_log=notice_log,
                                                membership=membership)
                        notice_log_record.save()
                    except:
                        # catch the exception and email
                        notice.err += traceback.format_exc()
                        print traceback.format_exc()

                if num_sent > 0:
                    notice_log.num_sent = num_sent
                    notice_log.save()

            return num_sent

        def email_member(notice, membership, global_context):
            user = membership.user

            body = notice.email_content
            context = membership.get_field_items()
            context['membership'] = membership
            context.update(global_context)

            # corporate member corp_replace_str
            if membership.corporate_membership_id:
                context['corporate_membership_notice'] = corp_replace_str

            if membership.expire_dt:
                context.update({
                    'expire_dt': time.strftime(
                    "%d-%b-%y %I:%M %p",
                    membership.expire_dt.timetuple()),
                })

            if membership.payment_method:
                payment_method_name = membership.payment_method.human_name
            else:
                payment_method_name = ''

            context.update({
                'member_number': membership.member_number,
                'payment_method': payment_method_name,
                'referer_url': '%s%s?next=%s' % (site_url, reverse('auth_login'), membership.referer_url),
                'membership_link': '%s%s' % (site_url, membership.get_absolute_url()),
                'renew_link': '%s%s' % (site_url, membership.get_absolute_url()),
                'mymembershipslink': '%s%s' % (site_url, membership.get_absolute_url()),
                'membershiplink': '%s%s' % (site_url, membership.get_absolute_url()),
                'renewlink': '%s%s' % (site_url, membership.get_absolute_url())
            })

            body = fieldify(body)

            body = '%s <br /><br />%s' % (body, get_footer())

            context = Context(context)
            template = Template(body)
            body = template.render(context)

            email_recipient = user.email
            subject = notice.subject.replace('(name)',
                                        user.get_full_name())
            template = Template(subject)
            subject = template.render(context)

            email_context.update({
                'subject':subject,
                'content':body})
            if notice.sender:
                email_context.update({
                    #'sender':notice.sender,
                    'reply_to':notice.sender})
            if notice.sender_display:
                email_context.update({'sender_display':notice.sender_display})

            notification.send_emails([email_recipient], 'membership_notice_email',
                                     email_context)
            if verbosity > 1:
                print 'To ', email_recipient, subject

        def get_footer():
            return """
                    This e-mail was generated by Tendenci&reg; Software -
                    a web based membership management software solution
                    www.tendenci.com developed by Schipul - The Web
                    Marketing Company
                    """

        exception_str = ""

        notices = Notice.objects.filter(status=True, status_detail='active'
                                    ).exclude(notice_time='attimeof')

        if notices:
            if verbosity > 1:
                print "Start sending out notices to members:"
            total_notices = 0
            total_sent = 0
            for notice in notices:
                total_notices += 1
                total_sent += process_notice(notice)
                if hasattr(notice, 'err'):
                    exception_str += notice.err

            if total_sent > 0:
                processed_notices = [notice for notice in notices if hasattr(
                                        notice, 'log'
                                        ) and notice.log.num_sent > 0]
                email_admins_recap(processed_notices, total_sent)

            # if there is any error, notify us
            if exception_str:
                email_script_errors(exception_str)

            if verbosity > 1:
                print 'Total notice processed: %d' % (total_notices)
                print 'Total email sent: %d' % (total_sent)
                print "Done"
        else:
            if verbosity > 1:
                print "No notices on the site."

Example 39

Project: tendenci
Source File: utils.py
View license
def api_rp_setup(data):
    """Create a recurrring payment account. Accepted format: json

    Input fields:
        email - required
        description - required
        amount - required
        cp_id - customer profile id, required
        pp_id - customer payment profile id, required
        billing_cycle_start_dt - required
        billing_cycle_end_dt - required
        response_str - required
        login_name
        login_password
        url
        first_name
        last_name


        billing_period - optional, default to 'month'
        billing_frequency - optional, default to 1
        billing_start_dt - optional, default to today
        num_days - optional, default to 0
        has_trial_period - optional, default to False
        trial_period_start_dt - optional, default to today
        trial_period_end_dt - optional, default to today
        trial_amount - optional, default to 0

    Output:
        rp_id - a recurring payment id
        rp_url - url to rp
        username
        result_code
    """
    from decimal import Decimal
    from tendenci.apps.base.utils import validate_email
    import dateutil.parser as dparser
    from tendenci.apps.imports.utils import get_unique_username

    email = data.get('email', '')
    description = data.get('description', '')
    url = data.get('url')
    payment_amount = data.get('amount', '')
    taxable = data.get('taxable', 0)
    if taxable in ('True', 'true', '1', 1):
        taxable = 1
    else:
        taxable = 0
    try:
        tax_rate = Decimal(data.get('tax_rate', 0))
        if tax_rate > 1: tax_rate = 0
    except:
        tax_rate = 0
    tax_exempt = data.get('tax_exempt', 0)
    if tax_exempt in ('True', 'true', '1', 1):
        tax_exempt = 1
    else:
        tax_exempt = 0
    try:
        payment_amount = Decimal(payment_amount)
    except:
        payment_amount = 0
    cp_id = data.get('cp_id')
    pp_id = data.get('pp_id')
    billing_cycle_start_dt = data.get('billing_cycle_start_dt')
    if billing_cycle_start_dt:
        billing_cycle_start_dt = dparser.parse(billing_cycle_start_dt)
    billing_cycle_end_dt = data.get('billing_cycle_end_dt')
    if billing_cycle_end_dt:
        billing_cycle_end_dt = dparser.parse(billing_cycle_end_dt)

    direct_response_str = data.get('response_str')

    if not all([validate_email(email),
                description,
                payment_amount>0,
                cp_id,
                pp_id,
                billing_cycle_start_dt,
                billing_cycle_end_dt,
                direct_response_str]
               ):
        return False, {}

    # 1) get or create user
    username = data.get('login_name')

    # check if user already exists based on email and username
    users = User.objects.filter(email=email, username=username)
    if users:
        u = users[0]
    else:
        # create user account
        u = User()
        u.email=email
        u.username = username
        if not u.username:
            u.username = email.split('@')[0]
        u.username = get_unique_username(u)
        raw_password = data.get('login_password')
        if not raw_password:
            raw_password = User.objects.make_random_password(length=8)
        u.set_password(raw_password)
        u.first_name = data.get('first_name', '')
        u.last_name = data.get('last_name', '')
        u.is_staff = False
        u.is_superuser = False
        u.save()

        profile = Profile.objects.create(
           user=u,
           creator=u,
           creator_username=u.username,
           owner=u,
           owner_username=u.username,
           email=u.email
        )

    # 2) create a recurring payment account
    rp = RecurringPayment()
    rp.user = u
    rp.description = description
    rp.url = url
    rp.payment_amount = payment_amount
    rp.taxable = taxable
    rp.tax_rate = tax_rate
    rp.tax_exempt = tax_exempt
    rp.customer_profile_id = cp_id
    rp.billing_start_dt = billing_cycle_start_dt

    has_trial_period = data.get('has_trial_period')
    trial_period_start_dt = data.get('trial_period_start_dt')
    trial_period_end_dt = data.get('trial_period_end_dt')
    if has_trial_period in ['True', '1',  True, 1] and all([trial_period_start_dt,
                                                            trial_period_end_dt]):
        rp.has_trial_period = True
        rp.trial_period_start_dt = dparser.parse(trial_period_start_dt)
        rp.trial_period_end_dt = dparser.parse(trial_period_end_dt)
    else:
        rp.has_trial_period = False

    rp.status_detail = 'active'
    rp.save()

    # 3) create a payment profile account
    payment_profile_exists = PaymentProfile.objects.filter(
                                        customer_profile_id=cp_id,
                                        payment_profile_id=pp_id
                                        ).exists()
    if not payment_profile_exists:
        PaymentProfile.objects.create(
                        customer_profile_id=cp_id,
                        payment_profile_id=pp_id,
                        owner=u,
                        owner_username=u.username
                        )

    # 4) create rp invoice
    billing_cycle = {'start': billing_cycle_start_dt,
                     'end': billing_cycle_end_dt}
    rp_invoice = rp.create_invoice(billing_cycle, billing_cycle_start_dt)
    rp_invoice.invoice.tender(rp.user)

    # 5) create rp transaction
    now = datetime.now()
    payment = Payment()
    payment.payments_pop_by_invoice_user(rp.user,
                                         rp_invoice.invoice,
                                         rp_invoice.invoice.guid)
    payment_transaction = PaymentTransaction(
                                    recurring_payment=rp,
                                    recurring_payment_invoice=rp_invoice,
                                    payment_profile_id=pp_id,
                                    trans_type='auth_capture',
                                    amount=rp_invoice.invoice.total,
                                    status=True)
    payment = payment_update_from_response(payment, direct_response_str)
    payment.mark_as_paid()
    payment.save()
    rp_invoice.invoice.make_payment(rp.user, Decimal(payment.amount))
    rp_invoice.invoice.save()


    rp_invoice.payment_received_dt = now
    rp_invoice.save()
    rp.last_payment_received_dt = now
    rp.num_billing_cycle_completed += 1
    rp.save()

    payment_transaction.payment = payment
    payment_transaction.result_code = data.get('result_code')
    payment_transaction.message_code = data.get('message_code')
    payment_transaction.message_text = data.get('message_text')

    payment_transaction.save()

    site_url = get_setting('site', 'global', 'siteurl')


    return True, {'rp_id': rp.id,
                  'rp_url': '%s%s' %  (site_url,
                                reverse('recurring_payment.view_account', args=[rp.id])),
                  'username': rp.user.username}

Example 40

Project: hubplus
Source File: views.py
View license
def details(request, id, template_name="photos/details.html"):
    """
    show the photo details
    """
    photo = get_object_or_404(Image, id=id)
    # @@@: test
    if not photo.is_public and request.user != photo.member:
        raise Http404
    photo_url = photo.get_display_url()
    
    tribes = []
    projects = []
    
    # Build a list of tribes and the photos from the pool
    for tribe in Tribe.objects.filter(members=request.user):
        phototribe = Tribe.objects.get(pk=tribe.id)
        if phototribe.photos.filter(photo=photo).count():
            tribes.append({
                "name": tribe.name,
                "slug": tribe.slug,
                "id": tribe.id,
                "has_photo": True,
            })
        else:
            tribes.append({
                "name": tribe.name,
                "slug": tribe.slug,
                "id": tribe.id,
                "has_photo": False,
            })

    # Build a list of projects and the photos from the pool
    for project in Project.objects.filter(members__user=request.user):
        photoproject = Project.objects.get(pk=project.id)
        if photoproject.photos.filter(photo=photo).count():
            projects.append({
                "name": project.name,
                "slug": project.slug,
                "id": project.id,
                "has_photo": True,
            })
        else:
            projects.append({
                "name": project.name,
                "slug": project.slug,
                "id": project.id,
                "has_photo": False,
            })

    title = photo.title
    host = "http://%s" % get_host(request)
    if photo.member == request.user:
        is_me = True
    else:
        is_me = False
    # TODO: check for authorized user and catch errors
    if is_me:
        if request.method == "POST" and request.POST["action"] == "add_to_project":
            projectid = request.POST["project"]
            myproject = Project.objects.get(pk=projectid)
            if not myproject.photos.filter(photo=photo).count():
                myproject.photos.create(photo=photo)
                request.user.message_set.create(message=_("Successfully add photo '%s' to project") % title)
            else:
                # TODO: this applies to pinax in general. dont use ugettext_lazy here. its usage is fragile.
                request.user.message_set.create(message=_("Did not add photo '%s' to project because it already exists.") % title)

            return HttpResponseRedirect(reverse('photo_details', args=(photo.id,)))
        
        if request.method == "POST":
            if request.POST["action"] == "addtotribe":
                tribeid = request.POST["tribe"]
                mytribe = Tribe.objects.get(pk=tribeid)
                if not mytribe.photos.filter(photo=photo).count():
                    mytribe.photos.create(photo=photo)
                    request.user.message_set.create(message=_("Successfully add photo '%s' to tribe") % title)
                else:
                    # TODO: this applies to pinax in general. dont use ugettext_lazy here. its usage is fragile.
                    request.user.message_set.create(message=_("Did not add photo '%s' to tribe because it already exists.") % title)

                return HttpResponseRedirect(reverse('photo_details', args=(photo.id,)))

            if request.POST["action"] == "removefromtribe":
                tribeid = request.POST["tribe"]
                mytribe = Tribe.objects.get(pk=tribeid)
                if mytribe.photos.filter(photo=photo).count():
                    mytribe.photos.filter(photo=photo).delete()
                    request.user.message_set.create(message=_("Successfully removed photo '%s' from tribe") % title)
                else:
                    # TODO: this applies to pinax in general. dont use ugettext_lazy here. its usage is fragile.
                    request.user.message_set.create(message=_("Did not remove photo '%s' from tribe.") % title)

                return HttpResponseRedirect(reverse('photo_details', args=(photo.id,)))

            if request.POST["action"] == "addtoproject":
                projectid = request.POST["project"]
                myproject = Project.objects.get(pk=projectid)
                if not myproject.photos.filter(photo=photo).count():
                    myproject.photos.create(photo=photo)
                    request.user.message_set.create(message=_("Successfully add photo '%s' to project") % title)
                else:
                    # TODO: this applies to pinax in general. dont use ugettext_lazy here. its usage is fragile.
                    request.user.message_set.create(message=_("Did not add photo '%s' to project because it already exists.") % title)

                return HttpResponseRedirect(reverse('photo_details', args=(photo.id,)))

            if request.POST["action"] == "removefromproject":
                projectid = request.POST["project"]
                myproject = Project.objects.get(pk=projectid)
                if myproject.photos.filter(photo=photo).count():
                    myproject.photos.filter(photo=photo).delete()
                    request.user.message_set.create(message=_("Successfully removed photo '%s' from project") % title)
                else:
                    # TODO: this applies to pinax in general. dont use ugettext_lazy here. its usage is fragile.
                    request.user.message_set.create(message=_("Did not remove photo '%s' from project.") % title)

                return HttpResponseRedirect(reverse('photo_details', args=(photo.id,)))

    return render_to_response(template_name, {
        "host": host, 
        "photo": photo,
        "photo_url": photo_url,
        "is_me": is_me,
        "projects": projects,
        "tribes": tribes,
    }, context_instance=RequestContext(request))

Example 41

Project: hubplus
Source File: models.py
View license
def patch_user_class():
    """access biz_type, introduced_by and postcode through prefixing 'md_' e.g user.md_biz_type.
    """
    from apps.plus_groups.models import TgGroup, User_Group  
    User._meta.db_table = 'tg_user'
    # Patching the User class
    User.add_to_class('__getattr__',  __getattr__)
    User.add_to_class('__setattr__',  __setattr__)

    # EXPERIMENT ... make username alias of user_name
    User.add_to_class('user_name', UserNameField(unique=True, max_length=255))
    #User.add_to_class('user_name',models.CharField(max_length=255,unique=True))
    #del User.username
    #User.add_to_class('username',AliasOf('user_name'))                      
    # EXPERIMENT END

    User.add_to_class('email_address', models.CharField(max_length=255,unique=True))

    #remove the existing django groups relation  
    gr = User._meta.get_field('groups')
    User._meta.local_many_to_many.remove(gr)
    del User.groups
    # add ours new relation for groups
    User.add_to_class('groups', models.ManyToManyField(TgGroup, through=User_Group, related_name='users'))

    User.add_to_class('description', models.TextField())
    User.add_to_class('organisation', models.CharField(max_length=255)) 
    User.add_to_class('title', models.CharField(max_length=255,null=True))
    User.add_to_class('mobile', models.CharField(max_length=30))
    User.add_to_class('work', models.CharField(max_length=30))
    User.add_to_class('home', models.CharField(max_length=30))
    User.add_to_class('fax', models.CharField(max_length=30))
    User.add_to_class('place', models.CharField(max_length=150, null=True))

    User.add_to_class('created',models.DateTimeField(default=datetime.datetime.now))
    User.add_to_class('email2',models.CharField(max_length=255))
    User.add_to_class('email3',models.CharField(max_length=255))
    User.add_to_class('skype_id',models.TextField())
    User.add_to_class('sip_id',models.TextField())
    User.add_to_class('website',models.TextField())
    User.add_to_class('homeplace', models.ForeignKey(Location, null=True))
    User.add_to_class('address', models.TextField())
    User.add_to_class('country', models.CharField(null=True, default="", max_length=2))

    User.add_to_class('homehub', models.ForeignKey("plus_groups.TgGroup", null=True)) # we need this for PSN, XXX need to decide how to make it compatible with hubspace for hub+ 

    User.add_to_class('psn_id', models.CharField(max_length=50,null=True))
    User.add_to_class('psn_password_hmac_key', models.CharField(max_length=50, null=True)) #this is just for the bizare hmacing of psn passwords by a field formly known as "fullname"

    User.add_to_class('cc_messages_to_email',models.BooleanField(default=False)) # internal messages get reflected to email

    User.add_to_class('has_avatar', models.BooleanField(default=False))

    User.email = AliasOf('email_address')
    if settings.PROJECT_THEME == 'plus':
       User.post_or_zip = AliasOf('md_postcode')
       User.add_to_class('public_field', models.SmallIntegerField(null=True)) # this will be phased out as it is redundant with the new permissions system
    else:
       User.add_to_class('post_or_zip', models.CharField(null=True, default="", max_length=30))
    
    User.is_active = AliasOf('active') # This takes precedence over the existing is_active field in django.contrib.auth.models
    User.add_to_class('active', models.SmallIntegerField(null=True)) # not currently shown, however setting this to 0 will stop the user logging in

    #User.add_to_class('image', models.CharField(null=True, default="", max_length= XXXX)


    User.set_password = set_password
    User.check_password = check_password
    User.is_member_of = is_member_of
    User.is_direct_member_of = is_direct_member_of
    User.get_enclosures = get_enclosures
    User.get_enclosure_set = get_enclosure_set
    User.is_group = lambda(self) : False
    User.is_user = lambda(self) : True

    User.save = user_save
    User.post_save = post_save

    User.is_admin_of = lambda self, group : self.is_member_of(group.get_admin_group())

    def is_site_admin(self) :
       from apps.plus_permissions.default_agents import get_all_members_group
       return self.is_admin_of(get_all_members_group())
    User.is_site_admin = is_site_admin

    def send_tweet(self, msg) :
       from apps.microblogging.models import send_tweet
       return send_tweet(self, msg)
    User.send_tweet = send_tweet

    def message(self, sender, subject, body, message_extra="") :

       if not self.active :
          return # don't send messages to inactive members

       from messages.models import Message
       from django.core.mail import send_mail
       from django.core.urlresolvers import reverse
       from django.utils.translation import ugettext_lazy as _, ugettext
       
       m = Message(subject=subject, body=body, sender = sender, recipient=self)
       m.save()

       if self.cc_messages_to_email :
          # recipient wants emails cc-ed 
          link = 'http://' + settings.DOMAIN_NAME + reverse('messages_all')
          settings_link = 'http://' + settings.DOMAIN_NAME + reverse('acct_settings')
          main = _(""" 
%(sender)s has sent you a new message on %(account_name)s .

---------------------------------------------------------------

%(body)s

---------------------------------------------------------------


Click %(link)s to see your account.

If you do not want to receive emails when you receive messages on %(account_name)s, please change your settings here : %(settings_link)s

%(message_extra)s

""") % {'account_name':settings.SITE_NAME, 'body':body, 'link':link, 'sender':sender.get_display_name(), 'settings_link':settings_link, "message_extra":message_extra}

          self.email_user(subject, main, settings.SERVER_EMAIL)

       return m

    User.message = message


    def group_invite_message(self, group, invited_by, accept_url, special_message='') :

       self.message(invited_by, 
                    Template(settings.GROUP_INVITE_SUBJECT_TEMPLATE).render(
             Context({'group_name':group.get_display_name() })),
                    Template(settings.GROUP_INVITE_TEMPLATE).render(
             Context({
                   'first_name':self.first_name,
                   'last_name':self.last_name,
                   'sponsor':invited_by.get_display_name(),
                   'group_name':group.get_display_name(),
                   'site_name':settings.SITE_NAME,
                   'special_message':special_message,
                   'signup_link':accept_url,
                   })
             )+"""
%s""" % accept_url
                    )
    
    User.group_invite_message = group_invite_message


    User.hubs = lambda self : self.groups.filter(group_type=settings.GROUP_HUB_TYPE,level='member')

    User.change_avatar = lambda self : True

    def is_following(self, other_user) :
       from apps.microblogging.models import Following
       return Following.objects.is_following(self, other_user)

    User.is_following = is_following

    def is_followed_by(self, other_user) :
       from apps.microblogging.models import Following
       return Following.objects.is_following(other_user, self)

    User.is_followed_by = is_followed_by

    AnonymousUser.is_member_of = lambda *args, **kwargs : False
    AnonymousUser.is_direct_member_of = lambda *args, **kwarg : False

Example 42

Project: modoboa
Source File: test_import_.py
View license
    def test_identities_import(self):
        f = ContentFile(b"""
account; [email protected]; toto; User; One; True; SimpleUsers; [email protected]; 0
account; [email protected]; toto; René; Truc; True; DomainAdmins; [email protected]; 5; test.com
alias; [email protected]; True; [email protected]
forward; [email protected]; True; [email protected]
forward; [email protected]; True; [email protected]
dlist; [email protected]; True; [email protected]; [email protected]
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        admin = User.objects.get(username="admin")
        u1 = User.objects.get(username="[email protected]")
        mb1 = u1.mailbox
        self.assertTrue(admin.is_owner(u1))
        self.assertEqual(u1.email, "[email protected]")
        self.assertEqual(u1.first_name, "User")
        self.assertEqual(u1.last_name, "One")
        self.assertTrue(u1.is_active)
        self.assertEqual(u1.role, "SimpleUsers")
        self.assertTrue(mb1.use_domain_quota)
        self.assertEqual(mb1.quota, 0)
        self.assertTrue(admin.is_owner(mb1))
        self.assertEqual(mb1.full_address, "[email protected]")
        self.assertTrue(
            self.client.login(username="[email protected]", password="toto")
        )

        da = User.objects.get(username="[email protected]")
        damb = da.mailbox
        self.assertEqual(da.first_name, u"René")
        self.assertEqual(da.role, "DomainAdmins")
        self.assertEqual(damb.quota, 5)
        self.assertFalse(damb.use_domain_quota)
        self.assertEqual(damb.full_address, "[email protected]")
        dom = Domain.objects.get(name="test.com")
        self.assertIn(da, dom.admins)
        u = User.objects.get(username="[email protected]")
        self.assertTrue(da.can_access(u))

        al = Alias.objects.get(address="[email protected]")
        self.assertTrue(
            al.aliasrecipient_set
            .filter(r_mailbox=u1.mailbox).exists()
        )
        self.assertTrue(admin.is_owner(al))

        fwd = Alias.objects.get(address="[email protected]")
        self.assertTrue(
            fwd.aliasrecipient_set
            .filter(
                address="[email protected]", r_mailbox__isnull=True,
                r_alias__isnull=True)
            .exists()
        )
        self.assertTrue(admin.is_owner(fwd))

        dlist = Alias.objects.get(address="[email protected]")
        self.assertTrue(
            dlist.aliasrecipient_set
            .filter(r_mailbox=u1.mailbox).exists()
        )
        self.assertTrue(
            dlist.aliasrecipient_set.filter(address="[email protected]")
            .exists()
        )
        self.assertTrue(admin.is_owner(dlist))

    def test_import_for_nonlocal_domain(self):
        """Try to import an account for nonlocal domain."""
        f = ContentFile(b"""
account; [email protected]; toto; User; One; True; SimpleUsers; [email protected]; 0
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        self.assertFalse(
            User.objects.filter(username="[email protected]").exists())

    def test_import_invalid_quota(self):
        f = ContentFile(b"""
account; [email protected]; toto; User; One; True; SimpleUsers; [email protected]; ; test.com
""", name="identities.csv")
        resp = self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        self.assertIn('wrong quota value', resp.content)

    def test_import_domain_by_domainadmin(self):
        """Check if a domain admin is not allowed to import a domain."""
        self.client.logout()
        self.client.login(username="[email protected]", password="toto")
        f = ContentFile(b"""
domain; domain2.com; 200; False
""", name="identities.csv")
        resp = self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        self.assertIn("You are not allowed to import domains", resp.content)
        f = ContentFile(b"""
domainalias; domalias1.com; test.com; True
""", name="identities.csv")
        resp = self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        self.assertIn(
            "You are not allowed to import domain aliases", resp.content)

    def test_import_quota_too_big(self):
        self.client.logout()
        self.client.login(username="[email protected]", password="toto")
        f = ContentFile(b"""
account; [email protected]; toto; User; One; True; SimpleUsers; [email protected]; 20
""", name="identities.csv")
        resp = self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        self.assertIn('Quota is greater than the allowed', resp.content)

    def test_import_missing_quota(self):
        f = ContentFile(b"""
account; [email protected]; toto; User; One; True; SimpleUsers; [email protected]
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True}
        )
        account = User.objects.get(username="[email protected]")
        self.assertEqual(
            account.mailbox.quota,
            account.mailbox.domain.quota
        )

    def test_import_duplicate(self):
        f = ContentFile(b"""
account; [email protected]; toto; Admin; ; True; DomainAdmins; [email protected]; 0; test.com
account; [email protected]; toto; René; Truc; True; DomainAdmins; [email protected]; 0; test.com
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True,
             "continue_if_exists": True}
        )
        admin = User.objects.get(username="admin")
        u1 = User.objects.get(username="[email protected]")
        self.assertTrue(admin.is_owner(u1))

    def test_import_superadmin(self):
        """Check if a domain admin can import a superadmin

        Expected result: no
        """
        self.client.logout()
        self.assertTrue(
            self.client.login(username="[email protected]", password="toto")
        )
        f = ContentFile(b"""
account; [email protected]; toto; Super; Admin; True; SuperAdmins; [email protected]; 50
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True,
             "continue_if_exists": True}
        )
        with self.assertRaises(User.DoesNotExist):
            User.objects.get(username="[email protected]")

    def test_import_alias_with_empty_values(self):
        f = ContentFile(b"""
alias;[email protected];True;[email protected];;;;;;;;;;;;;;;;
""", name="identities.csv")
        self.client.post(
            reverse("admin:identity_import"),
            {"sourcefile": f, "crypt_password": True,
             "continue_if_exists": True}
        )
        alias = Alias.objects.get(address="[email protected]")
        self.assertEqual(alias.type, "alias")

Example 43

Project: wagtail
Source File: pages.py
View license
def create(request, content_type_app_name, content_type_model_name, parent_page_id):
    parent_page = get_object_or_404(Page, id=parent_page_id).specific
    parent_page_perms = parent_page.permissions_for_user(request.user)
    if not parent_page_perms.can_add_subpage():
        raise PermissionDenied

    try:
        content_type = ContentType.objects.get_by_natural_key(content_type_app_name, content_type_model_name)
    except ContentType.DoesNotExist:
        raise Http404

    # Get class
    page_class = content_type.model_class()

    # Make sure the class is a descendant of Page
    if not issubclass(page_class, Page):
        raise Http404

    # page must be in the list of allowed subpage types for this parent ID
    if page_class not in parent_page.creatable_subpage_models():
        raise PermissionDenied

    if not page_class.can_create_at(parent_page):
        raise PermissionDenied

    for fn in hooks.get_hooks('before_create_page'):
        result = fn(request, parent_page, page_class)
        if hasattr(result, 'status_code'):
            return result

    page = page_class(owner=request.user)
    edit_handler_class = page_class.get_edit_handler()
    form_class = edit_handler_class.get_form_class(page_class)

    next_url = get_valid_next_url_from_request(request)

    if request.method == 'POST':
        form = form_class(request.POST, request.FILES, instance=page,
                          parent_page=parent_page)

        if form.is_valid():
            page = form.save(commit=False)

            is_publishing = bool(request.POST.get('action-publish')) and parent_page_perms.can_publish_subpage()
            is_submitting = bool(request.POST.get('action-submit'))

            if not is_publishing:
                page.live = False

            # Save page
            parent_page.add_child(instance=page)

            # Save revision
            revision = page.save_revision(
                user=request.user,
                submitted_for_moderation=is_submitting,
            )

            # Publish
            if is_publishing:
                revision.publish()

            # Notifications
            if is_publishing:
                if page.go_live_at and page.go_live_at > timezone.now():
                    messages.success(request, _("Page '{0}' created and scheduled for publishing.").format(page.get_admin_display_title()), buttons=[
                        messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
                    ])
                else:
                    messages.success(request, _("Page '{0}' created and published.").format(page.get_admin_display_title()), buttons=[
                        messages.button(page.url, _('View live')),
                        messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
                    ])
            elif is_submitting:
                messages.success(
                    request,
                    _("Page '{0}' created and submitted for moderation.").format(page.get_admin_display_title()),
                    buttons=[
                        messages.button(reverse('wagtailadmin_pages:view_draft', args=(page.id,)), _('View draft')),
                        messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit'))
                    ]
                )
                if not send_notification(page.get_latest_revision().id, 'submitted', request.user.pk):
                    messages.error(request, _("Failed to send notifications to moderators"))
            else:
                messages.success(request, _("Page '{0}' created.").format(page.get_admin_display_title()))

            for fn in hooks.get_hooks('after_create_page'):
                result = fn(request, page)
                if hasattr(result, 'status_code'):
                    return result

            if is_publishing or is_submitting:
                # we're done here
                if next_url:
                    # redirect back to 'next' url if present
                    return redirect(next_url)
                # redirect back to the explorer
                return redirect('wagtailadmin_explore', page.get_parent().id)
            else:
                # Just saving - remain on edit page for further edits
                target_url = reverse('wagtailadmin_pages:edit', args=[page.id])
                if next_url:
                    # Ensure the 'next' url is passed through again if present
                    target_url += '?next=%s' % urlquote(next_url)
                return redirect(target_url)
        else:
            messages.error(request, _("The page could not be created due to validation errors"))
            edit_handler = edit_handler_class(instance=page, form=form)
            has_unsaved_changes = True
    else:
        signals.init_new_page.send(sender=create, page=page, parent=parent_page)
        form = form_class(instance=page)
        edit_handler = edit_handler_class(instance=page, form=form)
        has_unsaved_changes = False

    return render(request, 'wagtailadmin/pages/create.html', {
        'content_type': content_type,
        'page_class': page_class,
        'parent_page': parent_page,
        'edit_handler': edit_handler,
        'preview_modes': page.preview_modes,
        'form': form,
        'next': next_url,
        'has_unsaved_changes': has_unsaved_changes,
    })

Example 44

Project: wagtail
Source File: pages.py
View license
def edit(request, page_id):
    latest_revision = get_object_or_404(Page, id=page_id).get_latest_revision()
    page = get_object_or_404(Page, id=page_id).get_latest_revision_as_page()
    parent = page.get_parent()

    content_type = ContentType.objects.get_for_model(page)
    page_class = content_type.model_class()

    page_perms = page.permissions_for_user(request.user)
    if not page_perms.can_edit():
        raise PermissionDenied

    for fn in hooks.get_hooks('before_edit_page'):
        result = fn(request, page)
        if hasattr(result, 'status_code'):
            return result

    edit_handler_class = page_class.get_edit_handler()
    form_class = edit_handler_class.get_form_class(page_class)

    next_url = get_valid_next_url_from_request(request)

    errors_debug = None

    if request.method == 'POST':
        form = form_class(request.POST, request.FILES, instance=page,
                          parent_page=parent)

        if form.is_valid() and not page.locked:
            page = form.save(commit=False)

            is_publishing = bool(request.POST.get('action-publish')) and page_perms.can_publish()
            is_submitting = bool(request.POST.get('action-submit'))
            is_reverting = bool(request.POST.get('revision'))

            # If a revision ID was passed in the form, get that revision so its
            # date can be referenced in notification messages
            if is_reverting:
                previous_revision = get_object_or_404(page.revisions, id=request.POST.get('revision'))

            # Save revision
            revision = page.save_revision(
                user=request.user,
                submitted_for_moderation=is_submitting,
            )

            # Publish
            if is_publishing:
                revision.publish()
                # Need to reload the page because the URL may have changed, and we
                # need the up-to-date URL for the "View Live" button.
                page = page.specific_class.objects.get(pk=page.pk)

            # Notifications
            if is_publishing:
                if page.go_live_at and page.go_live_at > timezone.now():
                    # Page has been scheduled for publishing in the future

                    if is_reverting:
                        message = _(
                            "Revision from {0} of page '{1}' has been scheduled for publishing."
                        ).format(
                            previous_revision.created_at.strftime("%d %b %Y %H:%M"),
                            page.get_admin_display_title()
                        )
                    else:
                        message = _(
                            "Page '{0}' has been scheduled for publishing."
                        ).format(
                            page.get_admin_display_title()
                        )

                    messages.success(request, message, buttons=[
                        messages.button(
                            reverse('wagtailadmin_pages:edit', args=(page.id,)),
                            _('Edit')
                        )
                    ])

                else:
                    # Page is being published now

                    if is_reverting:
                        message = _(
                            "Revision from {0} of page '{1}' has been published."
                        ).format(
                            previous_revision.created_at.strftime("%d %b %Y %H:%M"),
                            page.get_admin_display_title()
                        )
                    else:
                        message = _(
                            "Page '{0}' has been published."
                        ).format(
                            page.get_admin_display_title()
                        )

                    messages.success(request, message, buttons=[
                        messages.button(
                            page.url,
                            _('View live')
                        ),
                        messages.button(
                            reverse('wagtailadmin_pages:edit', args=(page_id,)),
                            _('Edit')
                        )
                    ])

            elif is_submitting:

                message = _(
                    "Page '{0}' has been submitted for moderation."
                ).format(
                    page.get_admin_display_title()
                )

                messages.success(request, message, buttons=[
                    messages.button(
                        reverse('wagtailadmin_pages:view_draft', args=(page_id,)),
                        _('View draft')
                    ),
                    messages.button(
                        reverse('wagtailadmin_pages:edit', args=(page_id,)),
                        _('Edit')
                    )
                ])

                if not send_notification(page.get_latest_revision().id, 'submitted', request.user.pk):
                    messages.error(request, _("Failed to send notifications to moderators"))

            else:  # Saving

                if is_reverting:
                    message = _(
                        "Page '{0}' has been replaced with revision from {1}."
                    ).format(
                        page.get_admin_display_title(),
                        previous_revision.created_at.strftime("%d %b %Y %H:%M")
                    )
                else:
                    message = _(
                        "Page '{0}' has been updated."
                    ).format(
                        page.get_admin_display_title()
                    )

                messages.success(request, message)

            for fn in hooks.get_hooks('after_edit_page'):
                result = fn(request, page)
                if hasattr(result, 'status_code'):
                    return result

            if is_publishing or is_submitting:
                # we're done here - redirect back to the explorer
                if next_url:
                    # redirect back to 'next' url if present
                    return redirect(next_url)
                # redirect back to the explorer
                return redirect('wagtailadmin_explore', page.get_parent().id)
            else:
                # Just saving - remain on edit page for further edits
                target_url = reverse('wagtailadmin_pages:edit', args=[page.id])
                if next_url:
                    # Ensure the 'next' url is passed through again if present
                    target_url += '?next=%s' % urlquote(next_url)
                return redirect(target_url)
        else:
            if page.locked:
                messages.error(request, _("The page could not be saved as it is locked"))
            else:
                messages.error(request, _("The page could not be saved due to validation errors"))

            edit_handler = edit_handler_class(instance=page, form=form)
            errors_debug = (
                repr(edit_handler.form.errors) +
                repr([
                    (name, formset.errors)
                    for (name, formset) in edit_handler.form.formsets.items()
                    if formset.errors
                ])
            )
            has_unsaved_changes = True
    else:
        form = form_class(instance=page)
        edit_handler = edit_handler_class(instance=page, form=form)
        has_unsaved_changes = False

    # Check for revisions still undergoing moderation and warn
    if latest_revision and latest_revision.submitted_for_moderation:
        messages.warning(request, _("This page is currently awaiting moderation"))

    return render(request, 'wagtailadmin/pages/edit.html', {
        'page': page,
        'content_type': content_type,
        'edit_handler': edit_handler,
        'errors_debug': errors_debug,
        'preview_modes': page.preview_modes,
        'form': form,
        'next': next_url,
        'has_unsaved_changes': has_unsaved_changes,
    })

Example 45

Project: transifex
Source File: validation.py
View license
    def test_push_translation_plural_strings(self):
        """Test the push translation view warnings and errors"""

        cases = {
            200: [{
                # 'source': ('trans', 'message')
                    'one': 'foo1',
                    'other': 'foo5',
                    'message': '',
                    'translations': {
                        'one': 'foo1',
                        'other': 'foo5',},
                }, {
                    'one': 'foo1',
                    'other': 'foo5\n',
                    'message': '',
                    'translations': {
                        'one': 'foo1',
                        'other': 'foo5\n',},
                }, {
                    'one': 'foo1\n',
                    'other': 'foo5',
                    'message': '',
                    'translations': {
                        'one': 'foo1\n',
                        'other': 'foo5',},
                }, {
                    'one': 'foo(',
                    'other': 'foo5',
                    'message': 'Translation string doesn\'t contain the same',
                    'translations': {
                        'one': 'foo',
                        'other': 'foo5)',},
                }, {
                    'one': 'foo{',
                    'other': 'foo5',
                    'message': 'Translation string doesn\'t contain the same',
                    'translations': {
                        'one': 'foo{}',
                        'other': 'foo5',},
                }, {
                    'one': 'foo[',
                    'other': 'foo5]',
                    'message': 'Translation string doesn\'t contain the same',
                    'translations': {
                        'one': 'foo[',
                        'other': 'foo5[]',},
                }, {
                    'one': 'email [email protected]',
                    'other': 'no email',
                    'message': '',
                    'translations': {
                        'one': 'email [email protected]',
                        'other': 'no email',},
                }, {
                    'one': 'email [email protected]',
                    'other': 'no email',
                    'message': 'The following email is either missing from the',
                    'translations': {
                        'one': 'no email',
                        'other': 'email [email protected]',},
                }, {
                    'one': 'url http://goatse.cx',
                    'other': 'no url',
                    'message': '',
                    'translations': {
                        'one': 'url http://goatse.cx',
                        'other': 'no url',},
                }, {
                    'one': 'url http://goatse.cx',
                    'other': 'no url',
                    'message': 'The following url is either missing from the',
                    'translations': {
                        'one': 'no url',
                        'other': 'url http://goatse.cx',},
                }, {
                    'one': 'foo1',
                    'other': 'foo5',
                    'message': 'Number 5 is in the source string but not',
                    'translations': {
                        'one': 'foo1',
                        'other': 'foo',},
                }, {
                    'one': 'foo1',
                    'other': 'foo5',
                    'message': 'Number 1 is in the source string but not',
                    'translations': {
                        'one': 'foo',
                        'other': 'foo5',},
                }, {
                    'one': '1 animal was hurt for this unit test',
                    'other': '%(count)s animals were hurt for this unit test',
                    'message': '',
                    'translations': {
                        'one': '1 animals was hurt for this unit test',
                        'other': '%(count)s animals were hurt for this unit test',},
                }, {
                    'one': '%(count)s animals were hurt for this unit test',
                    'other': '%(count)s animals were hurt for this unit test',
                    'message': '',
                    'translations': {
                        'one': '%(count)s animals were hurt for this unit test',
                        'other': '%(count)s animals were hurt for this unit test',},
                }, {
                    'one': 'foo1\n',
                    'other': 'foo5\n',
                    'message': '',
                    'translations': {
                        'one': 'foo1\n',
                        'other': 'foo5\n',},
                }],
            400: [{
                    'one': '1 animal was hurt for this unit test',
                    'other': '%(count)s animals were hurt for this unit test',
                    'message': 'The number of arguments seems to differ',
                    'translations': {
                        'one': '1 animals was hurt for this unit test',
                        'other': 'A lot of animals were hurt for this unit test',},
                }, {
                    'one': '1 animal was hurt for this unit test',
                    'other': '%(count)s animals were hurt for this unit test',
                    'message': 'The number of arguments seems to differ',
                    'translations': {
                        'one': '%(count) animals was hurt for this unit test',
                        'other': '%(count) animals were hurt for this unit test',},
                }, {
                    'one': 'efoo1\n',
                    'other': 'efoo5',
                    'message': 'Translation must end with a newline',
                    'translations': {
                        'one': 'efoo1',
                        'other': 'efoo5',},
                }, {
                    'one': 'efoo1',
                    'other': 'efoo5',
                    'message': 'Translation should not end with a newline',
                    'translations': {
                        'one': 'efoo1\n',
                        'other': 'efoo5',},
                }, {
                    'one': 'efoo1',
                    'other': 'efoo5',
                    'message': 'Cannot save unless plural translations are either',
                    'translations': {
                        'one': '',
                        'other': 'efoo5',},
                }, {
                    'one': 'efoo1',
                    'other': 'efoo5',
                    'message': 'Cannot save unless plural translations are either',
                    'translations': {
                        'one': 'efoo1',
                        'other': '',},
                }]
        }


        source_translation_1 = self.source_entity_plural.get_translation(self.language_en.code,
            rule=1)
        if not source_translation_1:
            self.source_entity_plural.translations.create(
                string='default',
                rule=1,
                source_entity=self.source_entity_plural,
                language=self.language_en,
                user=self.user['registered'],
                resource=self.resource
            )
            source_translation_1 = self.source_entity_plural.get_translation(self.language_en.code,
                rule=1)

        source_translation_5 = self.source_entity_plural.get_translation(self.language_en.code,
            rule=5)
        if not source_translation_5:
            self.source_entity_plural.translations.create(
                string='default',
                rule=5,
                source_entity=self.source_entity_plural,
                language=self.language_en,
                user=self.user['registered'],
                resource=self.resource
            )
            source_translation_5 = self.source_entity_plural.get_translation(self.language_en.code,
                rule=5)

        for code in cases.keys():
            for item in cases[code]:
                source_1 = item['one']
                source_5 = item['other']
                message = item['message']
                trans_1 = item['translations']['one']
                trans_5 = item['translations']['other']
                source_translation_1.string = source_1
                source_translation_1.save()
                source_translation_5.string = source_5
                source_translation_5.save()
                resp = self.client['maintainer'].post(reverse('push_translation',
                    args=[self.project.slug, self.language.code]),
                    json.dumps({'strings':[{'id':source_translation_5.id,
                        'translations':{'other':trans_5, 'one':trans_1}}]}),
                    content_type='application/json')
                if message:
                    self.assertTrue(message in resp.content, "Message '%s'"\
                        " couldn't be found in the response." % message)
                self.assertEqual(resp.status_code, 200)
                self.assertEqual(Translation.objects.filter(source_entity__resource=self.resource,
                    language = self.language, string=trans_5,rule=5).count(),
                    1 if code == 200 else 0)
                self.assertEqual(Translation.objects.filter(source_entity__resource=self.resource,
                    language = self.language, string=trans_1,rule=1).count(),
                    1 if code == 200 else 0)

                    # Update existing translation
                resp = self.client['maintainer'].post(reverse('push_translation',
                    args=[self.project.slug, self.language.code]),
                    json.dumps({'strings':[{'id':source_translation_5.id,
                        'translations':{'other':trans_5, 'one':trans_1}}]}),
                    content_type='application/json')
                if message:
                    self.assertTrue(message in resp.content, "Message '%s'"\
                        " couldn't be found in the response." % message)
                self.assertEqual(resp.status_code, 200)
                self.assertEqual(Translation.objects.filter(source_entity__resource=self.resource,
                    language = self.language, string=trans_5,rule=5).count(),
                    1 if code == 200 else 0)
                self.assertEqual(Translation.objects.filter(source_entity__resource=self.resource,
                    language = self.language, string=trans_1,rule=1).count(),
                    1 if code == 200 else 0)

Example 46

Project: transifex
Source File: permissions.py
View license
    def test_anon(self):
        """
        Test anonymous user
        """
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project.slug, self.resource.slug,self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        resp = self.client['anonymous'].get(reverse('resource_detail',
            args=[self.project.slug, self.resource.slug]))
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['anonymous'].post(reverse('project_resources',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['anonymous'].post(reverse('project_resources_more',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check that anonymous user is redirected to signin page
        page_url = reverse('clone_translate',
            args=[self.project.slug, self.resource.slug, self.language_en.code,
                  self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

        #PRIVATE PROJECT CHECKS
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        resp = self.client['anonymous'].get(reverse('resource_detail',
            args=[self.project_private.slug, self.resource_private.slug]))
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_ar.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['anonymous'].post(reverse('project_resources',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 403)
        resp = self.client['anonymous'].post(reverse('project_resources_more',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 403)

        # Check that anonymous user is redirected to signin page
        page_url = reverse('clone_translate',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_en.code,
                  self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['anonymous'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)
        resp = self.client['anonymous'].post(page_url)
        self.assertEqual(resp.status_code, 302)
        self.assertRedirects(resp, '/accounts/signin/?next=%s' % page_url)

Example 47

Project: transifex
Source File: permissions.py
View license
    def test_registered(self):
        """
        Test random registered user
        """
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project.slug, self.resource.slug,self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['registered'].post(reverse('project_resources',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['registered'].post(reverse('project_resources_more',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project.slug, self.resource.slug, self.language_en.code,
                  self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check 'lock and get translation file' perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 302)

        # PRIVATE PROJECT CHECKS
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_ar.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['registered'].post(reverse('project_resources',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(reverse('project_resources_more',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 403)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_en.code,
                  self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check 'lock and get translation file' perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['registered'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['registered'].post(page_url)
        self.assertEqual(resp.status_code, 403)

Example 48

Project: transifex
Source File: permissions.py
View license
    def test_team_member(self):
        """
        Test team_member permissions
        """
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project.slug, self.resource.slug,self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted
        page_url = reverse('resource_delete',
            args=[self.project.slug, self.resource.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
                           args=[self.project.slug, self.resource.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
                           args=[self.project.slug, self.resource.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['team_member'].post(reverse('project_resources',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(reverse('project_resources_more',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project.slug, self.resource.slug, self.language_en.code,
                  self.language.code])
        resp = self.client['team_member'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        # Check cloning to a non team-member language
        page_url = reverse('clone_translate',
            args=[self.project.slug, self.resource.slug, self.language_en.code,
                  self.language_ar.code])
        resp = self.client['team_member'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 403)

        # Check lock and get translation file perms for resource not accepting
        # translations.
        self.resource.accept_translations = False
        self.resource.save()
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)
        self.resource.accept_translations = True
        self.resource.save()

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 302)

        # PRIVATE PROJECT CHECKS
        # Delete Translations
        page_url = reverse('resource_translations_delete',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if resource gets deleted
        page_url = reverse('resource_delete',
            args=[self.project_private.slug, self.resource_private.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
                           args=[self.project_private.slug,
                                 self.resource_private.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
                           args=[self.project_private.slug,
                                 self.resource_private.slug])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 403)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['team_member'].post(reverse('project_resources',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(reverse('project_resources_more',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_en.code, self.language.code])
        resp = self.client['team_member'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        # Check cloning to a non team-member language
        page_url = reverse('clone_translate',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_en.code, self.language_ar.code])
        resp = self.client['team_member'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['team_member'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 403)

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['team_member'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['team_member'].post(page_url)
        self.assertEqual(resp.status_code, 302)

Example 49

Project: transifex
Source File: permissions.py
View license
    def test_maintainer(self):
        """
        Test maintainer permissions
        """
        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
                           args=[self.project.slug, self.resource.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
                           args=[self.project.slug, self.resource.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url, follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['maintainer'].post(reverse('project_resources',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(reverse('project_resources_more',
            args=[self.project.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project.slug, self.resource.slug, self.language_en.code,
                  self.language.code])
        resp = self.client['maintainer'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check lock and get translation file perms for resource not accepting
        # translations.
        self.resource.accept_translations = False
        self.resource.save()
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 403)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 403)
        self.resource.accept_translations = True
        self.resource.save()

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project.slug, self.resource.slug, self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 302)

        # Delete Translations
        page_url = reverse('resource_translations_delete',
                           args=[self.project.slug,
                                 self.resource.slug,self.language.code])
        resp = self.client['maintainer'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
                           args=[self.project.slug, self.resource.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['maintainer'].post(page_url,follow=True)
        self.assertEqual(resp.status_code, 200)

        # PRIVATE PROJECT CHECKS
        # Check if user is able to access resource details
        page_url = reverse('resource_detail',
                           args=[self.project_private.slug,
                                 self.resource_private.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check if user is able to access resource edit
        page_url = reverse('resource_edit',
                           args=[self.project_private.slug,
                                 self.resource_private.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url, follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check the popup
        page_url = reverse('resource_actions',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check the ajax view which returns more resources in project detail page.
        resp = self.client['maintainer'].post(reverse('project_resources',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(reverse('project_resources_more',
            args=[self.project_private.slug, 5]))
        self.assertEqual(resp.status_code, 200)

        # Check clone language perms
        page_url = reverse('clone_translate',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language_en.code, self.language.code])
        resp = self.client['maintainer'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check lock and get translation file perms
        page_url = reverse('lock_and_download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 200)

        # Check download file perms
        page_url = reverse('download_for_translation',
            args=[self.project_private.slug, self.resource_private.slug,
                  self.language.code])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['maintainer'].post(page_url)
        self.assertEqual(resp.status_code, 302)

        # Delete Translations
        page_url = reverse('resource_translations_delete',
                           args=[self.project_private.slug,
                                 self.resource_private.slug, self.language.code])
        resp = self.client['maintainer'].get(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)
        resp = self.client['maintainer'].post(page_url ,follow=True)
        self.assertEqual(resp.status_code, 200)

        # Check if resource gets deleted successfully
        page_url = reverse('resource_delete',
                           args=[self.project_private.slug,
                                 self.resource_private.slug])
        resp = self.client['maintainer'].get(page_url)
        self.assertEqual(resp.status_code, 302)
        resp = self.client['maintainer'].post(page_url,follow=True)
        self.assertEqual(resp.status_code, 200)

Example 50

Project: pootle
Source File: timeline.py
View license
def _calculate_timeline(request, unit):
    submission_filter = (
        Q(field__in=[SubmissionFields.TARGET, SubmissionFields.STATE,
                     SubmissionFields.COMMENT, SubmissionFields.NONE])
        | Q(type__in=SubmissionTypes.SUGGESTION_TYPES))
    timeline = (
        Submission.objects.filter(unit=unit)
                          .filter(submission_filter)
                          .exclude(field=SubmissionFields.COMMENT,
                                   creation_time=unit.commented_on)
                          .order_by("id"))
    User = get_user_model()
    entries_group = []
    context = {}
    timeline_fields = [
        "type", "old_value", "new_value", "submitter_id", "creation_time",
        "translation_project__language__code", "field", "suggestion_id",
        "suggestion__target_f", "quality_check__name", "submitter__username",
        "submitter__full_name", "suggestion__user__full_name", "submitter__email",
        "suggestion__user__username"]

    grouped_timeline = groupby(
        timeline.values(*timeline_fields),
        key=lambda item: "\001".join([
            str(x) for x in
            [
                item['submitter_id'],
                item['creation_time'],
                item['suggestion_id'],
            ]
        ])
    )

    # Group by submitter id and creation_time because
    # different submissions can have same creation time
    for key_, values in grouped_timeline:
        entry_group = {
            'entries': [],
        }

        for item in values:
            # Only add creation_time information for the whole entry group once
            entry_group['datetime'] = item['creation_time']

            # Only add submitter information for the whole entry group once
            entry_group.setdefault('submitter', ProxyTimelineUser(item))

            context.setdefault(
                'language',
                ProxyTimelineLanguage(item['translation_project__language__code']))

            entry = {
                'field': item['field'],
                'field_name': SubmissionFields.NAMES_MAP.get(item['field'], None),
                'type': item['type']}
            if item['field'] == SubmissionFields.STATE:
                entry['old_value'] = STATES_MAP[int(to_python(item['old_value']))]
                entry['new_value'] = STATES_MAP[int(to_python(item['new_value']))]
            elif item['suggestion_id']:
                entry.update({
                    'suggestion_text': item['suggestion__target_f'],
                    'suggestion_description':
                        mark_safe(_get_suggestion_description(item))})
            elif item['quality_check__name']:
                check_name = item['quality_check__name']
                check_url = (
                    u''.join(
                        [reverse('pootle-checks-descriptions'),
                         '#', check_name]))
                entry.update({
                    'check_name': check_name,
                    'check_display_name': check_names[check_name],
                    'checks_url': check_url})
            else:
                entry['new_value'] = to_python(item['new_value'])

            entry_group['entries'].append(entry)

        entries_group.append(entry_group)

    has_creation_entry = (
        len(entries_group) > 0
        and entries_group[0]['datetime'] == unit.creation_time)
    if (has_creation_entry):
        entries_group[0]['created'] = True
    else:
        created = {
            'created': True,
            'submitter': User.objects.get_system_user()}

        if unit.creation_time:
            created['datetime'] = unit.creation_time
        entries_group[:0] = [created]

    # Let's reverse the chronological order
    entries_group.reverse()
    context['entries_group'] = entries_group
    t = loader.get_template('editor/units/xhr_timeline.html')
    return t.render(context, request)