Beispiel #1
0
def select_reply_review(args):
    """Select reply collection"""
    is_parameter_exists([constants.ID], args)

    # Review Id
    review_id = args[constants.ID]

    # Request User
    request_user = args[constants.USER]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # Replies Queryset
    queryset = ReplyReview.objects.filter(review_id=review_id)

    # Replies
    review_replies = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not review_replies.has_next()

    reply_ids = [review_reply.reply_id for review_reply in review_replies]

    replies, _ = __get_replies(Q(id__in=reply_ids), request_user, 10)

    return replies, page_number, is_finished
Beispiel #2
0
def select_paper_like(args):
    """Select Paper Like"""

    # Request User
    request_user = args[constants.USER]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    # Papers Queryset
    queryset = PaperLike.objects.filter(Q(user_id=request_user.id)).order_by(
        '-creation_date').values_list('paper_id', flat=True)

    # Paper Ids
    paper_ids = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not paper_ids.has_next()

    # need to maintain the order
    preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(paper_ids)])

    # Papers
    papers, _ = __get_papers(Q(id__in=paper_ids), request_user, 10, preserved)

    return papers, page_number, is_finished
Beispiel #3
0
def select_user_search_collection(args):
    """Search Users Not in Collection"""
    is_parameter_exists([constants.TEXT, constants.COLLECTION_ID], args)

    # Collection ID
    collection_id = args[constants.COLLECTION_ID]

    # Request User
    request_user = args[constants.USER]

    # Search Keyword
    keyword = args[constants.TEXT]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # User Queryset
    queryset = User.objects.annotate(
        is_in_collection=__is_in_collection('id', collection_id)).filter(
            username__icontains=keyword,
            is_in_collection=False).values_list('id', flat=True)

    # User Ids
    user_ids = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not user_ids.has_next()

    # Users
    users, _, _ = __get_users(Q(id__in=user_ids), request_user, 10)

    return users, page_number, is_finished
Beispiel #4
0
def select_paper_collection(args):
    """Select Collections' Paper"""
    is_parameter_exists([
        constants.ID
    ], args)

    # Request User
    request_user = args[constants.USER]

    # Collection Id
    collection_id = args[constants.ID]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    # Papers Queryset
    queryset = CollectionPaper.objects.filter(
        collection_id=collection_id
    )

    # Papers
    collection_papers = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not collection_papers.has_next()

    paper_ids = [collection_paper.paper_id for collection_paper in collection_papers]

    papers, _ = __get_papers(Q(id__in=paper_ids), request_user, 10)

    return papers, page_number, is_finished
Beispiel #5
0
def select_user_search(args):
    """Select User Search"""
    is_parameter_exists([constants.TEXT], args)

    # Request User
    request_user = args[constants.USER]

    # Search Keyword
    keyword = args[constants.TEXT]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # User Queryset
    queryset = User.objects.filter(Q(username__icontains=keyword)).values_list(
        'id', flat=True)

    total_count = queryset.count()  # count whole users

    # User Ids
    user_ids = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not user_ids.has_next()

    # Users
    users, _, _ = __get_users(Q(id__in=user_ids), request_user, 10)

    return users, page_number, is_finished, total_count
Beispiel #6
0
def select_user_following_collection(args):
    """Get Following Users Not in Collection"""
    is_parameter_exists([constants.COLLECTION_ID], args)

    # Collection ID
    collection_id = args[constants.COLLECTION_ID]

    # Request User
    request_user = args[constants.USER]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # QuerySet
    queryset = UserFollow.objects.annotate(is_in_collection=__is_in_collection(
        'followed_user', collection_id)).filter(
            following_user=request_user.id,
            is_in_collection=False).values_list('followed_user', flat=True)

    # User Ids
    user_ids = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not user_ids.has_next()

    # Filter Query
    filter_query = Q(id__in=user_ids)

    # Users
    users, _, _ = __get_users(filter_query, request_user, 10)

    return users, page_number, is_finished
Beispiel #7
0
def __get_reviews(filter_query,
                  request_user,
                  count,
                  params=None,
                  page_number=1):
    """Get Reviews By Query"""
    params = {} if params is None else params
    order_by = '-pk' if constants.ORDER_BY not in params else params[
        constants.ORDER_BY]

    queryset = Review.objects.filter(filter_query).annotate(
        is_liked=__is_review_liked('id', request_user)).order_by(order_by)

    total_count = queryset.count() if constants.TOTAL_COUNT in params else None

    reviews = get_results_from_queryset(queryset, count, page_number)

    is_finished = True
    if count is not None:
        is_finished = not reviews.has_next()

    pagination_value = reviews[len(reviews) - 1].id if reviews else 0

    reviews = __pack_reviews(reviews, request_user)

    return reviews, pagination_value, is_finished, total_count
Beispiel #8
0
def __get_keywords(filter_query):
    """Get Keywords By Query"""
    queryset = Keyword.objects.filter(
        filter_query
    )

    keywords = get_results_from_queryset(queryset, None)

    keywords = __pack_keywords(keywords)

    return keywords
Beispiel #9
0
def __get_publications(filter_query):
    """Get Publications"""
    queryset = Publication.objects.filter(
        filter_query
    )

    publications = get_results_from_queryset(queryset, None)

    publications = __pack_publications(publications)

    return publications
Beispiel #10
0
def __get_publishers(filter_query):
    """Get Publishers By Query"""
    queryset = Publisher.objects.filter(
        filter_query
    )

    publishers = get_results_from_queryset(queryset, None)

    publishers = __pack_publisher(publishers)

    return publishers
Beispiel #11
0
def __get_authors(filter_query):
    """Get Authors By Query"""
    queryset = Author.objects.filter(
        filter_query
    )

    authors = get_results_from_queryset(queryset, None)

    authors = __pack_authors(authors)

    return authors
Beispiel #12
0
def __get_replies(filter_query, request_user, count):
    """Get Replies By Query"""
    queryset = Reply.objects.filter(filter_query).annotate(
        is_liked=__is_reply_liked('id', request_user))

    replies = get_results_from_queryset(queryset, count)

    pagination_value = replies[len(replies) - 1].id if replies else 0

    replies = __pack_replies(replies, request_user)

    return replies, pagination_value
Beispiel #13
0
def select_user_collection(args):
    """Get Users of the given Collection"""
    is_parameter_exists([constants.ID], args)

    collection_id = args[constants.ID]

    request_user = args[constants.USER]

    # Decide if results include request_user if she or he is one of members
    includes_me = True if constants.INCLUDES_ME not in args else json.loads(
        args[constants.INCLUDES_ME])

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # Check Collection Id
    if not Collection.objects.filter(id=collection_id).exists():
        raise ApiError(constants.NOT_EXIST_OBJECT)

    # Members QuerySet (except 'pending')
    if includes_me:
        query = Q(
            collection_id=collection_id) & ~Q(type=COLLECTION_USER_TYPE[2])
    else:
        query = Q(collection_id=collection_id) & ~Q(
            user_id=request_user.id) & ~Q(type=COLLECTION_USER_TYPE[2])

    queryset = CollectionUser.objects.filter(query)

    # Members(including owner) Of Collections
    collection_members = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not collection_members.has_next()

    # Member Ids
    member_ids = [
        collection_member.user_id for collection_member in collection_members
    ]
    member_ids = list(set(member_ids))

    # Get Members
    params = {constants.COLLECTION_ID: collection_id}
    members, _, _ = __get_users(Q(id__in=member_ids),
                                request_user,
                                10,
                                params=params)

    return members, page_number, is_finished
Beispiel #14
0
def __get_collections(filter_query,
                      request_user,
                      count,
                      params=None,
                      page_number=1):
    """Get Collections By Query"""
    params = {} if params is None else params
    paper_id = None if constants.PAPER_ID not in params else params[
        constants.PAPER_ID]
    order_by = '-pk' if constants.ORDER_BY not in params else params[
        constants.ORDER_BY]
    target_user_id = request_user.id if constants.USER_ID not in params else params[
        constants.USER_ID]

    queryset = Collection.objects.annotate(
        is_user_collection=__is_member('id', target_user_id),
        is_member=__is_member('id', request_user.id),
        is_shared=__is_shared(
            'id', target_user_id)).filter(filter_query).annotate(
                is_liked=__is_collection_liked('id', request_user),
                is_owned=__is_collection_owned('id', request_user),
                contains_paper=__contains_paper('id', paper_id),
                owner_id=Subquery(CollectionUser.objects.filter(
                    collection_id=OuterRef('id'),
                    type=COLLECTION_USER_TYPE[0]).values('user_id')[:1],
                                  output_field=models.IntegerField()),
                collection_user_type=Subquery(
                    CollectionUser.objects.filter(
                        collection_id=OuterRef('id'),
                        user_id=request_user.id,
                    ).values('type')[:1],
                    output_field=models.CharField())).order_by(order_by)

    total_count = queryset.count() if constants.TOTAL_COUNT in params else None

    collections = get_results_from_queryset(queryset, count, page_number)

    is_finished = True
    if count is not None:
        is_finished = not collections.has_next()

    pagination_value = collections[len(collections) -
                                   1].id if collections else 0

    collections = __pack_collections(collections,
                                     request_user,
                                     paper_id=paper_id)

    return collections, pagination_value, is_finished, total_count
Beispiel #15
0
def __get_papers(filter_query, request_user, count, order_by='-pk'):
    """Get Papers By Query"""
    queryset = Paper.objects.filter(
        filter_query
    ).annotate(
        is_liked=__is_paper_liked('id', request_user)
    ).order_by(order_by)

    papers = get_results_from_queryset(queryset, count)

    pagination_value = papers[len(papers) - 1].id if papers else 0

    papers = __pack_papers(papers, request_user)

    return papers, pagination_value
Beispiel #16
0
def select_recommendation(args):
    """Get Recommendations"""

    request_user = args[constants.USER]
    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    recommendation_queryset = UserRecommendation.objects.filter(user_id=request_user.id).order_by('rank')

    recommendations = get_results_from_queryset(recommendation_queryset, 30, page_number)

    is_finished = not recommendations.has_next()

    recommendations = __pack_recommendations(recommendations, request_user)

    return recommendations, page_number, is_finished
Beispiel #17
0
def select_keyword_init(args):
    """Get keywords init"""

    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    keyword_queryset = (Keyword.objects.annotate(num_papers=Count('papers'))
                        .filter(num_papers__gt=9, num_papers__lt=100))

    keywords = get_results_from_queryset(keyword_queryset, 20, page_number)

    is_finished = not keywords.has_next()

    keywords = paper_utils.pack_keywords(keywords)

    return keywords, page_number, is_finished
Beispiel #18
0
def __get_users(filter_query, request_user, count, params=None):
    """Get Users By Query"""
    params = {} if params is None else params
    collection_id = None if constants.COLLECTION_ID not in params else params[
        constants.COLLECTION_ID]

    queryset = User.objects.filter(filter_query).annotate(
        is_following=__is_following('id', request_user),
        is_followed=__is_followed('id', request_user))

    # FIXME: This function needs refactoring so that it works like that of collections/utils or reviews/utils
    total_count = queryset.count() if constants.TOTAL_COUNT in params else None

    users = get_results_from_queryset(queryset, count)

    pagination_value = users[len(users) - 1].id if users else 0

    users = __pack_users(users, request_user, collection_id=collection_id)

    return users, pagination_value, total_count
Beispiel #19
0
def select_subscriptions(args):
    """Get Subscriptions of the current User"""

    request_user = args[constants.USER]
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # get the list of users that this user is following
    followings_queryset = UserFollow.objects.filter(
        following_user=request_user.id).values_list('followed_user', flat=True)

    # anonymous reviews should not be seen
    anonymous_reviews = Review.objects.filter(anonymous=True).values_list(
        'id', flat=True)

    # private collections where the user is not a member should not be seen
    private_collections = Collection.objects.annotate(
        is_member=__is_member('id', request_user.id)).filter(
            type="private", is_member=False).values_list('id', flat=True)

    # Subscription QuerySet
    subscription_queryset = Subscription.objects.filter(
        Q(actor__in=followings_queryset)).exclude(
            action_object_content_type__model="Review",
            action_object_object_id__in=anonymous_reviews,
        ).exclude(
            action_object_content_type__model="Collection",
            action_object_object_id__in=private_collections,
        )

    subscriptions = get_results_from_queryset(subscription_queryset, 20,
                                              page_number)

    # is_finished
    is_finished = not subscriptions.has_next()

    subscriptions = __pack_subscriptions(subscriptions, request_user)

    return subscriptions, page_number, is_finished
Beispiel #20
0
def select_notifications(args):
    """Get Notifications of the current User"""
    # Request User
    request_user = args[constants.USER] if constants.USER in args else None

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    # User
    user = User.objects.get(pk=request_user.id)

    # Notification QuerySet
    queryset = user.notifications.unread().filter(~Q(actor_object_id=request_user.id))

    total_count = queryset.count()

    notifications = get_results_from_queryset(queryset, 10, page_number)

    is_finished = not notifications.has_next()

    notifications = __pack_notifications(notifications)

    return notifications, page_number, is_finished, total_count
Beispiel #21
0
def __get_papers_search(result_ids, request_user, source_to_id, external, is_finished):
    """Get Papers By Query"""
    # need to maintain the order
    preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(result_ids)])

    queryset = Paper.objects.filter(
        Q(id__in=result_ids)
    ).annotate(
        is_liked=__is_paper_liked('id', request_user)
    ).order_by(preserved)

    if external:
        # if external, give all ready search results
        papers = queryset
    else:
        papers = get_results_from_queryset(queryset, SEARCH_COUNT)
        is_finished = len(papers) < SEARCH_COUNT if SEARCH_COUNT and papers else True

    pagination_value = papers[len(papers) - 1].id if papers else 0

    papers = __pack_papers(papers, request_user, source_to_id=source_to_id)

    return papers, pagination_value, is_finished
Beispiel #22
0
def select_user_followed(args):
    """Select User’s Followers"""
    is_parameter_exists([constants.ID], args)

    # Request User
    request_user = args[constants.USER]

    # Requested User ID
    requested_user_id = args[constants.ID]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(
        args[constants.PAGE_NUMBER])

    # Check User Id
    if not User.objects.filter(id=requested_user_id).exists():
        raise ApiError(constants.NOT_EXIST_OBJECT)

    # Follower QuerySet
    queryset = UserFollow.objects.filter(
        followed_user=requested_user_id).values_list('following_user',
                                                     flat=True)

    # User Ids
    user_ids = get_results_from_queryset(queryset, 10, page_number)

    # is_finished
    is_finished = not user_ids.has_next()

    # Filter Query
    filter_query = Q(id__in=user_ids)

    # Users
    users, _, _ = __get_users(filter_query, request_user, 10)

    return users, page_number, is_finished
Beispiel #23
0
def select_paper_search(args):
    """Select Paper Search"""
    is_parameter_exists([
        constants.TEXT
    ], args)

    # Request User
    request_user = args[constants.USER]

    # Search Keyword
    keyword = args[constants.TEXT]

    # Page Number
    page_number = 1 if constants.PAGE_NUMBER not in args else int(args[constants.PAGE_NUMBER])

    # Check cache
    cache_key = keyword + '_' + str(page_number)
    cache_result = cache.get(cache_key)

    if cache_result:
        logging.info("CACHE HIT: %s", cache_key)
        result_ids, paper_ids, external, is_finished = cache_result

    else:
        logging.info("CACHE MISS: %s", cache_key)
        paper_ids = {
            'papersfeed': [], # only used when all external search fails
            'arxiv': [],
            'crossref': [],
        }
        is_finished_dict = {
            'arxiv': False,
            'crossref': False,
        }

        future_to_source = {}
        with concurrent.futures.ThreadPoolExecutor() as executor:
            future_to_source[executor.submit(exploit_arxiv, keyword, page_number)] = 'arxiv'
            future_to_source[executor.submit(exploit_crossref, keyword, page_number)] = 'crossref'
            for future in concurrent.futures.as_completed(future_to_source):
                source = future_to_source[future]
                try:
                    paper_ids[source], is_finished_dict[source] = future.result()
                except Exception as exc: # pylint: disable=broad-except
                    logging.warning("[%s] generated an exception: %s", source, exc)

        external = True
        # if there are both results (len <= SEARCH_RESULT * 2)
        if paper_ids['arxiv'] and paper_ids['crossref']:
            result_ids = paper_ids['arxiv'] + paper_ids['crossref']
            is_finished = is_finished_dict['arxiv'] and is_finished_dict['crossref']

        # if only there are results of Crossref (len <= SEARCH_COUNT)
        elif not paper_ids['arxiv'] and paper_ids['crossref']:
            result_ids = paper_ids['crossref']
            is_finished = is_finished_dict['crossref']

        # if only there are results of arXiv (len <= SEARCH_COUNT)
        elif not paper_ids['crossref'] and paper_ids['arxiv']:
            result_ids = paper_ids['arxiv']
            is_finished = is_finished_dict['arxiv']

        # if cannot get any results from external sources
        else:
            external = False
            logging.info("[naive-search] Searching in PapersFeed DB")

            # Papers Queryset
            queryset = Paper.objects.filter(Q(title__icontains=keyword) | Q(abstract__icontains=keyword)) \
                .values_list('id', 'abstract')

            # Check if the papers have keywords. If not, try extracting keywords this time
            abstracts = {}
            for paper_id, abstract in queryset:
                paper_ids['papersfeed'].append(paper_id)

                if not PaperKeyword.objects.filter(paper_id=paper_id).exists():
                    abstracts[paper_id] = abstract

            if abstracts:
                __extract_keywords_from_abstract(abstracts)

            # Paper Ids
            result_ids = get_results_from_queryset(paper_ids['papersfeed'], SEARCH_COUNT, page_number)
            # is_finished (tentative)
            is_finished = False

        # Cache set
        cache.set(cache_key, (result_ids, paper_ids, external, is_finished), timeout=None)
        logging.info("CACHE SET: %s", cache_key)

    # Papers - Sometimes, there can be duplicated ids in result_ids. Thus, len(papers) < len(result_ids) is possible.
    papers, _, is_finished = __get_papers_search(result_ids, request_user, paper_ids, external, is_finished)
    return papers, page_number, is_finished