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
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
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
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
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
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
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)
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
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
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
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
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
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)
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
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
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)
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
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 }
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))
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
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
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()
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 }
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
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
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
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
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
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
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