def create(self, request, *args, **kwargs): # Is deprecated? user = request.user if not user.is_anonymous: request.data['user'] = user.id created_location = request.data.get('created_location') if created_location is not None: created_location = created_location.upper() request.data['created_location'] = created_location else: return Response('Missing required field `created_location`', status=status.HTTP_400_BAD_REQUEST) interaction = request.data.get('interaction', None) if interaction is not None: interaction = interaction.upper() request.data['interaction'] = interaction paper_id = request.data['paper'] res = super().create(request, *args, **kwargs) paper_event_id = res.data['id'] if created_location == PaperEvent.PAPER and PaperEvent.VIEW: create_contribution.apply_async((Contribution.SUPPORTER, { 'app_label': 'analytics', 'model': 'paperevent' }, user.id, paper_id, paper_event_id), priority=2, countdown=10)
def _create_contribution(self, decision): use_async = True if TESTING: use_async = False app_label = decision._meta.app_label model = decision._meta.model.__name__.lower() user_id = decision.peer_review.assigned_user.id unified_doc_id = decision.unified_document.id obj_id = decision.id if use_async: create_contribution.apply_async((Contribution.PEER_REVIEWER, { 'app_label': app_label, 'model': model }, user_id, unified_doc_id, obj_id), priority=1, countdown=10) else: create_contribution(contribution_type=Contribution.PEER_REVIEWER, instance_type={ 'app_label': app_label, 'model': model }, user_id=user_id, unified_doc_id=unified_doc_id, object_id=obj_id)
def create(self, request, *args, **kwargs): document_type = request.path.split('/')[2] document_id = get_document_id_from_path(request) document = RELATED_DISCUSSION_MODELS[document_type].objects.get( id=document_id) unified_document = document.unified_document unified_doc_id = unified_document.id if request.query_params.get('created_location') == 'progress': request.data['created_location'] = ( BaseComment.CREATED_LOCATION_PROGRESS) response = super().create(request, *args, **kwargs) hubs = list(unified_document.hubs.all().values_list('id', flat=True)) self.sift_track_create_content_comment(request, response, Reply) discussion_id = response.data['id'] create_contribution.apply_async((Contribution.COMMENTER, { 'app_label': 'discussion', 'model': 'reply' }, request.user.id, unified_doc_id, discussion_id), priority=3, countdown=10) doc_type = get_doc_type_key(unified_document) reset_unified_document_cache(hub_ids=hubs, document_type=[doc_type, 'all'], filters=[DISCUSSED, TRENDING]) return self.get_self_upvote_response(request, response, Reply)
def update_or_create_vote(request, user, paper, vote_type): vote = retrieve_vote(user, paper) if vote: vote.vote_type = vote_type vote.save() events_api.track_content_vote(user, vote, request) return get_vote_response(vote, 200) vote = create_vote(user, paper, vote_type) events_api.track_content_vote(user, vote, request) unified_doc_id = paper.unified_document.id create_contribution.apply_async( ( Contribution.UPVOTER, { "app_label": "paper", "model": "vote" }, user.id, unified_doc_id, vote.id, ), priority=3, countdown=10, ) return get_vote_response(vote, 201)
def hypothesis_create_contribution(created, instance, sender, update_fields, **kwargs): if created: created_by = instance.created_by unified_doc_id = instance.unified_document.id create_contribution.apply_async((Contribution.SUBMITTER, { 'app_label': 'hypothesis', 'model': 'hypothesis' }, created_by.id, unified_doc_id, instance.id), priority=3, countdown=5)
def update_or_create_vote(request, user, item, vote_type): cache_filters_to_reset = [TOP, TRENDING] if isinstance(item, (Thread, Comment, Reply)): cache_filters_to_reset = [TRENDING] hub_ids = [0] # NOTE: Hypothesis citations do not have a unified document attached has_unified_doc = hasattr(item, "unified_document") if has_unified_doc: hub_ids += list(item.unified_document.hubs.values_list("id", flat=True)) vote = retrieve_vote(user, item) # TODO: calvinhlee - figure out how to handle contributions if vote is not None: vote.vote_type = vote_type vote.save(update_fields=["updated_date", "vote_type"]) if has_unified_doc: doc_type = get_doc_type_key(item.unified_document) reset_unified_document_cache( hub_ids, document_type=[doc_type, "all"], filters=cache_filters_to_reset ) # events_api.track_content_vote(user, vote, request) return get_vote_response(vote, 200) vote = create_vote(user, item, vote_type) if has_unified_doc: doc_type = get_doc_type_key(item.unified_document) reset_unified_document_cache( hub_ids, document_type=[doc_type, "all"], filters=cache_filters_to_reset ) app_label = item._meta.app_label model = item._meta.model.__name__.lower() # events_api.track_content_vote(user, vote, request) create_contribution.apply_async( ( Contribution.UPVOTER, {"app_label": app_label, "model": model}, request.user.id, vote.unified_document.id, vote.id, ), priority=2, countdown=10, ) return get_vote_response(vote, 201)
def create(self, request, *args, **kwargs): model = request.path.split('/')[2] model_id = get_document_id_from_path(request) instance = RELATED_DISCUSSION_MODELS[model].objects.get(id=model_id) if model == 'citation': unified_document = instance.source else: unified_document = instance.unified_document if request.query_params.get('created_location') == 'progress': request.data['created_location'] = ( BaseComment.CREATED_LOCATION_PROGRESS) response = super().create(request, *args, **kwargs) response = self.get_self_upvote_response(request, response, Thread) created_thread = Thread.objects.get(id=response.data['id']) if request.data.get('review'): created_thread.review_id = request.data.get('review') created_thread.save() hubs = list(unified_document.hubs.all().values_list('id', flat=True)) discussion_id = response.data['id'] self.sift_track_create_content_comment(request, response, Thread, is_thread=True) create_contribution.apply_async((Contribution.COMMENTER, { 'app_label': 'discussion', 'model': 'thread' }, request.user.id, unified_document.id, discussion_id), priority=1, countdown=10) doc_type = get_doc_type_key(unified_document) reset_unified_document_cache( hub_ids=hubs, document_type=[doc_type, 'all'], filters=[DISCUSSED, TRENDING], ) return Response(self.serializer_class(created_thread).data, status=status.HTTP_201_CREATED)
def update_or_create_vote(request, user, summary, vote_type): vote = retrieve_vote(user, summary) if vote: vote.vote_type = vote_type vote.save(update_fields=['updated_date', 'vote_type']) events_api.track_content_vote(user, vote, request) return get_vote_response(vote, 200) vote = create_vote(user, summary, vote_type) events_api.track_content_vote(user, vote, request) create_contribution.apply_async((Contribution.UPVOTER, { 'app_label': 'summary', 'model': 'vote' }, user.id, summary.paper.unified_document.id, vote.id), priority=3, countdown=10) return get_vote_response(vote, 201)
def create(self, request): paper_id = request.data.get('paper') summary = self._create_summary(request) context = self.get_serializer_context() created = None if self._user_can_direct_edit(request.user): created = self._approve_and_add_summary_to_paper( paper_id, summary, request.user) self._invalidate_paper_cache(paper_id) update_or_create_vote(request, request.user, summary, Vote.UPVOTE) # TODO: Return old summary? # if created is not None and not created: # summary = summary.paper.summary data = SummarySerializer(summary, context=context).data create_contribution.apply_async((Contribution.CURATOR, { 'app_label': 'summary', 'model': 'summary' }, request.user.id, paper_id, summary.id), priority=2, countdown=10) return Response(data, status=201)
def create(self, request): user = request.user data = request.data amount = data['amount'] purchase_method = data['purchase_method'] purchase_type = data['purchase_type'] content_type_str = data['content_type'] object_id = data['object_id'] transfer_rsc = False recipient = None if content_type_str not in self.ALLOWED_CONTENT_TYPES: return Response(status=400) if purchase_method not in (Purchase.OFF_CHAIN, Purchase.ON_CHAIN): return Response(status=400) decimal_amount = decimal.Decimal(amount) if decimal_amount <= 0: return Response(status=400) content_type = ContentType.objects.get(model=content_type_str) with transaction.atomic(): if purchase_method == Purchase.ON_CHAIN: purchase = Purchase.objects.create( user=user, content_type=content_type, object_id=object_id, purchase_method=purchase_method, purchase_type=purchase_type, amount=amount) else: user_balance = user.get_balance() if user_balance - decimal_amount < 0: return Response('Insufficient Funds', status=402) purchase = Purchase.objects.create( user=user, content_type=content_type, object_id=object_id, purchase_method=purchase_method, purchase_type=purchase_type, amount=amount, paid_status=Purchase.PAID) source_type = ContentType.objects.get_for_model(purchase) Balance.objects.create( user=user, content_type=source_type, object_id=purchase.id, amount=f'-{amount}', ) purchase_hash = purchase.hash() purchase.purchase_hash = purchase_hash purchase_boost_time = purchase.get_boost_time(amount) purchase.boost_time = purchase_boost_time purchase.group = purchase.get_aggregate_group() purchase.save() item = purchase.item context = { 'purchase_minimal_serialization': True, 'exclude_stats': True } # transfer_rsc is set each time just in case we want # to disable rsc transfer for a specific item if content_type_str == 'paper': paper = Paper.objects.get(id=object_id) unified_doc = paper.unified_document paper.calculate_hot_score() recipient = paper.uploaded_by cache_key = get_cache_key('paper', object_id) cache.delete(cache_key) transfer_rsc = True hub_ids = paper.hubs.values_list('id', flat=True) reset_unified_document_cache( hub_ids, document_type=['all', 'paper'], filters=[TRENDING], ) elif content_type_str == 'thread': transfer_rsc = True recipient = item.created_by unified_doc = item.unified_document elif content_type_str == 'comment': transfer_rsc = True unified_doc = item.unified_document recipient = item.created_by elif content_type_str == 'reply': transfer_rsc = True unified_doc = item.unified_document recipient = item.created_by elif content_type_str == 'summary': transfer_rsc = True recipient = item.proposed_by unified_doc = item.paper.unified_document elif content_type_str == 'bulletpoint': transfer_rsc = True recipient = item.created_by unified_doc = item.paper.unified_document elif content_type_str == 'researchhubpost': transfer_rsc = True recipient = item.created_by unified_doc = item.unified_document hub_ids = unified_doc.hubs.values_list('id', flat=True) reset_unified_document_cache( hub_ids, document_type=['all', 'posts'], filters=[TRENDING], ) if unified_doc.is_removed: return Response('Content is removed', status=403) if transfer_rsc and recipient and recipient != user: distribution = create_purchase_distribution(amount) distributor = Distributor(distribution, recipient, purchase, time.time()) distributor.distribute() serializer = self.serializer_class(purchase, context=context) serializer_data = serializer.data if recipient and user: self.send_purchase_notification(purchase, unified_doc, recipient) self.send_purchase_email(purchase, recipient, unified_doc) create_contribution.apply_async((Contribution.SUPPORTER, { 'app_label': 'purchase', 'model': 'purchase' }, user.id, unified_doc.id, purchase.id), priority=2, countdown=10) return Response(serializer_data, status=201)
def create(self, validated_data): request = self.context.get("request", None) if request: user = request.user else: user = None validated_data["uploaded_by"] = user if "url" in validated_data or "pdf_url" in validated_data: error = Exception("URL uploading is deprecated") sentry.log_error(error) raise error # Prepare validated_data by removing m2m authors = validated_data.pop("authors") hubs = validated_data.pop("hubs") hypothesis_id = validated_data.pop("hypothesis_id", None) citation_type = validated_data.pop("citation_type", None) file = validated_data.get("file") try: with transaction.atomic(): # Temporary fix for updating read only fields # Not including file, pdf_url, and url because # those fields are processed for read_only_field in self.Meta.read_only_fields: if read_only_field in validated_data: validated_data.pop(read_only_field, None) # valid_doi = self._check_valid_doi(validated_data) # if not valid_doi: # raise IntegrityError('DETAIL: Invalid DOI') self._add_url(file, validated_data) self._clean_abstract(validated_data) self._add_raw_authors(validated_data) paper = None if paper is None: # It is important to note that paper signals # are ran after call to super paper = super(PaperSerializer, self).create(validated_data) paper.full_clean(exclude=["paper_type"]) unified_doc = paper.unified_document unified_doc_id = paper.unified_document.id if hypothesis_id: self._add_citation(user, hypothesis_id, unified_doc, citation_type) paper_id = paper.id paper_title = paper.paper_title or "" file = paper.file self._check_pdf_title(paper, paper_title, file) # NOTE: calvinhlee - This is an antipattern. Look into changing Vote.objects.create(paper=paper, created_by=user, vote_type=Vote.UPVOTE) # Now add m2m values properly if validated_data["paper_type"] == Paper.PRE_REGISTRATION: paper.authors.add(user.author_profile) # TODO: Do we still need add authors from the request content? paper.authors.add(*authors) self._add_orcid_authors(paper) paper.hubs.add(*hubs) for hub in hubs: hub.paper_count = hub.get_paper_count() hub.save(update_fields=["paper_count"]) try: self._add_file(paper, file) except Exception as e: sentry.log_error(e, ) paper.set_paper_completeness() # Fix adding references # self._add_references(paper) paper.pdf_license = paper.get_license(save=False) update_unified_document_to_paper(paper) tracked_paper = events_api.track_content_paper( user, paper, request) update_user_risk_score(user, tracked_paper) create_contribution.apply_async( ( Contribution.SUBMITTER, { "app_label": "paper", "model": "paper" }, user.id, unified_doc_id, paper_id, ), priority=3, countdown=10, ) celery_calculate_paper_twitter_score.apply_async((paper_id, ), priority=5, countdown=10) hub_ids = unified_doc.hubs.values_list("id", flat=True) if hub_ids.exists(): reset_unified_document_cache( hub_ids, document_type=["paper", "all"], filters=[NEWEST], with_default_hub=True, ) return paper except IntegrityError as e: sentry.log_error(e) raise e except Exception as e: error = PaperSerializerError(e, "Failed to create paper") sentry.log_error(error, base_error=error.trigger) raise error