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))
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))
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))
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))
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))
def related_items(request): item_id = request.GET['item_id'] item = Item.objects.get(pk=item_id) topics_of_item_dict = get_topics_of_item(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) cursor = connection.cursor() #@UndefinedVariable if topic_tuple: if len(topic_tuple) > 1: str_topic_tuple = str(topic_tuple) else: str_topic_tuple = '(' + str(topic_tuple[0]) + ')' cursor.execute('select i.id,i.name,i.url,i.share_count+i.sina_count as count 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}) related_items = cursor.fetchall() else: related_items = None return_value = {} profile = Profile.objects.get(pk=request.user.pk) return_value['items'] = related_items return_value['iframe'] = profile.iframe related_items_json = json.dumps(return_value, ensure_ascii=False) # print related_items # related_items_json = serializers.serialize('json', related_items) return HttpResponse(related_items_json)
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))
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))