def mission_updates(request, object_uuid, slug=None): # Only need to check that at least one update exists here to mark that # updates are available for this mission. query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \ '(mission:Mission {object_uuid: "%s"}) ' \ 'WITH quest, mission ' \ 'OPTIONAL MATCH (mission)<-[:ABOUT]-(updates:Update) ' \ 'RETURN quest, mission, ' \ 'CASE WHEN count(updates) > 0 ' \ 'THEN true ELSE false END AS update' % object_uuid res, _ = db.cypher_query(query) if res.one is None: return redirect("404_Error") # Instead of doing inflation and serialization of all the updates here # without pagination lets just indicate if we have any or not and then # hit the endpoint to gather the actual updates. quest = Quest.inflate(res.one.quest) mission_obj = Mission.inflate(res.one.mission) return render( request, 'mission/updates.html', { "updates": res.one.update, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "slug": slugify(mission_obj.get_mission_title()), "quest": QuestSerializer(quest).data })
def mission_endorsements(request, object_uuid, slug=None): # Just check if there are any endorsements either from a Pleb or a Quest query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \ '(mission:Mission {object_uuid:"%s"}) ' \ 'WITH quest, mission ' \ 'OPTIONAL MATCH (mission)<-[:ENDORSES]-(endorsement) ' \ 'RETURN endorsement, quest, mission' % object_uuid res, _ = db.cypher_query(query) # Instead of doing inflation and serialization of all the updates here # without pagination lets just indicate if we have any or not and then # hit the endpoint to gather the actual updates. quest = Quest.inflate(res.one.quest) mission_obj = Mission.inflate(res.one.mission) return render( request, 'mission/endorsements.html', { "quest": QuestSerializer(quest).data, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "slug": slugify(mission_obj.get_mission_title()), "endorsements": True if res.one.endorsement else False })
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 endorsements(self, request, object_uuid=None): serialized = [] endorsements = Mission.get_endorsements(object_uuid) page = self.paginate_queryset(endorsements) for node in page: if "Pleb" in node.labels: serialized.append(PlebSerializerNeo(Pleb.inflate(node.e)).data) if "Quest" in node.labels: serialized.append(QuestSerializer(Quest.inflate(node.e)).data) return self.get_paginated_response(serialized)
def get_about(self, obj): from sb_missions.neo_models import Mission from sb_missions.serializers import MissionSerializer from sb_quests.neo_models import Quest from sb_quests.serializers import QuestSerializer if obj.about_type == "mission": return MissionSerializer(Mission.get(obj.about_id)).data elif obj.about_type == "quest": return QuestSerializer(Quest.get(obj.about_id)).data else: return None
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 get_search_html(request, object_uuid): try: quest = Quest.get(object_uuid) except (CypherException, IOError): return Response('Server Error', status=500) rendered_html = render_to_string( "saga_search_block.html", QuestSerializer(quest, context={ 'request': request }).data) return Response({'html': rendered_html}, status=200)
def delete_account(request): """ Delete account page. """ try: query = 'MATCH (q:Quest {owner_username:"******"}) RETURN q' % ( request.user.username) res, _ = db.cypher_query(query) quest = QuestSerializer(Quest.inflate(res[0][0]), context={ 'request': request }).data except (DoesNotExist, Quest.DoesNotExist, IndexError): quest = None return render(request, 'settings/delete_account.html', {"quest": quest})
def get_quest(self, obj): from sb_quests.neo_models import Quest from sb_quests.serializers import QuestSerializer # We use object_uuid here instead of owner_username as none of the # public officials have a owner quest = None query = 'MATCH (o:PublicOfficial {object_uuid: "%s"})-' \ '[:IS_HOLDING]->(quest:Quest) ' \ 'RETURN quest' % obj.object_uuid res, _ = db.cypher_query(query) if res.one: quest = res.one if quest is not None: quest = QuestSerializer(Quest.inflate(quest)).data return quest
def test_quest(self): self.client.force_authenticate(user=self.user) quest = Quest(owner_username=self.pleb.username, first_name="Tyler", last_name="Wiersing").save() es = Elasticsearch(settings.ELASTIC_SEARCH_HOST) index_res = es.index(index='full-search-base', doc_type='quest', body=QuestSerializer(quest).data) time.sleep(1) self.assertTrue(index_res['created']) url = reverse('search-list') + "?query=tyler&filter=quests" response = self.client.get(url, format='json') self.assertGreaterEqual(response.data['count'], 1) self.assertContains(response, quest.object_uuid, status_code=status.HTTP_200_OK)
def general_settings(request): """ Displays the users profile_page. This is where we call the functions to determine who the senators are for the plebs state and which representative for the plebs district. Checks to see if the user currently accessing the page is the same user as the one who owns the page. If so it loads the page fully, if the user is a friend of the owner of the page then it allows them to see posts and comments on posts on the owners wall. If the user is neither the owner nor a friend then it only shows the users name, congressmen, reputation and profile pictures along with a button that allows them to send a friend request. :param request: :return: """ address_key = settings.ADDRESS_AUTH_ID query = 'MATCH (person:Pleb {username: "******"})' \ '-[r:LIVES_AT]->(house:Address) RETURN house' % ( request.user.username) try: res, col = db.cypher_query(query) address = AddressSerializer(Address.inflate(res[0][0]), context={ 'request': request }).data except (CypherException, ClientError): return redirect("500_Error") except IndexError: address = False try: query = 'MATCH (q:Quest {owner_username:"******"}) RETURN q' % ( request.user.username) res, _ = db.cypher_query(query) quest = QuestSerializer(Quest.inflate(res[0][0]), context={ 'request': request }).data except (DoesNotExist, Quest.DoesNotExist, IndexError): quest = None return render(request, 'settings/general_settings.html', { "address": address, "address_key": address_key, "quest": quest })
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 get(self, request, object_uuid=None, slug=None): try: mission_obj = Mission.get(object_uuid) except (Mission.DoesNotExist, DoesNotExist): return redirect("404_Error") except (CypherException, ClientError, IOError): return redirect("500_Error") mission_dict = MissionSerializer(mission_obj, context={ 'request': request }).data return render( request, self.template_name, { "mission": mission_dict, "quest": QuestSerializer(Quest.get(mission_obj.owner_username)).data })
def mission_edit_updates(request, object_uuid, slug=None, edit_id=None): query = 'MATCH (update:Update {object_uuid: "%s"})-[:ABOUT]->' \ '(mission:Mission)<-[:EMBARKS_ON]-(quest:Quest)' \ 'WITH update, mission, quest ' \ 'MATCH (quest)-[:EMBARKS_ON]->(missions:Mission) ' \ 'RETURN mission, quest, update, missions ' \ 'ORDER BY missions.created DESC' % edit_id res, _ = db.cypher_query(query) if res.one is None: return redirect("select_mission") missions = [ MissionSerializer(Mission.inflate(row.missions)).data for row in res ] mission_obj = Mission.inflate(res.one.mission) return render( request, 'updates/edit.html', { "update": UpdateSerializer(Update.inflate(res.one.update)).data, "mission": MissionSerializer(mission_obj).data, "slug": slugify(mission_obj.get_mission_title()), "quest": QuestSerializer(Quest.inflate(res.one.quest)).data, "missions": missions })
def contribute_settings(request): """ This view provides the necessary information for rendering a user's Quest settings. If they have an ongoing Quest it provides the information for that and if not it returns nothing and the template is expected to provide a button for the user to start their Quest. :param request: :return: """ try: query = 'MATCH (q:Quest {owner_username:"******"}) RETURN q' % ( request.user.username) res, _ = db.cypher_query(query) quest = QuestSerializer(Quest.inflate(res[0][0]), context={ 'request': request }).data except (DoesNotExist, Quest.DoesNotExist, IndexError): quest = None return render(request, 'settings/contribute_settings.html', { "stripe_key": settings.STRIPE_PUBLIC_KEY, "quest": quest })
def get(self, request): try: query = 'MATCH (q:Quest {owner_username:"******"}) RETURN q' % ( request.user.username) res, _ = db.cypher_query(query) quest = QuestSerializer(Quest.inflate(res[0][0]), context={ 'request': request }).data except (DoesNotExist, Quest.DoesNotExist, IndexError): quest = None return render( request, self.template_name, { 'page_profile': PlebSerializerNeo(Pleb.get(username=request.user.username), context={ 'expand': True, 'request': request }).data, 'page_user': User.objects.get(username=request.user.username), 'quest': quest })
def get(self, request, username=None): from sb_missions.neo_models import Mission from sb_missions.serializers import MissionSerializer from sb_missions.utils import order_tasks query = 'MATCH (person:Pleb {username: "******"})' \ '-[r:IS_WAGING]->(quest:Quest) WITH quest ' \ 'OPTIONAL MATCH (quest)-[:EMBARKS_ON]->(missions:Mission) ' \ 'RETURN quest, missions ORDER BY missions.created DESC' % ( request.user.username) try: res, _ = db.cypher_query(query) if res.one is None: return redirect("404_Error") except (CypherException, ClientError): return redirect("500_Error") res.one.quest.pull() quest_obj = Quest.inflate(res.one.quest) quest_ser = QuestSerializer(quest_obj, context={ 'request': request }).data quest_ser['account_type'] = quest_obj.account_type if res.one.missions is None: mission_link = reverse('select_mission') mission_active = False onboarding_sort = [] mission_obj = None onboarding_done = 0 else: mission_obj = Mission.inflate(res[0].missions) mission_link = reverse('mission_settings', kwargs={ "object_uuid": mission_obj.object_uuid, "slug": slugify(mission_obj.get_mission_title()) }) mission_active = mission_obj.active onboarding_sort, completed_count = order_tasks( mission_obj.object_uuid) onboarding_done = int( (float(completed_count) / float(len(onboarding_sort))) * 100) res, _ = db.cypher_query('MATCH (a:Quest {owner_username: "******"})' '-[:LOCATED_AT]->(b:Address) ' 'RETURN b' % quest_obj.owner_username) if res.one is not None: address = Address.inflate(res.one) else: address = None if self.template_name == "manage/quest_banking.html" \ and address is None: return redirect('account_setup') if self.template_name == "manage/quest_settings.html": return redirect('general_settings') return render( request, self.template_name, { "quest": quest_ser, "mission_link": mission_link, "mission_active": mission_active, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "address": address, "onboarding_top_3": onboarding_sort[:3], "onboarding_rest": onboarding_sort[3:], "onboarding_done": onboarding_done })
def create(self, validated_data): request = self.context.get('request') response_dict = { "id": validated_data['id'], "type": validated_data['type'], 'data': validated_data['data'] } Intercom.app_id = settings.INTERCOM_APP_ID Intercom.app_api_key = settings.INTERCOM_API_KEY stripe.api_key = settings.STRIPE_SECRET_KEY stripe.api_version = settings.STRIPE_API_VERSION event_type = validated_data['type'] if event_type == "invoice.payment_failed": try: customer = stripe.Customer.retrieve( validated_data['data']['object']['customer']) except stripe.InvalidRequestError: raise serializers.ValidationError("Ran into some issues") try: pleb = Pleb.nodes.get(email=customer['email']) except (DoesNotExist, Pleb.DoesNotExist): return response_dict message_data = { 'message_type': 'email', 'subject': 'Subscription Failure Notice', 'body': "Hi {{ first_name }},\nIt looks like we ran into " "some trouble processing your subscription payment. " "Please verify your billing information is correct " "and we'll automatically retry to process the payment. " "If the payment continues to fail we'll automatically " "move you over to a free account. If you believe " "there has been a mistake please respond to this " "email and we'd be happy to help!\n\nBest Regards," "\n\nDevon", 'template': 'personal', 'from_user': { 'type': 'admin', 'id': settings.INTERCOM_ADMIN_ID_DEVON }, 'to_user': { 'type': 'user', 'user_id': pleb.username } } serializer = IntercomMessageSerializer(data=message_data) serializer.is_valid(raise_exception=True) serializer.save() response_dict["detail"] = "Invoice Payment Failed" return response_dict if event_type == "account.updated": try: account = stripe.Account.retrieve( validated_data['data']['object']['id']) except (stripe.InvalidRequestError, stripe.APIConnectionError) as e: logger.exception(e) raise serializers.ValidationError(e) except stripe.AuthenticationError: # Just return silently here so that Stripe stops sending us the # unauthenticatable user return response_dict if account.get('deleted', False): return response_dict try: pleb = Pleb.nodes.get(email=account.email) except (DoesNotExist, Pleb.DoesNotExist): return response_dict quest = Quest.nodes.get(owner_username=pleb.username) if quest.account_verified != "verified" \ and account.legal_entity.verification.status == "verified": # Need this to ensure the notification is only sent once if # Stripe sends a subsequent message before we've saved the # verification off. query = 'MATCH (a:Notification {action_name: ' \ '"Your Quest has been verified!"})' \ '-[:NOTIFICATION_TO]->(pleb:Pleb {username: "******"}) ' \ 'RETURN a' % pleb.username res, _ = db.cypher_query(query) if res.one is None: create_system_notification( to_plebs=[pleb], notification_id=str(uuid1()), url=reverse('quest_manage_banking', kwargs={'username': pleb.username}), action_name="Your Quest has been verified!") quest_ser = QuestSerializer(instance=quest, data={'active': True}, context={ "secret": settings.SECRET_KEY, "request": request }) quest_ser.is_valid(raise_exception=True) quest_ser.save() cache.delete("%s_quest" % quest.owner_username) # Update quest after saving from serializer so we're not working # with a stale instance. quest = Quest.nodes.get(owner_username=pleb.username) # Need this because the serializer doesn't get into the area # where verification is updated unless a new external account # is added. quest.account_verified = \ account.legal_entity.verification.status quest.account_verified_date = datetime.now(pytz.utc) # When a quest is verified it automatically becomes active # If a user wants to take their quest inactive they have the # option but to reactivate they have to reach out to us and # explain because we don't want people just going active, # inactive and screwing with donors. quest.active = True message_data = { 'message_type': 'email', 'subject': 'Quest Verified', 'body': "Hi Team,\n%s's Quest has been verified by Stripe. " "Please review it in the <a href='%s'>" "council area</a>." % (quest.owner_username, reverse('council_missions', request=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() if account.verification.fields_needed: quest.account_verification_fields_needed = \ account.verification.fields_needed quest.account_verified = \ account.legal_entity.verification.status quest.account_verification_details = \ str(account.legal_entity.verification.details) if quest.account_first_updated is None: quest.account_first_updated = datetime.now(pytz.utc) verify = account.verification # Determine if we need Quest to upload identification documentation if 'legal_entity.verification.document' in verify.fields_needed: quest.verification_document_needed = True # Save off when the additional information is due by if hasattr(verify, 'due_by') and verify.due_by is not None: quest.verification_due_date = datetime.fromtimestamp( account.verification.due_by) else: quest.verification_due_date = None # Indicate why the account was disabled by the payment processing # platform if verify.disabled_reason is not None: quest.verification_disabled_reason = \ account.verification.disabled_reason\ .replace('_', " ").title() else: quest.verification_disabled_reason = None quest.save() cache.delete("%s_quest" % quest.owner_username) response_dict["detail"] = "Account Updated" return response_dict if event_type == "transfer.failed": try: transfer = stripe.Transfer.retrieve( validated_data['data']['object']['id']) if transfer.type == 'stripe_account': account = stripe.Account.retrieve(transfer.destination) if account.get('deleted', False): return response_dict else: raise serializers.ValidationError('An error occurred') except (stripe.InvalidRequestError, stripe.APIConnectionError) as e: logger.exception(e) raise serializers.ValidationError(e) except stripe.AuthenticationError: # Just return silently here so that Stripe stops sending us the # unauthenticatable user return response_dict try: pleb = Pleb.nodes.get(email=account.email) except (DoesNotExist, Pleb.DoesNotExist): return response_dict create_system_notification( to_plebs=[pleb], notification_id=str(uuid1()), url=reverse('quest_manage_banking', kwargs={'username': pleb.username}), action_name="A transfer to your bank account has " "failed! Please review that your " "Quest Banking information is correct.") Event.create(event_name="stripe-transfer-failed", user_id=pleb.username, created=calendar.timegm( datetime.now(pytz.utc).utctimetuple())) response_dict["detail"] = "Transfer Failed" return response_dict if event_type == 'customer.subscription.trial_will_end': try: customer = stripe.Customer.retrieve( validated_data['data']['object']['customer']) except (stripe.InvalidRequestError, stripe.APIConnectionError) as e: logger.exception(e) raise serializers.ValidationError(e) try: pleb = Pleb.nodes.get(email=customer.email) except (DoesNotExist, Pleb.DoesNotExist): return response_dict create_system_notification( to_plebs=[pleb], notification_id=str(uuid1()), url=reverse('quest_manage_billing', kwargs={'username': pleb.username}), action_name="Your Pro Trial will " "be ending soon, add a payment method to " "keep your Pro Account features.") response_dict["detail"] = "Trail Will End" return response_dict response_dict["detail"] = "No updates" return response_dict
def update_search_object(object_uuid, label=None, object_data=None, index="full-search-base"): from plebs.serializers import PlebSerializerNeo from sb_quests.serializers import QuestSerializer from sb_quests.neo_models import Quest from sb_missions.serializers import MissionSerializer from sb_missions.neo_models import Mission from sb_questions.serializers import QuestionSerializerNeo from sb_base.neo_models import get_parent_votable_content if label is None: label = get_parent_votable_content( object_uuid).get_child_label().lower() logger.critical("Updating Search Object") logger.critical({"object_uuid": object_uuid}) query = 'MATCH (a:%s {object_uuid:"%s"}) RETURN a' % \ (label.title(), object_uuid) res, _ = db.cypher_query(query) if res.one: res.one.pull() else: raise update_search_object.retry(exc=DoesNotExist( 'Object with uuid: %s ' 'does not exist' % object_uuid), countdown=3, max_retries=None) if label == "question": instance = Question.inflate(res.one) object_data = QuestionSerializerNeo(instance).data if 'mission' in object_data: object_data.pop('mission') if 'profile' in object_data: object_data.pop('profile') logger.critical(object_data) elif label == "quest": instance = Quest.inflate(res.one) object_data = QuestSerializer(instance).data logger.critical(object_data) elif label == "mission": instance = Mission.inflate(res.one) object_data = MissionSerializer(instance).data # Need to pop review_feedback because ES's serializer cannot parse # set types. # If we don't pop it we receive # TypeError("Unable to serialize set([]) (type: <type 'set'>)",)) # If we can submit a JSON serialized version we can get around this by # using: # from rest_framework.renderers import JSONRenderer # JSONRenderer().render(serializer.data) # Also please note python's json.dumps() function runs into this same # issue. if 'review_feedback' in object_data: object_data.pop('review_feedback', None) if 'quest' in object_data: object_data.pop('quest') logger.critical(object_data) elif label == "pleb": instance = Pleb.inflate(res.one) object_data = PlebSerializerNeo(instance).data if 'quest' in object_data: object_data.pop('quest') logger.critical(object_data) else: # Currently we only need this functionality for Questions as # they are the only objects in search that we display votes # for in the search interface. error_dict = { "message": "Search False setup. " "Object Data None, Instance not None", "instance_label": label, "instance_uuid": object_uuid, } logger.critical(error_dict) return False try: es = Elasticsearch(settings.ELASTIC_SEARCH_HOST) res = es.index(index=index, doc_type=object_data['type'], id=object_uuid, body=object_data) except (ElasticsearchException, TransportError, ConflictError, RequestError) as e: logger.exception("Failed to connect to Elasticsearch") logger.critical(object_data) raise update_search_object.retry(exc=e, countdown=5, max_retries=None) except KeyError: error_dict = { "message": "Search: KeyError False creation", "instance_uuid": object_uuid, "object_data": object_data } logger.critical(error_dict) return False try: if instance.search_id is None: instance.search_id = res['_id'] instance.populated_es_index = True instance.save() except AttributeError: pass cache.delete("%s_vote_search_update" % object_uuid) return res
def js_settings(request): data = { 'api': { 'google_maps': environ.get('GOOGLE_MAPS_JS'), 'stripe': settings.STRIPE_PUBLIC_KEY, 'liveaddress': settings.ADDRESS_AUTH_ID, 'stripe_transaction_fee': settings.STRIPE_TRANSACTION_PERCENT }, 'google_maps': environ.get('GOOGLE_MAPS_JS'), 'user': {}, 'static_url': settings.STATIC_URL, "default_profile_pic": static('images/sage_coffee_grey-01.png'), 'version': environ.get("SHA1", ""), 'quest_promo_key': settings.PROMOTION_KEYS[0], 'url_regex': settings.URL_REGEX } try: if request.user.is_authenticated(): data['user']['type'] = "auth" data['user']['username'] = request.user.username try: pleb = Pleb.get(request.user.username) data['profile'] = PlebSerializerNeo(pleb, context={ "request": request, "expand": True }).data # Private not available in the serializer data['profile']['stripe_account'] = pleb.stripe_account data['profile']['stripe_customer_id'] = pleb.stripe_account if data['profile']['quest'] is not None: quest = Quest.get(pleb.username) data['profile']['quest'] = QuestSerializer(quest).data if "/quests/%s/" % quest.owner_username in request.path or \ "/quests/%s/" % quest.object_uuid in request.path: data['profile']['quest']['is_owner'] = True data['profile']['quest']['available_missions'] = False if quest.account_type == "free": data['profile']['quest']['free_quest'] = True if len(quest.missions) >= settings.FREE_MISSIONS: data['profile']['quest'][ 'available_missions'] = True stripe.api_key = settings.STRIPE_SECRET_KEY stripe.api_version = settings.STRIPE_API_VERSION if "quest" in request.path: # If we're in a place where we're telling the user # that their quest is inactive lets indicate that the # quest has a card on file so they can activate if quest.stripe_default_card_id is not None: data['profile']['quest']['card_on_file'] = True else: data['profile']['quest']['card_on_file'] = False data['profile']['quest'][ 'account_type'] = quest.account_type if "quest" in request.path and "billing" in request.path: # Private not available in the serializer data['profile']['quest']['card'] = None data['profile']['quest']['subscription'] = None if quest.stripe_customer_id: customer = stripe.Customer.retrieve( quest.stripe_customer_id) if quest.stripe_default_card_id: credit_card = customer.sources.retrieve( quest.stripe_default_card_id) data['profile']['quest']['card'] = { "brand": credit_card['brand'], "last4": credit_card['last4'], "exp_month": credit_card['exp_month'], "exp_year": credit_card['exp_year'] } if quest.stripe_subscription_id is not None: subscription = customer.subscriptions.retrieve( quest.stripe_subscription_id) data['profile']['quest']['subscription'] = { "current_period_end": subscription['current_period_end'], "current_period_start": subscription['current_period_start'], "amount": subscription['plan']['amount'] } except (CypherException, IOError, Pleb.DoesNotExist, DoesNotExist): data['profile'] = None else: data['user']['type'] = "anon" except AttributeError: data['user']['type'] = "anon" js_settings_output = "var SB_APP_SETTINGS = " js_settings_output += json.dumps(data) js_settings_output += ";" return { 'js_settings': js_settings_output, }
def get(self, request, object_uuid=None, slug=None): # Do a second optional match to get the list of missions, # the first is just to make sure we're dealing with the actual # owner of the Mission. query = 'MATCH (pleb:Pleb {username: "******"})-[:IS_WAGING]->' \ '(quest:Quest) WITH quest ' \ 'OPTIONAL MATCH (quest)-[:EMBARKS_ON]->(missions:Mission) ' \ 'RETURN missions, quest ' \ 'ORDER BY missions.created DESC' % request.user.username res, _ = db.cypher_query(query) if res.one is None: return redirect("404_Error") if res.one.missions is None: return redirect("select_mission") if object_uuid is None: mission_obj = Mission.inflate(res[0].missions) return redirect('mission_settings', object_uuid=mission_obj.object_uuid, slug=slug) mission_obj = Mission.get(object_uuid) if self.template_name == "manage/epic.html" and \ not mission_obj.saved_for_later and \ not mission_obj.submitted_for_review: if mission_obj.epic is None: return redirect('must_finish_epic', object_uuid=mission_obj.object_uuid, slug=slug) return redirect("submit_mission_for_review", object_uuid=mission_obj.object_uuid, slug=slug) missions = [ MissionSerializer(Mission.inflate(row.missions)).data for row in res ] quest = Quest.inflate(res.one.quest) if mission_obj.owner_username != quest.owner_username: return redirect("404_Error") onboarding_sort, completed_count = order_tasks(object_uuid) if len(onboarding_sort) != 0: onboarding_done = int( (float(completed_count) / float(len(onboarding_sort))) * 100) else: onboarding_done = 0 return render( request, self.template_name, { "missions": missions, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "quest": QuestSerializer(quest, context={ "request": request }).data, "slug": slugify(mission_obj.get_mission_title()), "epic_template": render_to_string("manage/placeholder_epic.html"), "update_placeholder": render_to_string("updates/placeholder.html"), "onboarding_top_3": onboarding_sort[:3], "onboarding_rest": onboarding_sort[3:], "onboarding_done": onboarding_done })