예제 #1
0
 def get_encompassed_by(self, obj):
     request, _, _, relations, _ = gather_request_data(self.context)
     encompassed_by = Location.get_encompassed_by(obj.object_uuid)
     if relations == 'hyperlink':
         return [reverse('location-detail', kwargs={'object_uuid': row},
                         request=request) for row in encompassed_by]
     return encompassed_by
예제 #2
0
    def get_solutions(self, obj):
        expand_param = self.context.get('expand_param', None)
        request, expand, _, relations, expedite = gather_request_data(
            self.context,
            expedite_param=self.context.get('expedite_param', None),
            expand_param=expand_param)
        if expedite == "true":
            return []
        solutions = []
        if expand == "true" and relations != "hyperlink":
            query = 'MATCH (a:Question {object_uuid: "%s"})' \
                '-[:POSSIBLE_ANSWER]->(solutions:Solution) ' \
                'WHERE solutions.to_be_deleted = false ' \
                'RETURN solutions' % obj.object_uuid
            res, _ = db.cypher_query(query)
            solutions = SolutionSerializerNeo(
                [Solution.inflate(row[0]) for row in res],
                many=True,
                context={
                    "request": request,
                    "expand_param": expand_param
                }).data
        else:
            if relations == "hyperlink":
                solutions = [
                    reverse('solution-detail',
                            kwargs={'object_uuid': solution_uuid},
                            request=request)
                    for solution_uuid in obj.get_solution_ids()
                ]
            else:
                return solutions

        return solutions
예제 #3
0
 def create(self, validated_data):
     request, _, _, _, _ = gather_request_data(self.context)
     stripe.api_key = settings.STRIPE_SECRET_KEY
     stripe.api_version = settings.STRIPE_API_VERSION
     donor = Pleb.get(request.user.username)
     token = validated_data.pop('token', None)
     # TODO add payment_method selection support to direct donations
     # this pop is just to allow the donation to save using **validated_data
     validated_data.pop('payment_method', None)
     donation = Donation(owner_username=donor.username,
                         **validated_data).save()
     if not donor.stripe_customer_id:
         customer = stripe.Customer.create(
             description="Customer for %s" % donor.username,
             card=token,
             email=donor.email)
         donor.stripe_customer_id = customer['id']
         donor.save()
         cache.delete(donor.username)
         donor.refresh()
     donor.donations.connect(donation)
     donation.owned_by.connect(donor)
     charge = stripe.Charge.create(
         amount=donation.amount,
         currency="usd",
         customer=donor.stripe_customer_id,
         receipt_email=donor.email,
         description="Donation to Sagebrew from %s" % donor.username
     )
     donation.stripe_charge_id = charge['id']
     donation.save()
     spawn_task(task_func=check_privileges,
                task_param={"username": donor.username})
     return donation
예제 #4
0
 def get_geo_data(self, obj):
     request, expand, _, _, _ = gather_request_data(self.context)
     if obj.geo_data is None:
         return False
     if expand == 'true':
         return loads(obj.geo_data)
     return True
예제 #5
0
 def get_url(self, obj):
     request, _, _, _, expedite = gather_request_data(self.context)
     # If expedite is true it is assumed the calling function handles this
     # functionality
     if obj.url is not None:
         return obj.url
     if expedite != "true":
         parent_object = get_parent_object(obj.object_uuid)
         parent_url = reverse(
             '%s-detail' % parent_object.get_child_label().lower(),
             kwargs={'object_uuid': parent_object.object_uuid},
             request=request)
         if request is not None:
             # Shouldn't need to check for anon because if user is anon
             # comments will return an empty list for private content.
             # It will return the proper information for public info.
             response = request_to_api(parent_url,
                                       request.user.username,
                                       req_method="GET")
         else:
             parent_url = "%s%s" % (settings.WEB_ADDRESS, parent_url)
             response = request_to_api(parent_url,
                                       obj.owner_username,
                                       req_method="GET")
         return response.json()['url']
     return None
예제 #6
0
 def get_location(self, obj):
     request, _, _, relation, _ = gather_request_data(self.context)
     location = Position.get_location(obj.object_uuid)
     if relation == 'hyperlink':
         return reverse('location-detail',
                        kwargs={'object_uuid': location},
                        request=request)
     return location
예제 #7
0
 def get_href(self, obj):
     request, _, _, _, _ = gather_request_data(
         self.context,
         expedite_param=self.context.get('expedite_param', None),
         expand_param=self.context.get('expand_param', None))
     return reverse('question-detail',
                    kwargs={'object_uuid': obj.object_uuid},
                    request=request)
예제 #8
0
 def get_positions(self, obj):
     request, _, _, relations, _ = gather_request_data(self.context)
     positions = Location.get_positions(obj.object_uuid)
     if relations == 'hyperlink':
         return [reverse('position-detail',
                         kwargs={'object_uuid': row}, request=request)
                 for row in positions]
     return positions
예제 #9
0
 def get_location(self, obj):
     request, _, _, _, _ = gather_request_data(self.context)
     location = obj.get_location()
     if location is not None:
         return LocationSerializer(location,
                                   context={'request': request}).data
     else:
         return None
예제 #10
0
 def get_is_following(self, obj):
     request, _, _, _, _ = gather_request_data(self.context)
     if request is not None:
         # Backwards because we don't want to be dependent on the Pleb as
         # the object running the query so the user can follow multiple
         # types of objects. Such as Quest or Plebs.
         return obj.is_following(request.user.username)
     return False
예제 #11
0
 def get_updates(self, obj):
     request, _, _, relation, _ = gather_request_data(self.context)
     updates = Quest.get_updates(obj.object_uuid)
     if relation == 'hyperlink':
         return [
             reverse('update-detail',
                     kwargs={'object_uuid': update},
                     request=request) for update in updates
         ]
     return updates
예제 #12
0
 def get_quest(self, obj):
     request, expand, _, _, _ = gather_request_data(
         self.context, expand_param=self.context.get('expand', None))
     try:
         quest = Quest.get(owner_username=obj.username)
     except(Quest.DoesNotExist, DoesNotExist):
         return None
     if expand == 'true' and quest is not None:
         return QuestSerializer(quest, context={'request': request}).data
     return quest.owner_username
예제 #13
0
 def test_no_query_params_request(self):
     request = self.factory.get('/conversations/%s/' %
                                self.question.object_uuid)
     context = {'request': request}
     request, expand, expand_array, relations, expedite = \
         gather_request_data(context)
     self.assertEqual('false', expand)
     self.assertEqual(len(expand_array), 0)
     self.assertEqual('primarykey', relations)
     self.assertEqual('false', expedite)
예제 #14
0
    def update(self, instance, validated_data):
        request, _, _, _, _ = gather_request_data(self.context)
        stripe.api_key = settings.STRIPE_SECRET_KEY
        stripe.api_version = settings.STRIPE_API_VERSION
        mission = validated_data.pop('mission', None)
        quest = validated_data.pop('quest', None)
        payment_method = validated_data.pop('payment_method', None)

        donor = Pleb.get(instance.owner_username)
        quest_desc = quest.title \
            if quest.title else "%s %s" % (quest.first_name, quest.last_name)
        mission_desc = mission.get_mission_title()
        description = "Gift purchase to %s's mission for %s" % (quest_desc,
                                                                mission_desc)
        payment_method = payment_method if payment_method is not None \
            else donor.stripe_default_card_id
        stripe_res = stripe.Charge.create(customer=donor.stripe_customer_id,
                                          amount=instance.total,
                                          currency="usd",
                                          description=description,
                                          receipt_email=donor.email,
                                          source=payment_method)
        instance.stripe_charge_id = stripe_res['id']
        instance.paid = True
        instance.save()

        message_data = {
            'message_type':
            'email',
            'subject':
            'New Gift',
            'body':
            get_template('orders/email/new_order.html').render(
                Context({
                    'first_name': quest.first_name,
                    'mission_title': mission_desc,
                    "donor_first_name": donor.first_name,
                    "donor_last_name": donor.last_name,
                })),
            'template':
            "personal",
            'from_user': {
                'type': "admin",
                'id': settings.INTERCOM_ADMIN_ID_DEVON
            },
            'to_user': {
                'type': "user",
                'user_id': quest.owner_username
            }
        }
        serializer = IntercomMessageSerializer(data=message_data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return instance
예제 #15
0
 def get_quest(self, obj):
     from sb_quests.neo_models import Quest
     from sb_quests.serializers import QuestSerializer
     request, _, _, _, _ = gather_request_data(self.context)
     query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \
             '(:Mission {object_uuid: "%s"}) RETURN quest' % obj.object_uuid
     res, _ = db.cypher_query(query)
     if res.one is None:
         return None
     return QuestSerializer(Quest.inflate(res.one),
                            context={'request': request}).data
예제 #16
0
 def test_query_params(self):
     request = self.factory.get('/conversations/%s/?'
                                'expedite=true&expand=true' %
                                self.question.object_uuid)
     context = {'request': request}
     request, expand, expand_array, relations, expedite = \
         gather_request_data(context, expedite_param=True)
     self.assertEqual('true', expand)
     self.assertEqual(len(expand_array), 0)
     self.assertEqual('primarykey', relations)
     self.assertEqual('true', expedite)
예제 #17
0
 def get_is_owner(self, obj):
     """
     Determine if the currently logged in user is the owner of this object.
     :param obj:
     :return:
     """
     request, _, _, _, _ = gather_request_data(self.context)
     if request is None:
         return False
     if not request.user.is_authenticated():
         return False
     return obj.owner_username == request.user.username
예제 #18
0
    def get_can_comment(self, obj):
        """
        Determine if the currently logged in user can flag this object.
        :param obj:
        :return:
        """
        request, _, _, _, _ = gather_request_data(self.context)
        detail = None
        short_detail = None
        if request is None:
            return {
                "status": False,
                "detail": "You must be logged in to comment on content.",
                "short_detail": "Signup To Comment"
            }
        if not request.user.is_authenticated():
            return {
                "status": False,
                "detail": "You must be logged in to comment on content.",
                "short_detail": "Signup To Comment"
            }
        if obj.owner_username == request.user.username:
            # Always allow the owner to comment on their own content
            return {
                "status": True,
                "detail": detail,
                "short_detail": short_detail
            }
        obj_type = obj.__class__.__name__.lower()
        if obj_type == "question" or obj_type == "solution":
            can_comment = "comment" in Pleb.get(
                username=request.user.username).get_privileges()
            if not can_comment:
                mission = obj.get_mission(obj.object_uuid, request)
                if mission:
                    if mission['owner_username'] == request.user.username:
                        return {
                            "status": True,
                            "detail": detail,
                            "short_detail": short_detail
                        }
                detail = "You must have 20+ reputation to comment on " \
                         "Conversation Cloud content."
                short_detail = "Requirement: 20+ Reputation"
        else:
            can_comment = True

        return {
            "status": can_comment,
            "detail": detail,
            "short_detail": short_detail
        }
예제 #19
0
 def get_question(self, obj):
     from sb_questions.neo_models import Question
     from sb_questions.serializers import QuestionSerializerNeo
     request, expand, _, relations, expedite = gather_request_data(
         self.context,
         expedite_param=self.context.get('expedite_param', None),
         expand_param=self.context.get('expand_param', None))
     question = Question.get(object_uuid=obj.parent_id)
     if expand:
         return QuestionSerializerNeo(question).data
     return reverse('question-detail',
                    kwargs={'object_uuid': question.object_uuid},
                    request=self.context.get('request', None))
예제 #20
0
 def get_href(self, obj):
     """
     href provides a link to the objects API detail endpoint. This is for
     programmatic access.
     """
     request, _, _, _, _ = gather_request_data(self.context)
     if obj.href is None:
         try:
             return obj.get_href(request)
         except AttributeError:
             return None
     else:
         return obj.href
예제 #21
0
 def get_url(self, obj):
     """
     url provides a link to the human viewable page that the object appears
     on. This is for user consumption and templates.
     """
     request, _, _, _, _ = gather_request_data(self.context)
     if obj.url is None:
         try:
             return obj.get_url(request)
         except AttributeError:
             return None
     else:
         return obj.url
예제 #22
0
    def get_flagged(self, obj):
        """
        Determine if the currently logged in user has already flagged this
        object
        :param obj:
        :return:
        """
        request, _, _, _, _ = gather_request_data(self.context)
        if request is None:
            return False
        if not request.user.is_authenticated():
            return False

        return request.user.username in obj.get_flagged_by()
예제 #23
0
    def get_can_upvote(self, obj):
        """
        Determine if the currently logged in user can up vote this object.
        :param obj:
        :return:
        """
        request, _, _, _, _ = gather_request_data(self.context)
        can_upvote = True
        detail = None
        short_detail = None
        if request is None:
            return {
                "status": False,
                "detail": "You must be logged in to upvote content.",
                "short_detail": "Signup To Vote"
            }
        if not request.user.is_authenticated():
            return {
                "status": False,
                "detail": "You must be logged in to upvote content.",
                "short_detail": "Signup To Vote"
            }
        obj_type = obj.__class__.__name__.lower()
        # Duplicated logic for sake of readability
        if obj_type == "question" or obj_type == "solution":
            if obj.owner_username == request.user.username:
                can_upvote = False
                detail = "You cannot upvote your own " \
                         "Conversation Cloud content"
                short_detail = "Cannot Upvote Own " \
                               "Conversation Cloud Content"
        elif obj_type == "comment" and hasattr(obj, 'parent_type') and \
            (obj.parent_type == "question" or
                obj.parent_type == "solution"):
            if obj.owner_username == request.user.username:
                can_upvote = False
                detail = "You cannot upvote your own " \
                         "Conversation Cloud content"
                short_detail = "Cannot Upvote Own " \
                               "Conversation Cloud Content"

        # Currently we allow everyone to upvote without regulation. This is
        # to generate an initial base of reputation.

        return {
            "status": can_upvote,
            "detail": detail,
            "short_detail": short_detail
        }
예제 #24
0
 def get_mission(self, obj):
     from sb_missions.neo_models import Mission
     from sb_missions.serializers import MissionSerializer
     request, expand, _, relation, _ = gather_request_data(self.context)
     mission = Donation.get_mission(obj.object_uuid)
     if mission is None:
         return None
     if expand == 'true':
         return MissionSerializer(Mission.get(
             object_uuid=mission)).data
     if relation == "hyperlink" and mission is not None:
         return reverse('mission-detail',
                        kwargs={"object_uuid": mission},
                        request=request)
     return mission
예제 #25
0
 def create(self, validated_data):
     # TODO we don't have a way currently to distinguish what a Update is
     # about. Think it'll be based on an attribute submitted by the front
     # end. That will be based on where it's at (make update from Public
     # Office Mission vs Advocate Mission vs Quest vs etc)
     request, _, _, _, _ = gather_request_data(self.context)
     quest = validated_data.pop('quest', None)
     owner = Pleb.get(request.user.username)
     validated_data['owner_username'] = owner.username
     about = validated_data.pop('about', None)
     about_type = validated_data.get('about_type')
     validated_data['content'] = \
         render_content(validated_data.get('content', ''))
     update = Update(**validated_data).save()
     quest.updates.connect(update)
     url = None
     if about_type == 'mission':
         update.mission.connect(about)
         url = reverse('mission_updates',
                       kwargs={
                           'object_uuid': about.object_uuid,
                           'slug': slugify(about.get_mission_title())
                       })
     elif about_type == 'quest':
         update.quest.connect(about)
     cache.delete("%s_updates" % quest.object_uuid)
     task_params = {
         "sb_object":
         update.object_uuid,
         "to_plebs":
         quest.get_followers(),
         "from_pleb":
         request.user.username,
         "notification_id":
         str(uuid1()),
         "url":
         url,
         "action_name":
         "%s %s has made an Update on a Quest you follow!" %
         (request.user.first_name, request.user.last_name),
         "public":
         True
     }
     spawn_task(task_func=spawn_notifications, task_param=task_params)
     return update
예제 #26
0
    def get_products(self, obj):
        '''
        Gets the products attached to the order.

        The expand method is provided here because we won't always want to
        query Amazon for specific information about the product.

        If expand is true we will hit Amazon and get back specific information
        about the product such as price and images.
        :param obj:
        :return:
        '''
        request, expand, _, _, _ = gather_request_data(self.context)
        serialized_products = [
            ProductSerializer(product).data for product in obj.get_products()
        ]
        if expand == 'true':  # pragma: no cover
            # Not covering this as we have no good way to mock a request to
            # the amazon api as they use request signatures. - Devon Bleibtrey
            vendor_ids = [
                product['vendor_id'] for product in serialized_products
            ]
            amazon = AmazonAPI(settings.AMAZON_PROMOTION_API_KEY,
                               settings.AMAZON_PROMOTION_API_SECRET_KEY,
                               settings.AMAZON_ASSOCIATE_TAG)
            for sub_list in chunk_list(vendor_ids, 10):
                sub_ids = ",".join(sub_list)
                products = amazon.lookup(ItemId=sub_ids)
                if not hasattr(products, '__iter__'):
                    products = [products]
                for product in products:
                    match = next((l for l in serialized_products
                                  if l['vendor_id'] == product.asin), None)
                    if match is not None:
                        price, currency = product.price_and_currency
                        match['information'] = {
                            "title": product.title,
                            "image": product.large_image_url,
                            "price": price,
                            "currency": currency,
                            "asin": product.asin,
                            "url": product.offer_url
                        }
        return serialized_products
예제 #27
0
 def get_quest(self, obj):
     from sb_quests.neo_models import Quest
     from sb_quests.serializers import QuestSerializer
     request, expand, _, relation, _ = gather_request_data(self.context)
     query = 'MATCH (d:Donation {object_uuid: "%s"})-' \
             '[:CONTRIBUTED_TO]->' \
             '(mission:Mission)<-[:EMBARKS_ON]-(quest:Quest) ' \
             'RETURN quest' % obj.object_uuid
     res, _ = db.cypher_query(query)
     if res.one is None:
         return None
     quest = Quest.inflate(res.one)
     if expand == 'true':
         return QuestSerializer(quest).data
     if relation == "hyperlink":
         return reverse('quest-detail',
                        kwargs={"object_uuid": quest.object_uuid},
                        request=request)
     return quest.owner_username
예제 #28
0
 def create(self, validated_data):
     from sb_tags.neo_models import Tag
     from sb_tags.serializers import TagSerializer
     request, _, _, _, _ = gather_request_data(self.context)
     generated_tags = []
     if request is None:
         raise serializers.ValidationError(
             "Must perform creation from web request")
     for tag in validated_data['interests']:
         try:
             query = 'MATCH (profile:Pleb {username: "******"}), ' \
                     '(tag:Tag {name: "%s"}) ' \
                     'CREATE UNIQUE (profile)-[:INTERESTED_IN]->(tag) ' \
                     'RETURN tag' % (request.user.username, slugify(tag))
             res, _ = db.cypher_query(query)
             generated_tags.append(TagSerializer(Tag.inflate(res.one)).data)
         except(ConstraintViolation, Exception):
             pass
     cache.delete(request.user.username)
     return generated_tags
예제 #29
0
 def get_profile(self, obj):
     from plebs.serializers import PlebSerializerNeo
     request, expand, _, relation, _ = gather_request_data(
         self.context,
         expedite_param=self.context.get('expedite_param', None),
         expand_param=self.context.get('expand_param', None))
     owner_username = obj.owner_username
     if expand == "true":
         owner = Pleb.get(username=owner_username)
         profile_dict = PlebSerializerNeo(owner,
                                          context={
                                              'request': request
                                          }).data
     elif relation == 'hyperlink':
         profile_dict = reverse('profile-detail',
                                kwargs={"username": owner_username},
                                request=request)
     else:
         profile_dict = obj.owner_username
     return profile_dict
예제 #30
0
    def create(self, validated_data):
        request, _, _, _, _ = gather_request_data(self.context)
        product_ids = validated_data.get('product_ids', [])
        mission = validated_data.get('mission', None)
        total = validated_data.get('total', 0)
        owner = Pleb.get(request.user.username)
        order = Order(total=total, owner_username=owner.username).save()
        order.owner.connect(owner)
        order.mission.connect(mission)
        for product_id in product_ids:
            product = Product.nodes.get(object_uuid=product_id)
            product.orders.connect(order)

        message_data = {
            'message_type':
            'email',
            'subject':
            'Submit Mission For Review',
            'body':
            'Hi Team,\n%s has submitted an Order. '
            'Please review it in the <a href="%s">'
            'council area</a>. ' %
            (order.owner_username,
             reverse('council_orders', request=self.context.get('request'))),
            'template':
            "personal",
            'from_user': {
                'type': "admin",
                'id': settings.INTERCOM_ADMIN_ID_DEVON
            },
            'to_user': {
                'type': "user",
                'user_id': settings.INTERCOM_USER_ID_DEVON
            }
        }
        serializer = IntercomMessageSerializer(data=message_data)
        if serializer.is_valid():
            serializer.save()

        return order