Beispiel #1
0
def personal_search(request):
    """    
    The user can search any item within his own collections and can search **only shared items** of other users
    
    TODO: Build a hash table to store item_id in the result of user_item to reduce time from O(n^2) to O(n)
    
    Reference: http://docs.haystacksearch.org/dev/searchqueryset_api.html#field-lookups
    """
    #Two parameters to tune
    RESULTS_PER_PAGE = 10
    load_all = False
    
    query = request.GET['q'].strip()  #Heystack only accepts key name as 'q'
    user_id = int(request.GET['pid'])
    if query == '':
        sqs = EmptySearchQuerySet()
    else:
        searchqueryset = SearchQuerySet()
        if user_id == request.user.pk:
            pronoun = '我'
            own_items = User_Item.objects.filter(user__pk=request.user.pk)
        else:
            pronoun = Profile.objects.get(pk=user_id).name
            own_items = User_Item.objects.filter(user__pk=user_id).exclude(status=1)
            
        own_items_ids = []
        for oi in own_items:
            own_items_ids.append(int(oi.item_id))
        sqs = searchqueryset.auto_query(query).filter(primary_key__in=own_items_ids)
        
    if load_all:
            sqs = sqs.load_all()
    paginator = Paginator(sqs, RESULTS_PER_PAGE)   
    try:
        page = paginator.page(request.GET.get('page', 1))
        feeds_id = ''
        for result in page.object_list:
            feeds_id += str(result.object.id) + ','
        feeds_id = feeds_id[:-1]
        topics_of_item_dict = get_topics_of_item(feeds_id, request.user.pk)
        friends_of_item_dict = get_friends_of_item(feeds_id, request.user.pk)
        user_item_status_dict = get_user_items(feeds_id, request.user.pk)
    except InvalidPage:
        raise Http404
    context = {
            'query': query,
            'page': page,
            'page_type':'search',
            'topics_of_item_dict':topics_of_item_dict,
            'friends_of_item_dict':friends_of_item_dict,
            'user_item_status_dict':user_item_status_dict,
            'paginator': paginator,
            'suggestion': None,
            'pronoun': pronoun,
            'num_results': len(sqs),
            'user_id': user_id
        }
    from django.template import add_to_builtins
    add_to_builtins('haystack.templatetags.highlight')
    return render_to_response('main/search/personal_search_results.html', context, context_instance=RequestContext(request))
Beispiel #2
0
def item(request, item_id=0):
    item = Item.objects.get(pk=item_id)
    topics_of_item_dict = get_topics_of_item(item_id, request.user.pk)
    friends_of_item_dict = get_friends_of_item(item_id, request.user.pk)
    user_item_status_dict = get_user_items(item_id, request.user.pk)
    topic_list = []
    topics = []
    if item.pk in topics_of_item_dict:
        topics = topics_of_item_dict[item.pk]
        for t in topics:
            topic_list.append(int(t[0]))
    topic_tuple = tuple(topic_list)
    
    if topic_tuple:
        if len(topic_tuple) > 1:
            str_topic_tuple = str(topic_tuple)
        else:
            str_topic_tuple = '(' + str(topic_tuple[0]) + ')'
        related_items = Item.objects.raw('select i.* from \
                        main_item as i, main_item_topic as it \
                        where it.item_id<>%(1)s and it.topic_id in %(2)s and i.id = it.item_id \
                        group by it.item_id  \
                        order by count(it.item_id) desc limit 0,7' % {'1':item.id, '2':str_topic_tuple})
    else:
        related_items = None

    return render_to_response('main/item.html', {'items':[item], 'topics':topics,'item_id':item_id,
                                                 'topics_of_item_dict':topics_of_item_dict,
                                                 'friends_of_item_dict':friends_of_item_dict,
                                                 'user_item_status_dict':user_item_status_dict,
                                                  'related_items':related_items}, 
                               context_instance=RequestContext(request))
Beispiel #3
0
def top_video(request, channel_id=0):
    """ 
    By default displays the funny videos
    """
    try:
        channel_id = int(channel_id)
    except:
        raise Http404
    
    channels = Channel.objects.filter(type=1).order_by('sort_id') 
    if channel_id == 0:
        cids = [int(x.id) for x in channels]
        cf = Channel_Feed.objects.filter(channel__in=cids)
        cf = list(cf)
        cf.sort(key=lambda x: (x.sina_count / (abs(datetime.now()-x.create_date).days*24 +
                 (datetime.now()-x.create_date).seconds/3600 + 2) ** 2.2), reverse=True)
        top_70_item_list = [int(x.item_id) for x in cf[10:200]]
        feeds_id_10 = ','.join([str(f.item_id) for f in cf[:10]])
        
    else:    
        channel = get_object_or_404(Channel, pk=channel_id)
        if channel.type == 0:
            raise Http404
        #To avoid excessive join, we get top n id directly from channel feeds
        cf = Channel_Feed.objects.filter(channel__pk=channel_id)
        cf = list(cf)
        cf.sort(key=lambda x: (x.sina_count / (abs(datetime.now()-x.create_date).days*24 +
                 (datetime.now()-x.create_date).seconds/3600 + 2) ** 2.2), reverse=True)
        top_70_item_list = [int(x.item_id) for x in cf[10:200]]
        
        #feeds = Item.objects.raw('select i.* from main_item as i, \
        #        (select * from main_channel_feed where channel_id=%s order by sina_count desc limit 0, 10) as cf\
        #        where cf.item_id = i.id ' % channel_id)
        feeds_id_10 = ','.join([str(f.item_id) for f in cf[:10]])
            
    items = Item.objects.filter(pk__in=[x.item_id for x in cf[:10]])        
    topics_of_item_dict = get_topics_of_item(feeds_id_10, 0)
    if request.user.is_authenticated():
        friends_of_item_dict = get_friends_of_item(feeds_id_10, request.user.pk)
        user_item_status_dict = get_user_items(feeds_id_10, request.user.pk)
    else:
        friends_of_item_dict = {}
        user_item_status_dict = {}
        
    channels_vals = Channel.objects.filter(type=1)
    
    weight = 0
    if request.user.is_authenticated() and channel_id:
        user_channels = User_Channel.objects.filter(user=request.user.pk, channel=channel_id)
        if len(user_channels) > 0:
            weight = user_channels[0].weight
    
    return render_to_response('main/discover/top_video.html', {'page_type':'top_video', 'channels':channels, 'channels_vals':channels_vals, 'current_channel_id':channel_id, 
                               'user_channel_weight':weight, 'items':items, 'top_70_item_list':top_70_item_list, 'user_item_status_dict':user_item_status_dict,
                               'topics_of_item_dict':topics_of_item_dict, 'friends_of_item_dict':friends_of_item_dict,},
                               context_instance=RequestContext(request))
Beispiel #4
0
def search(request):
    """
    Modification/Combination based on two haystack classes:
    1,haystack/views/SearchView
    2,haystack/forms/SearchForm/search()
    
    Reference:
       #. http://docs.haystacksearch.org/dev/
       #. http://lucene.apache.org/solr/tutorial.html
    """
    #Two parameters to tune
    RESULTS_PER_PAGE = 10
    load_all = False
    
    query = request.GET['q'].strip()  #Heystack only accepts key name as 'q'
    if query == '':
        sqs = EmptySearchQuerySet()
    else:
        searchqueryset = SearchQuerySet()
        sqs = searchqueryset.auto_query(query) #The default auto_query method has been modified to use OR instead of AND
    if load_all:
            sqs = sqs.load_all()
    paginator = Paginator(sqs, RESULTS_PER_PAGE)   
    try:
        page = paginator.page(request.GET.get('page', 1))
        feeds_id = ''
        for result in page.object_list:
            feeds_id += str(result.object.id) + ',' #If an item is deleted and not reindexed, then error
        feeds_id = feeds_id[:-1]
        topics_of_item_dict = get_topics_of_item(feeds_id, request.user.pk)
        friends_of_item_dict = get_friends_of_item(feeds_id, request.user.pk)
        user_item_status_dict = get_user_items(feeds_id, request.user.pk)
    except InvalidPage:
        raise Http404
    context = {
            'query': query,
            'page': page,
            'page_type':'search',
            'topics_of_item_dict':topics_of_item_dict,
            'friends_of_item_dict':friends_of_item_dict,
            'user_item_status_dict':user_item_status_dict,
            'paginator': paginator,
            'suggestion': None,
            'num_results': len(sqs),
        }
    from django.template import add_to_builtins
    add_to_builtins('haystack.templatetags.highlight')  #Changed haystack.utils.Highlighter.highliht to not use window
    return render_to_response('main/search/web_search_results.html', context, context_instance=RequestContext(request))
Beispiel #5
0
def discover(request):
    """
    Displays top 10 tags and top items
    """
    topics = Topic.objects.all().order_by('-follower_count')[:17]
    items = Item.objects.all().order_by('-share_count')[:70]
    
    top_70_item_list = []
    len_items = len(items)
    for i in range(10, len_items):
        if i < len_items:
            top_70_item_list.append(int(items[i].pk))
    
    feeds_id_10 = ''
    for f in items[:10]:
        feeds_id_10 += str(f.id) + ','
    feeds_id_10 = feeds_id_10[:-1]
    
    topics_of_item_dict = get_topics_of_item(feeds_id_10, request.user.pk)
    friends_of_item_dict = get_friends_of_item(feeds_id_10, request.user.pk)
    user_item_status_dict = get_user_items(feeds_id_10, request.user.pk)
    
    
    itemlists = ItemList.objects.all().order_by('-follower_count')
    itemlists_id = ''
    for i in itemlists:
        itemlists_id += str(i.id) + ','
    
    topics_of_itemlist_dict = get_topics_of_itemlist(itemlists_id[:-1])
    
    
    return render_to_response('main/discover/discover.html', {'topics':topics,'items':items[:10],
                                                  'top_70_item_list':top_70_item_list,
                                                  'topics_of_item_dict':topics_of_item_dict,
                                                  'friends_of_item_dict':friends_of_item_dict,
                                                  'user_item_status_dict':user_item_status_dict,
                                                  'itemlists':itemlists, 'topics_of_itemlist_dict':topics_of_itemlist_dict },    
                               context_instance=RequestContext(request))
Beispiel #6
0
def topic(request, topic_id, type=0, redirect_from_id=0):
    """
    Renders topic page
    
    Args:
      type =
        0: Display all recent items
        1: Display hot items under this topic
    """
    type = int(type)
    if type != 0 and type != 1 and type != 2:
        raise Http404
    topic = Topic.objects.get(pk=topic_id)
    if topic.merged_to_id:
        return redirect("main.views.topic.topic", topic.merged_to_id, 0, topic.pk)
    
    if redirect_from_id:
        redirect_from_topic = Topic.objects.get(pk=redirect_from_id)
    else:
        redirect_from_topic = None          
    
    topic_childs = Topic.objects.raw('select t.* from main_topic as t, main_topic_parent as tp where\
                                     tp.parent_id= %s and tp.topic_id=t.id' % topic_id)
    
    topic_parents = Topic_Parent.objects.filter(topic__id=topic_id, parent_deleted=False)
    
    #topic_experts = Profile.objects.raw('select p.* from main_profile as p, main_user_topic_fame as utf \
    #                                    where score>0 and utf.topic_id=%s and p.user_id=utf.user_id \
    #                                    order by score desc limit 0,5' % topic.pk)
    
    user_topic = User_Topic.objects.filter(user__pk=request.user.pk, topic__pk=topic_id)
    if(user_topic):
        topic_bio = user_topic[0].topic_bio
        already_followed = True
    else:
        topic_bio = ''
        already_followed = False
    deleted = topic.deleted
    merged_to_id = topic.merged_to_id
    image_form = ImageForm()
    
    
    if type == 0:
        items = Item.objects.raw('select i.* \
                                  from main_item as i inner join \
                                  (select * from main_item_topic where topic_id= %s ) as it \
                                  on i.id=it.item_id and i.deleted=0 \
                                  order by create_date desc limit 0,20' % topic_id)
        #Not used for now: Use memcached; RawQuerySet must be converted to list before stored in memcached
#        cache_key = 't_' + topic_id + '_recent_items'
#        cache_time = 1800 # 30 min to live
#        items = cache.get(cache_key)
#        if not items:
#            items = Item.objects.raw('select i.* \
#                                  from main_item as i inner join \
#                                  (select * from main_item_topic where topic_id= %s ) as it \
#                                  on i.id=it.item_id and i.deleted=0 \
#                                  order by create_date desc limit 0,20' % topic_id )
#            cache.set(cache_key, list(items), cache_time)
    elif type == 1:
        items = Item.objects.raw('select i.* \
                                      from main_item as i inner join \
                                      (select * from main_topic_hot_item where topic_id= %s ) as thi \
                                      on i.id=thi.item_id and i.deleted=0 \
                                      order by share_count desc' % topic_id)
    else: #type=2, display itemlists under this topic
        itemlists = ItemList.objects.raw('select i.* \
                                  from main_itemlist as i inner join \
                                  (select * from main_itemlist_topic where topic_id= %s ) as it \
                                  on i.id=it.itemlist_id \
                                  order by i.follower_count desc limit 0,20' % topic_id)
    
    context_dict = {'topic':topic, 'type':type, 'redirect_from_id':redirect_from_id,
                    'redirect_from_topic':redirect_from_topic, 'topic_parents':topic_parents, 
                    #'topic_experts':topic_experts,
                    'topic_childs':topic_childs, 'image_form':image_form,
                    'already_followed':already_followed,
                    'deleted':deleted, 'merged_to_id':merged_to_id,
                    'topic_bio':topic_bio,
                    }
    
    
    if type == 0 or type == 1:
        items = list(items)
        feeds_id_10 = ','.join([str(i.id) for i in items[:10]])
           
        topics_of_item_dict = get_topics_of_item(feeds_id_10, request.user.pk)
        friends_of_item_dict = get_friends_of_item(feeds_id_10, request.user.pk)
        user_item_status_dict = get_user_items(feeds_id_10, request.user.pk)
          
        top_70_item_list = []
        for i in range(10, 69):
            if i < len(items):
                top_70_item_list.append(int(items[i].pk))
        
        #        cache_key = 't_' + topic_id + '_hot_items'
        #        cache_time = 1800 # 30 min to live
        #        items = cache.get(cache_key)
        #        if not items:
        #            items = Item.objects.raw('select i.* \
        #                                      from main_item as i inner join \
        #                                      (select * from main_topic_hot_item where topic_id= %s ) as thi \
        #                                      on i.id=thi.item_id and i.deleted=0 \
        #                                      order by share_count desc limit 0,20' % topic_id )
        #            cache.set(cache_key, list(items), cache_time)
        
        context_dict['items'] = items[:10]
        context_dict['topics_of_item_dict'] = topics_of_item_dict
        context_dict['friends_of_item_dict'] = friends_of_item_dict
        context_dict['user_item_status_dict'] = user_item_status_dict
        context_dict['top_70_item_list'] = top_70_item_list
    else: #for itemlist    
        context_dict['itemlists'] = itemlists
        itemlists_id = ''
        for i in itemlists:
            itemlists_id += str(i.id) + ','
        
        topics_of_itemlist_dict = get_topics_of_itemlist(itemlists_id[:-1])
        context_dict['topics_of_itemlist_dict'] = topics_of_itemlist_dict    
    
    
    return render_to_response('main/topic/topic.html', context_dict,
                               context_instance=RequestContext(request))
Beispiel #7
0
def index(request, type='', id=0):
    """
    Retrieve feeds shared by friends, the topic you followed, and the channel you subscribe to
    
    Args:
      `page_type` is used to distinguish between index and profile page when filtering in Redis 
    .. warning::
       Do not add @login_required decorator to this view
    """
    if not request.user.is_authenticated():
        if request.META.has_key('HTTP_USER_AGENT'):
            user_agent = request.META['HTTP_USER_AGENT']
            if (user_agent.find('MSIE 6') != -1):
                browser_warning = '我们网站对IE6或IE6内核浏览器支持不好,请换用IE9,搜狗,360极速,Chrome或Firefox'
                return render_to_response('main/account/login.html', {'browser_warning':browser_warning}, context_instance=RequestContext(request))
        return render_to_response('main/account/login.html', {}, context_instance=RequestContext(request))
    
    channel_id = 0
    feed_group_id = 0
    if type == 'feed_group':
        feed_group_id = int(id)
    elif type == 'channel':
        channel_id = int(id)
    feed_group_sort_id = 0
    cursor = connection.cursor() #@UndefinedVariable
    #Need to add condition that it's not expired
    notifications = Notification.objects.filter(user__pk=request.user.pk, unread=True).order_by('-id')[:5]
    
    # Channel that user subscribe
    cursor.execute('SELECT uc.sort_id, c.id, c.name, c.weight, uc.weight FROM main_user_channel AS uc, \
        main_channel AS c WHERE uc.channel_id=c.id AND uc.user_id=%s ORDER BY\
        uc.sort_id' % request.user.pk)
    channels = cursor.fetchall()
    channels_length = len(channels)
    
    #Used to render tabs on index page
    feed_groups = FeedGroup.objects.raw('select * from main_feedgroup where creator_id= %s order by sort_id' % request.user.pk)
    feed_groups_length = len(list(feed_groups))
    
    if feed_group_id:
        feed_group = FeedGroup.objects.get(pk=feed_group_id)
        if feed_group.creator_id != request.user.pk:
            feeds = []
        else:
            topics = feed_group.topics.split()
            users = feed_group.selected_followed.split()
            feeds, top_70_item_list = feeds_of_feedgroup(topics, users, request.user.pk)
            feeds_id_10 = ','.join([str(f.id) for f in feeds[:10]])
            feed_group_sort_id = feed_group.sort_id
    elif channel_id:
        try:
            feeds = list(Item.objects.filter(pk__in=[cf.item_id for cf in Channel_Feed.objects.filter(channel__id=channel_id)]).order_by('-sina_count'))
        except:
            feeds = []
        feeds_id_10 = ','.join([str(f.id) for f in feeds[:10]])
        top_70_item_list = [int(x.id) for x in feeds[10:200]]
    else: #get feeds by redis
        my_feeds_key = 'news_feeds_' + str(request.user.pk)
        if settings.PRODUCTION and redis_client.exists(my_feeds_key):
            feeds_id = redis_client.zrevrange(my_feeds_key, 0, 199) #inclusive
            feeds_id_10 = ','.join(feeds_id[:10])
            top_70_item_list = [int(x) for x in feeds_id[10:200]]
            feeds = Item.objects.filter(pk__in=feeds_id[:10])
        else:
            #following = User_User.objects.filter(follower__pk=request.user.pk)
            following = redis_client.zrevrange('user_following_'+str(request.user.pk), 0, -1, withscores=True)
            followed_topics = User_Topic.objects.filter(user__pk=request.user.pk)
            max_item_count = 0
            for f in followed_topics:
                if f.item_count > max_item_count:
                    max_item_count = f.item_count 
            source_dict = {}
            max_afinity_count = following[0][1] if len(following) > 0 else 1
            for f in following:
                key = 'user_shared_' + str(f[0])
                if redis_client.exists(key):
                    #source_dict[key] = f[1]
                    source_dict[key] = math.sqrt(f[1] / (max_afinity_count+1)) * 15 + 1
            for f in followed_topics:
                key = 'topic_items_' + str(f.topic_id)
                if redis_client.exists(key):
                    #source_dict[key] = f.item_count / 10 + 1
                    source_dict[key] = math.sqrt(f.item_count / (max_item_count+1)) * 10 + 1 #set the weight by interest in this topic
            for c in channels:
                key = 'channel_feeds_' + str(c[1])
                if redis_client.exists(key):
                    source_dict[key] = c[3] * c[4]
                    
            if source_dict:
                redis_client.zunionstore(my_feeds_key, source_dict)
                expire_at = datetime.now() + timedelta(seconds=600) #10 min later
                expire_at_unix = int(time.mktime(expire_at.timetuple()))
                redis_client.expireat(my_feeds_key, expire_at_unix)
                feeds_id = redis_client.zrevrange(my_feeds_key, 0, 199)  #index inclusive
                #Store for candidate to down weight tomorrow
                yesterday_key = 'news_feeds_yesterday_candidate_' + str(request.user.pk)
                if not redis_client.exists(yesterday_key):
                    for fid in feeds_id[:10]:
                        redis_client.sadd(yesterday_key, fid)
                feeds_id_10 = ','.join(feeds_id[:10])
                top_70_item_list = [int(x) for x in feeds_id[10:200]]
                feeds = Item.objects.filter(pk__in=feeds_id[:10])
            else:
                feeds = Item.objects.raw('select i.* from main_item as i, main_channel_feed as cf \
                          where cf.item_id = i.id order by i.sina_count desc limit 0,70')
                
                feeds_id_10 = ','.join([str(x.id) for x in feeds[:10]])
                top_70_item_list = [int(x.id) for x in feeds[10:200]]
    
    #Filter out the items that has been shared/favourites by the user;Filter out top 10 item yesterday
    feeds = feeds[:10]
    ui_list = get_user_item_list(feeds_id_10, request.user.pk)
    item_to_del_dict = {}
    for ui in ui_list:
        item_to_del_dict[ui[2]] = 1
    #Do not delete member while iterate over list, which will produce unpredictable result
    feeds = [f for f in feeds if f.id not in item_to_del_dict]
    if redis_client.exists('news_feeds_yesterday_'+str(request.user.pk)):
        yesterday_set = redis_client.smembers('news_feeds_yesterday_'+str(request.user.pk))
        yesterday_dict = {}
        for y in yesterday_set:
            yesterday_dict[int(y)] = 1
        filtered_feeds = []
        insert_index = 0
        for f in feeds:
            if f.id not in yesterday_dict:
                filtered_feeds.append(f)
            else:
                top_70_item_list.insert(insert_index, int(f.id))
                insert_index += 1 #maintain original order
        feeds = filtered_feeds
    feeds_id_10 = ','.join([str(f.id) for f in feeds])
    
    
        
    topics_of_item_dict = get_topics_of_item(feeds_id_10, request.user.pk)
    friends_of_item_dict = get_friends_of_item(feeds_id_10, request.user.pk)
    #This step is unnecessary since we won't show the share status of items
    user_item_status_dict = get_user_items(feeds_id_10, request.user.pk)
    
    #get sys_message
    all_sys_msgs = Sys_Message.objects.filter(type=1, expired=False)
    sys_msgs = []
    for m in all_sys_msgs:
        try:
            Sys_Message_Sta.objects.get(message=m.pk, user=request.user.pk, deleted=False, unread=True)
            sys_msgs.append(m)
        except Sys_Message_Sta.DoesNotExist:
            pass
        
        
    return render_to_response('main/index.html', {'page_type':'index', 'items':feeds, 'top_70_item_list':top_70_item_list,
                               'topics_of_item_dict':topics_of_item_dict, 'friends_of_item_dict':friends_of_item_dict,
                              'feed_groups':feed_groups, 'feed_group_id':int(feed_group_id), 'user_item_status_dict':user_item_status_dict,
                              'tab_sort_param':{'feed_group_sort_id':feed_group_sort_id, 'feed_groups_length':feed_groups_length, 
                              'channels_length':channels_length},'channel_id':channel_id,
                              'notifications': notifications, 'sys_msgs':sys_msgs, 'channels':channels, },
                               context_instance=RequestContext(request))