Beispiel #1
0
 def delete_embargo(request, foia):
     """Remove an embargo from the FOIA"""
     foia.embargo = False
     foia.save(comment='removed embargo')
     logger.info('%s unembargoed %s', request.user, foia)
     new_action(request.user, 'unembargoed', target=foia)
     return
Beispiel #2
0
 def remove_member(self, request):
     """Removes a single member from an organization"""
     organization = self.get_object()
     try:
         user_pk = request.POST['member']
         user = User.objects.select_related('profile').get(pk=user_pk)
     except (KeyError, User.DoesNotExist):
         messages.error(request, 'No member selected to remove.')
         return
     # let members remove themselves from the organization, but nobody else
     removing_self = user == request.user
     user_is_owner = organization.owner == request.user
     if removing_self or user_is_owner or request.user.is_staff:
         if organization.remove_member(user):
             new_action(request.user,
                        'removed',
                        action_object=user,
                        target=organization)
             logging.info('%s %s %s from %s.', request.user, 'removed',
                          user, organization)
             if removing_self:
                 msg = 'You are no longer a member.'
             else:
                 msg = 'You removed membership from %s.' % user.first_name
             messages.success(request, msg)
     else:
         messages.error(
             request, 'You do not have permission to remove this member.')
     return
Beispiel #3
0
 def pay(self, user, amount):
     """
     Users can make payments for request fees.
     Upon payment, we create a snail mail task and we set the request to a processing status.
     Payments are always snail mail, because we need to mail the check to the agency.
     Since collaborators may make payments, we do not assume the user is the request creator.
     Returns the communication that was generated.
     """
     # We create the payment communication and a snail mail task for it.
     payable_to = self.agency.payable_to if self.agency else None
     comm = self.communications.create(
         from_user=user,
         to_user=self.get_to_user(),
         date=datetime.now(),
         response=False,
         communication=render_to_string('message/communication/payment.txt',
                                        {
                                            'amount': amount,
                                            'payable_to': payable_to,
                                        }))
     self.submit(payment=True, snail=True, amount=amount)
     # We perform some logging and activity generation
     logger.info('%s has paid %0.2f for request %s', user.username, amount,
                 self.title)
     utils.new_action(user, 'paid fees', target=self)
     # We return the communication we generated, in case the caller wants to do anything with it
     return comm
Beispiel #4
0
 def _flag(self, request, foia):
     """Allow a user to notify us of a problem with the request"""
     text = request.POST.get('text')
     if request.user.is_authenticated() and text:
         FlaggedTask.objects.create(user=request.user, text=text, foia=foia)
         messages.success(request, 'Problem succesfully reported')
         new_action(request.user, 'flagged', target=foia)
     return redirect(foia)
Beispiel #5
0
 def _follow_up(self, request, foia):
     """Handle submitting follow ups"""
     success_msg = 'Your follow up has been sent.'
     has_perm = foia.has_perm(request.user, 'followup')
     comm_sent = self._new_comm(request, foia, has_perm, success_msg)
     if comm_sent:
         new_action(request.user, 'followed up on', target=foia)
     return redirect(foia)
Beispiel #6
0
 def _follow_up(self, request, foia):
     """Handle submitting follow ups"""
     can_follow_up = foia.editable_by(request.user) or request.user.is_staff
     test = can_follow_up and foia.status != 'started'
     success_msg = 'Your follow up has been sent.'
     comm_sent = self._new_comm(request, foia, test, success_msg)
     if comm_sent:
         new_action(request.user, 'followed up on', target=foia)
     return redirect(foia)
Beispiel #7
0
 def _thank(self, request, foia):
     """Handle submitting a thank you follow up"""
     success_msg = 'Your thank you has been sent.'
     has_perm = foia.has_perm(request.user, 'thank')
     comm_sent = self._new_comm(
             request, foia, has_perm, success_msg, thanks=True)
     if comm_sent:
         new_action(request.user, verb='thanked', target=foia.agency)
     return redirect(foia)
Beispiel #8
0
 def close_crowdfund(self, succeeded=False):
     """Close the crowdfund and create a new task for it once it reaches its goal."""
     self.closed = True
     self.save()
     task.models.CrowdfundTask.objects.create(crowdfund=self)
     verb = 'ended'
     if succeeded:
         logging.info('Crowdfund %d reached its goal.', self.id)
         verb = 'succeeded'
     new_action(self, verb)
     return
Beispiel #9
0
 def form_valid(self, form):
     """Saves relationship and sends action before returning URL"""
     redirection = super(ProjectCrowdfundView, self).form_valid(form)
     crowdfund = self.object
     project = self.get_project()
     relationship = ProjectCrowdfunds.objects.create(project=project,
                                                     crowdfund=crowdfund)
     new_action(self.request.user,
                'began crowdfunding',
                action_object=relationship.crowdfund,
                target=relationship.project)
     return redirection
Beispiel #10
0
 def _thank(self, request, foia):
     """Handle submitting a thank you follow up"""
     test = foia.editable_by(request.user) and foia.is_thankable()
     success_msg = 'Your thank you has been sent.'
     comm_sent = self._new_comm(request,
                                foia,
                                test,
                                success_msg,
                                thanks=True)
     if comm_sent:
         new_action(request.user, verb='thanked', target=foia.agency)
     return redirect(foia)
Beispiel #11
0
 def create_embargo(request, foia):
     """Apply an embargo to the FOIA"""
     if foia.has_perm(request.user, 'embargo'):
         foia.embargo = True
         foia.save(comment='added embargo')
         logger.info('%s embargoed %s', request.user, foia)
         new_action(request.user, 'embargoed', target=foia)
         fine_tune_embargo(request, foia)
     else:
         logger.error('%s was forbidden from embargoing %s', request.user, foia)
         messages.error(request, 'You cannot embargo requests.')
     return
Beispiel #12
0
def _submit_request(request, foia):
    """Submit request for user"""
    if not foia.user == request.user:
        messages.error(request, 'Only a request\'s owner may submit it.')
    elif not request.user.profile.make_request():
        error_msg = ('You do not have any requests remaining. '
                     'Please purchase more requests and then resubmit.')
        messages.error(request, error_msg)
    else:
        foia.submit()
        request.session['ga'] = 'request_submitted'
        messages.success(request, 'Your request was submitted.')
        new_action(request.user, 'submitted', target=foia)
    return redirect(foia)
Beispiel #13
0
 def test_unidentical_notification(self):
     """A new notification shoudl not mark any with unidentical language as read."""
     first_action = new_action(self.request.agency, 'completed', target=self.request)
     second_action = new_action(self.request.agency, 'rejected', target=self.request)
     third_action = new_action(self.owner, 'completed', target=self.request)
     unread_count = self.owner.notifications.get_unread().count()
     self.request.notify(first_action)
     eq_(self.owner.notifications.get_unread().count(), unread_count + 1,
         'The user should have one unread notification.')
     self.request.notify(second_action)
     eq_(self.owner.notifications.get_unread().count(), unread_count + 2,
         'The user should have two unread notifications.')
     self.request.notify(third_action)
     eq_(self.owner.notifications.get_unread().count(), unread_count + 3,
         'The user should have three unread notifications.')
Beispiel #14
0
class NotificationFactory(factory.django.DjangoModelFactory):
    """A factory for creating Notification test objects."""
    class Meta:
        model = Notification

    user = factory.SubFactory(UserFactory)
    action = factory.LazyAttribute(lambda obj: new_action(obj.user, 'acted'))
Beispiel #15
0
 def setUp(self):
     agency = AgencyFactory()
     self.owner = UserFactory()
     self.follower = UserFactory()
     self.request = FOIARequestFactory(user=self.owner, agency=agency)
     follow(self.follower, self.request)
     self.action = new_action(agency, 'completed', target=self.request)
Beispiel #16
0
def crowdfund_request(request, idx, **kwargs):
    """Crowdfund a request"""
    # pylint: disable=unused-argument
    foia = FOIARequest.objects.get(pk=idx)
    owner_or_staff = request.user == foia.user or request.user.is_staff
    # check for unauthorized access
    if not owner_or_staff:
        messages.error(request, 'You may only crowdfund your own requests.')
        return redirect(foia)
    if foia.has_crowdfund():
        messages.error(request, 'You may only run one crowdfund per request.')
        return redirect(foia)
    if foia.status != 'payment':
        messages.error(request,
                       'You may only crowfund when payment is required.')
        return redirect(foia)
    if request.method == 'POST':
        # save crowdfund object
        form = CrowdfundForm(request.POST)
        if form.is_valid():
            crowdfund = form.save()
            foia.crowdfund = crowdfund
            foia.save(comment='added a crowdfund')
            messages.success(request,
                             'Your crowdfund has started, spread the word!')
            new_action(request.user,
                       'began crowdfunding',
                       action_object=crowdfund,
                       target=foia)
            return redirect(foia)

    elif request.method == 'GET':
        # create crowdfund form
        default_crowdfund_duration = 30
        date_due = datetime.now() + timedelta(default_crowdfund_duration)
        initial = {
            'name': u'Crowdfund Request: %s' % unicode(foia),
            'description':
            'Help cover the request fees needed to free these docs!',
            'payment_required': foia.get_stripe_amount(),
            'date_due': date_due,
            'foia': foia
        }
        form = CrowdfundForm(initial=initial)

    return render_to_response('forms/foia/crowdfund.html', {'form': form},
                              context_instance=RequestContext(request))
Beispiel #17
0
 def _appeal(self, request, foia):
     """Handle submitting an appeal, then create an Appeal from the returned communication."""
     form = AppealForm(request.POST)
     has_perm = foia.has_perm(request.user, 'appeal')
     if not has_perm:
         messages.error(request, 'You do not have permission to submit an appeal.')
         return redirect(foia)
     if not form.is_valid():
         messages.error(request, 'You did not submit an appeal.')
         return redirect(foia)
     communication = foia.appeal(form.cleaned_data['text'])
     base_language = form.cleaned_data['base_language']
     appeal = Appeal.objects.create(communication=communication)
     appeal.base_language.set(base_language)
     new_action(request.user, 'appealed', target=foia)
     messages.success(request, 'Your appeal has been sent.')
     return redirect(foia)
Beispiel #18
0
 def test_basic(self):
     """An action only needs an actor and a verb."""
     actor = UserFactory()
     verb = 'acted'
     action = new_action(actor, verb)
     ok_(isinstance(action, Action), 'An Action should be returned.')
     eq_(action.actor, actor)
     eq_(action.verb, verb)
Beispiel #19
0
 def add_members(self, request):
     """Grants organization membership to a list of users"""
     organization = self.get_object()
     if not organization.is_owned_by(
             request.user) and not request.user.is_staff:
         messages.error(request,
                        'You cannot add members this organization.')
         return
     form = AddMembersForm(request.POST)
     if form.is_valid():
         new_members = form.cleaned_data['members']
         new_member_count = len(new_members)
         existing_member_count = organization.members.count()
         if new_member_count + existing_member_count > organization.max_users:
             difference = (new_member_count +
                           existing_member_count) - organization.max_users
             seat = 'seats' if difference > 1 else 'seat'
             messages.error(
                 request,
                 'You will need to purchase %d %s.' % (difference, seat))
             return
         if not organization.active:
             messages.error(
                 request,
                 'You may not add members to an inactive organization.')
             return
         members_added = 0
         for member in new_members:
             try:
                 if organization.add_member(member):
                     new_action(request.user,
                                'added',
                                action_object=member,
                                target=organization)
                     logging.info('%s %s %s to %s.', request.user, 'added',
                                  member, organization)
                     members_added += 1
             except AttributeError as exception:
                 messages.error(request, exception)
         if members_added > 0:
             members_plural = 'members' if members_added > 1 else 'member'
             messages.success(
                 request,
                 'You added %d %s.' % (members_added, members_plural))
     return
Beispiel #20
0
def crowdfund_request(request, idx, **kwargs):
    """Crowdfund a request"""
    # pylint: disable=unused-argument
    # select for update locks this request in order to prevent a race condition
    # allowing multiple crowdfunds to be created for it
    foia = FOIARequest.objects.select_for_update().get(pk=idx)
    # check for unauthorized access
    if not foia.has_perm(request.user, 'crowdfund'):
        messages.error(request, 'You may not crowdfund this request.')
        return redirect(foia)
    if request.method == 'POST':
        # save crowdfund object
        form = CrowdfundForm(request.POST)
        if form.is_valid():
            crowdfund = form.save()
            foia.crowdfund = crowdfund
            foia.save(comment='added a crowdfund')
            messages.success(request, 'Your crowdfund has started, spread the word!')
            new_action(
                request.user,
                'began crowdfunding',
                action_object=crowdfund,
                target=foia)
            crowdfund.send_intro_email(request.user)
            return redirect(foia)

    elif request.method == 'GET':
        # create crowdfund form
        default_crowdfund_duration = 30
        date_due = datetime.now() + timedelta(default_crowdfund_duration)
        initial = {
            'name': u'Crowdfund Request: %s' % unicode(foia),
            'description': 'Help cover the request fees needed to free these docs!',
            'payment_required': foia.get_stripe_amount(),
            'date_due': date_due,
            'foia': foia
        }
        form = CrowdfundForm(initial=initial)

    return render(
            request,
            'forms/foia/crowdfund.html',
            {'form': form},
            )
Beispiel #21
0
 def test_for_object(self):
     """Notifications should be filterable by a single object."""
     foia = factories.FOIARequestFactory()
     _action = new_action(factories.UserFactory(), 'submitted', target=foia)
     object_notification = factories.NotificationFactory(user=self.user, action=_action)
     object_notifications = Notification.objects.for_object(foia)
     ok_(object_notification in object_notifications,
         'A notification for the object should be in the set returned.')
     ok_(self.notification not in object_notifications,
         'A notification not including the object should not be in the set returned.')
Beispiel #22
0
 def create_agency_notifications(self):
     """Create the notifications for when an agency creates a new comm"""
     if self.foia and self.foia.agency:
         action = new_action(self.foia.agency,
                             'sent a communication',
                             action_object=self,
                             target=self.foia)
         self.foia.notify(action)
     if self.foia:
         self.foia.update(self.anchor())
Beispiel #23
0
 def test_idential_different_requests(self):
     """An identical action on a different request should not mark anything as read."""
     other_request = FOIARequestFactory(user=self.owner, agency=self.request.agency)
     other_action = new_action(self.request.agency, 'completed', target=other_request)
     unread_count = self.owner.notifications.get_unread().count()
     self.request.notify(self.action)
     eq_(self.owner.notifications.get_unread().count(), unread_count + 1,
         'The user should have one unread notification.')
     other_request.notify(other_action)
     eq_(self.owner.notifications.get_unread().count(), unread_count + 2,
         'The user should have two unread notifications.')
Beispiel #24
0
 def pay(self, user, amount):
     """
     Users can make payments for request fees.
     Upon payment, we create a snail mail task and we set the request to a processing status.
     Payments are always snail mail, because we need to mail the check to the agency.
     Since collaborators may make payments, we do not assume the user is the request creator.
     Returns the communication that was generated.
     """
     from muckrock.foia.models.communication import FOIACommunication
     from muckrock.task.models import SnailMailTask
     # We mark the request as processing
     self.status = 'submitted'
     self.date_processing = date.today()
     self.save()
     # We create the payment communication and a snail mail task for it.
     payable_to = self.agency.payable_to if self.agency else None
     comm = FOIACommunication.objects.create(
         foia=self,
         from_who='MuckRock.com',
         to_who=self.get_to_who(),
         date=datetime.now(),
         delivered='mail',
         response=False,
         full_html=False,
         autogenerated=False,
         communication=render_to_string('message/communication/payment.txt',
                                        {
                                            'amount': amount,
                                            'payable_to': payable_to
                                        }))
     SnailMailTask.objects.create(communication=comm,
                                  category='p',
                                  user=user,
                                  amount=amount)
     # We perform some logging and activity generation
     logger.info('%s has paid %0.2f for request %s', user.username, amount,
                 self.title)
     utils.new_action(user, 'paid fees', target=self)
     # We return the communication we generated, in case the caller wants to do anything with it
     return comm
Beispiel #25
0
 def save(self, *args, **kwargs):
     """Creates an action if question is newly asked"""
     is_new = True if self.pk is None else False
     super(Question, self).save(*args, **kwargs)
     if is_new:
         action = new_action(self.user, 'asked', target=self)
         # Notify users who subscribe to new question notifications
         new_question_subscribers = Profile.objects.filter(
             new_question_notifications=True)
         users_to_notify = [
             profile.user for profile in new_question_subscribers
         ]
         notify(users_to_notify, action)
Beispiel #26
0
 def save(self, *args, **kwargs):
     """Update the questions answer date when you save the answer"""
     is_new = True if self.pk is None else False
     super(Answer, self).save(*args, **kwargs)
     self.question.answer_date = self.date
     self.question.save()
     if is_new:
         action = new_action(self.user,
                             'answered',
                             action_object=self,
                             target=self.question)
         # Notify the question's owner and its followers about the new answer
         notify(self.question.user, action)
         notify(followers(self.question), action)
Beispiel #27
0
 def test_get_question(self):
     """Try getting the detail page for a Question with an unread notification."""
     question = QuestionFactory()
     view = QuestionDetail.as_view()
     # Create a notification for the question
     action = new_action(UserFactory(), 'answered', target=question)
     notification = notify(self.user, action)[0]
     ok_(not notification.read, 'The notification should be unread.')
     # Try getting the view as the user
     response = http_get_response(question.get_absolute_url(),
                                  view,
                                  self.user,
                                  pk=question.pk,
                                  slug=question.slug)
     eq_(response.status_code, 200, 'The view should respond 200 OK.')
     # Check that the notification has been read.
     notification.refresh_from_db()
     ok_(notification.read, 'The notification should be marked as read.')
Beispiel #28
0
 def test_get_foia(self):
     """Try getting the detail page for a FOIA Request with an unread notification."""
     agency = AgencyFactory()
     foia = FOIARequestFactory(agency=agency)
     view = FOIARequestDetail.as_view()
     # Create a notification for the request
     action = new_action(agency, 'completed', target=foia)
     notification = notify(self.user, action)[0]
     ok_(not notification.read, 'The notification should be unread.')
     # Try getting the view as the user
     response = http_get_response(foia.get_absolute_url(),
                                  view,
                                  self.user,
                                  idx=foia.pk,
                                  slug=foia.slug,
                                  jidx=foia.jurisdiction.pk,
                                  jurisdiction=foia.jurisdiction.slug)
     eq_(response.status_code, 200, 'The view should response 200 OK.')
     # Check that the notification has been read.
     notification.refresh_from_db()
     ok_(notification.read, 'The notification should be marked as read.')
Beispiel #29
0
 def setUp(self):
     self.action = new_action(UserFactory(), 'acted')
Beispiel #30
0
 def setUp(self):
     self.user = factories.UserFactory()
     self.action = new_action(self.user, 'acted')
     self.notification = factories.NotificationFactory()