Пример #1
0
def feed_query(
    request,
    hints: T.list(T.dict(
        id=T.feed_unionid.object,
        dt_updated=T.datetime.object,
    )).maxlen(MAX_FEED_COUNT * 10).optional,
    detail: FeedDetailSchema,
) -> T.dict(
    total=T.int.optional,
    size=T.int.optional,
    feeds=T.list(FeedSchema).maxlen(MAX_FEED_COUNT),
    deleted_size=T.int.optional,
    deleted_ids=T.list(T.feed_unionid).maxlen(MAX_FEED_COUNT),
):
    """Feed query, if user feed count exceed limit, only return limit feeds."""
    if hints:
        # allow hints schema exceed feed count limit, but discard exceeded
        hints = hints[:MAX_FEED_COUNT]
        check_unionid(request, [x['id'] for x in hints])
    total, feeds, deleted_ids = UnionFeed.query_by_user(
        user_id=request.user.id, hints=hints, detail=detail)
    feeds = [x.to_dict() for x in feeds]
    return dict(
        total=total,
        size=len(feeds),
        feeds=feeds,
        deleted_size=len(deleted_ids),
        deleted_ids=deleted_ids,
    )
Пример #2
0
def feed_query(
    request,
    hints: T.list(
        T.dict(id=T.feed_unionid.object,
               dt_updated=T.datetime.object)).optional,
    detail: FeedDetailSchema,
) -> T.dict(
        total=T.int.optional,
        size=T.int.optional,
        feeds=T.list(FeedSchema).maxlen(5000),
        deleted_size=T.int.optional,
        deleted_ids=T.list(T.feed_unionid),
):
    """Feed query"""
    if hints:
        check_unionid(request, [x['id'] for x in hints])
    total, feeds, deleted_ids = UnionFeed.query_by_user(
        user_id=request.user.id, hints=hints, detail=detail)
    feeds = [x.to_dict() for x in feeds]
    return dict(
        total=total,
        size=len(feeds),
        feeds=feeds,
        deleted_size=len(deleted_ids),
        deleted_ids=deleted_ids,
    )
Пример #3
0
def feed_delete_all(
    request,
    ids: T.list(T.feed_unionid.object).maxlen(MAX_FEED_COUNT).optional,
) -> T.dict(num_deleted=T.int):
    check_unionid(request, ids)
    num_deleted = UnionFeed.delete_all(user_id=request.user.id, ids=ids)
    return dict(num_deleted=num_deleted)
Пример #4
0
def story_query_batch(
    request,
    storys: T.list(
        T.dict(
            feed_id=T.feed_unionid.object,
            offset=T.int.min(0),
            limit=T.int.min(1).max(10).default(1),
        )),
    detail: StoryDetailSchema,
) -> StoryResultSchema:
    feed_union_ids = [x['feed_id'] for x in storys]
    check_unionid(request, feed_union_ids)
    story_keys = []
    for item in storys:
        feed_id = item['feed_id'].feed_id
        offset = item['offset']
        for i in range(item['limit']):
            story_keys.append((feed_id, offset + i))
    storys = UnionStory.batch_get_by_feed_offset(story_keys=story_keys,
                                                 user_id=request.user.id,
                                                 detail=detail)
    storys = [x.to_dict() for x in storys]
    return dict(
        total=len(storys),
        size=len(storys),
        storys=storys,
    )
Пример #5
0
def feed_set_all_readed(
    request,
    ids: T.list(T.feed_unionid.object).maxlen(MAX_FEED_COUNT).optional,
) -> T.dict(num_updated=T.int):
    check_unionid(request, ids)
    num_updated = UnionFeed.set_all_readed_by_user(user_id=request.user.id, ids=ids)
    return dict(num_updated=num_updated)
Пример #6
0
def feed_set_all_group(
    request,
    ids: T.list(T.feed_unionid.object).maxlen(MAX_FEED_COUNT),
    group: T.str.maxlen(50),
) -> T.dict(num_updated=T.int):
    check_unionid(request, ids)
    feed_ids = [x.feed_id for x in ids]
    num_updated = UnionFeed.set_all_group(
        user_id=request.user.id, feed_ids=feed_ids, group=group)
    return dict(num_updated=num_updated)
Пример #7
0
def feed_query_creation(
    request,
    limit: T.int.min(10).max(2000).default(500),
    detail: FeedDetailSchema
) -> T.dict(
    total=T.int.min(0),
    size=T.int.min(0),
    feed_creations=T.list(FeedCreationSchema).maxlen(2000),
):
    feed_creations = FeedCreation.query_by_user(request.user.id, limit=limit, detail=detail)
    feed_creations = [x.to_dict() for x in feed_creations]
    return dict(
        total=len(feed_creations),
        size=len(feed_creations),
        feed_creations=feed_creations,
    )
Пример #8
0
def feed_create(
    request, url: _SCHEMA_FEED_CREATE_URL
) -> T.dict(
        is_ready=T.bool,
        feed=FeedSchema.optional,
        feed_creation=FeedCreationSchema.optional,
):
    """Deprecated, use feed_import instead."""
    try:
        feed, feed_creation = UnionFeed.create_by_url(url=url,
                                                      user_id=request.user.id)
    except FeedExistError:
        return Response({'message': 'already exists'}, status=400)
    if feed_creation:
        scheduler.tell(
            'worker_rss.find_feed',
            dict(
                feed_creation_id=feed_creation.id,
                url=feed_creation.url,
            ))
    return dict(
        is_ready=bool(feed),
        feed=feed.to_dict() if feed else None,
        feed_creation=feed_creation.to_dict() if feed_creation else None,
    )
Пример #9
0
def story_fetch_fulltext(
    request,
    feed_id: T.feed_unionid.object,
    offset: T.int.min(0),
) -> T.dict(
        feed_id=T.feed_unionid,
        offset=T.int.min(0),
        response_status=T.int,
        response_status_name=T.str,
        use_proxy=T.bool.optional,
        accept=T_ACCEPT.optional,
        story=StorySchema.optional,
):
    feed_unionid = feed_id
    check_unionid(request, feed_unionid)
    user_id, feed_id = feed_unionid
    content = dict(feed_id=feed_id, offset=offset)
    expire_at = int(time.time() + 60)
    use_proxy = None
    accept = None
    try:
        result = scheduler.ask('harbor_rss.sync_story_fulltext',
                               content,
                               expire_at=expire_at)
    except _TIMEOUT_ERRORS as ex:
        LOG.error(f'Ask harbor_rss.sync_story_fulltext timeout: {ex}')
        response_status = FeedResponseStatus.CONNECTION_TIMEOUT
    else:
        response_status = result['response_status']
        use_proxy = result['use_proxy']
        accept = result['accept']
    story = None
    if accept != FulltextAcceptStrategy.REJECT.value:
        story = UnionStory.get_by_feed_offset(feed_unionid,
                                              offset,
                                              detail=True)
        story = story.to_dict()
    response_status_name = FeedResponseStatus.name_of(response_status)
    return dict(
        feed_id=feed_unionid,
        offset=offset,
        response_status=response_status,
        response_status_name=response_status_name,
        use_proxy=use_proxy,
        accept=accept,
        story=story,
    )
Пример #10
0
def story_query_recent(
    request,
    feed_ids: T.list(T.feed_unionid.object).optional,
    days: T.int.min(1).max(30).default(14),
    detail: StoryDetailSchema,
) -> StoryResultSchema:
    check_unionid(request, feed_ids)
    storys = UnionStory.query_recent_by_user(user_id=request.user.id,
                                             feed_unionids=feed_ids,
                                             days=days,
                                             detail=detail)
    storys = [x.to_dict() for x in storys]
    return dict(
        total=len(storys),
        size=len(storys),
        storys=storys,
    )
Пример #11
0
def feed_create(request, url: T.url.default_schema('http')) -> T.dict(
    is_ready=T.bool,
    feed=FeedSchema.optional,
    feed_creation=FeedCreationSchema.optional,
):
    try:
        feed, feed_creation = UnionFeed.create_by_url(url=url, user_id=request.user.id)
    except FeedExistError:
        return Response({'message': 'already exists'}, status=400)
    if feed_creation:
        scheduler.tell('worker_rss.find_feed', dict(
            feed_creation_id=feed_creation.id,
            url=feed_creation.url,
        ))
    return dict(
        is_ready=bool(feed),
        feed=feed.to_dict() if feed else None,
        feed_creation=feed_creation.to_dict() if feed_creation else None,
    )
Пример #12
0
LOG = logging.getLogger(__name__)

StorySchema = T.dict(
    id=T.story_unionid,
    feed=T.dict(id=T.feed_unionid, ),
    offset=T.int,
    user=T.dict(id=T.int, ).optional,
    unique_id=T.str.optional,
    title=T.str.optional,
    link=T.str.optional,
    author=T.str.optional,
    image_url=T.str.optional,
    audio_url=T.str.optional,
    iframe_url=T.str.optional,
    has_mathjax=T.bool.optional,
    sentence_count=T.int.optional,
    dt_published=T.datetime.object.optional.invalid_to_default,
    dt_updated=T.datetime.object.optional,
    dt_created=T.datetime.object.optional,
    dt_synced=T.datetime.object.optional,
    is_watched=T.bool.default(False),
    dt_watched=T.datetime.object.optional,
    is_favorited=T.bool.default(False),
    dt_favorited=T.datetime.object.optional,
    summary=T.str.optional,
    content=T.str.optional,
    image_token=T.str.optional,
).slim

StoryResultSchema = T.dict(
    total=T.int.optional,
Пример #13
0
FeedSchema = T.dict(
    id=T.feed_unionid,
    user=T.dict(
        id=T.int,
    ),
    status=T.str,
    url=T.url,
    link=T.str.optional,
    author=T.str.optional,
    icon=T.str.optional,
    description=T.str.optional,
    version=T.str.optional,
    title=T.str.maxlen(200).optional,
    group=T.str.maxlen(50).optional,
    warnings=T.str.optional,
    num_unread_storys=T.int.optional,
    total_storys=T.int.optional,
    dt_updated=T.datetime.object.optional,
    dt_created=T.datetime.object.optional,
    dt_checked=T.datetime.object.optional,
    dt_synced=T.datetime.object.optional,
    encoding=T.str.optional,
    etag=T.str.optional,
    last_modified=T.str.optional,
    content_hash_base64=T.str.optional,
    story_offset=T.int.min(0).optional,
    dryness=T.int.min(0).max(1000).optional,
    freeze_level=T.int.min(0).optional,
    use_proxy=T.bool.optional,
    response_status=T.int.optional,
    dt_first_story_published=T.datetime.object.optional.invalid_to_default,
    dt_latest_story_published=T.datetime.object.optional.invalid_to_default,
).slim
Пример #14
0
from django.contrib.auth.models import User
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.permissions import AllowAny
from rest_framework.exceptions import AuthenticationFailed
from allauth.socialaccount.models import SocialAccount

from rssant_config import CONFIG
from rssant_common.hashid import HASH_ID

UserSchema = T.dict(
    id=T.str,
    username=T.str,
    has_usable_password=T.bool.optional,
    avatar_url=T.str.optional,
    token=T.str.optional,
    social_accounts=T.list(T.dict(
        provider=T.str,
        avatar_url=T.str.optional,
    )).optional,
    shopant_enable=T.bool.default(False),
)

UserView = RestRouter(permission_classes=[AllowAny])


def serialize_user(user):
    avatar_url = None
    social_accounts_info = []
    social_accounts = list(SocialAccount.objects.filter(user=user).all())
    for acc in social_accounts:
        if not avatar_url:
Пример #15
0
from rssant_api.models import UnionStory
from rssant_api.models.story import StoryDetailSchema
from .helper import check_unionid

StorySchema = T.dict(
    id=T.story_unionid,
    feed=T.dict(
        id=T.feed_unionid,
    ),
    offset=T.int,
    user=T.dict(
        id=T.int,
    ).optional,
    unique_id=T.str.optional,
    title=T.str.optional,
    link=T.str.optional,
    has_mathjax=T.bool.optional,
    dt_published=T.datetime.object.optional.invalid_to_default,
    dt_updated=T.datetime.object.optional,
    dt_created=T.datetime.object.optional,
    dt_synced=T.datetime.object.optional,
    is_watched=T.bool.default(False),
    dt_watched=T.datetime.object.optional,
    is_favorited=T.bool.default(False),
    dt_favorited=T.datetime.object.optional,
    summary=T.str.optional,
    content=T.str.optional,
).remove_empty

StoryResultSchema = T.dict(
    total=T.int.optional,
    size=T.int.optional,
Пример #16
0
from django_rest_validr import RestRouter, T
from django.contrib import auth as django_auth
from django.contrib.auth.models import User
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.permissions import AllowAny
from rest_framework.exceptions import AuthenticationFailed
from allauth.socialaccount.models import SocialAccount

UserSchema = T.dict(
    id=T.int,
    username=T.str,
    avatar_url=T.str.optional,
    token=T.str.optional,
)

UserView = RestRouter(permission_classes=[AllowAny])


def serialize_user(user):
    try:
        social_account = SocialAccount.objects.get(user=user)
        avatar_url = social_account.get_avatar_url()
    except SocialAccount.DoesNotExist:
        avatar_url = None
    token, created = Token.objects.get_or_create(user=user)
    return dict(
        id=user.id,
        username=user.username,
        avatar_url=avatar_url,
        token=token.key,
Пример #17
0
from django_rest_validr import RestRouter, T
from django.contrib import auth as django_auth
from django.contrib.auth.models import User
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.permissions import AllowAny
from rest_framework.exceptions import AuthenticationFailed
from allauth.socialaccount.models import SocialAccount

UserSchema = T.dict(id=T.int,
                    username=T.str,
                    avatar_url=T.str.optional,
                    token=T.str.optional,
                    social_accounts=T.list(
                        T.dict(
                            provider=T.str,
                            avatar_url=T.str.optional,
                        )).optional)

UserView = RestRouter(permission_classes=[AllowAny])


def serialize_user(user):
    avatar_url = None
    social_accounts_info = []
    social_accounts = list(SocialAccount.objects.filter(user=user).all())
    for acc in social_accounts:
        if not avatar_url:
            avatar_url = acc.get_avatar_url()
        social_accounts_info.append(
            dict(