def get_distinct_channels(self, request): """ Gets a distinct list of channels from videos in this project """ project = self.get_project( request.project_id, assigned_only=True ) def _get_project_distinct_channels(project): return { o['channel_id']: o['channel_name'] for o in ( YouTubeVideo.objects .filter(projectvideos__project=project) .values('channel_id', 'channel_name') .distinct() ) } channels = cache_manager.get_or_set( _get_project_distinct_channels, project) return DistinctChannelListResponse( items=[ DistinctChannelMessage( id=channel_id, name=channel_name) for channel_id, channel_name in channels.items()], is_list=True )
def get_project_stats(self, request): """ Gets stats on videos and tag counts for the project """ project = self.get_project(request.project_id) def _get_project_stats(project): total_tags = VideoTagInstance.objects.filter( video_tag__project=project).count() tag_name_path = "video_tag__project_tag__global_tag__name" tag_name_count_path = "{0}__count".format(tag_name_path) tags = ( VideoTagInstance.objects .filter(video_tag__project=project) .values(tag_name_path) .annotate(Count(tag_name_path)) .order_by("-" + tag_name_count_path) )[:20] return { "total_videos": ( Video.non_trashed_objects .filter(project=project) .count() ), "archived_videos": Video.trash.filter(project=project).count(), "favourited_videos": ( Video.objects .filter(project=project) .filter(favourited=True) .count() ), "video_tags": total_tags, "watched_videos": ( Video.objects .values("related_users") .filter(related_users__watched=True) .annotate(Count('related_users')) .filter(related_users__count__gt=0) .count() ), "total_tags": total_tags, "top_tags": [ TagCountMessage( name=tag_obj[tag_name_path], count=tag_obj[tag_name_count_path] ) for tag_obj in tags] } items = cache_manager.get_or_set( _get_project_stats, project) return ProjectStatsMessage(**items)
def tag_list(self, request): """ API Endpoint to get a specific global tag. """ def _tag_list(): return TagListResponse( items=map( self.tag_document_mapper.map, GlobalTag.objects.all()), is_list=True ) return cache_manager.get_or_set( _tag_list, message_type=TagListResponse)
def get_current_user_stats(self, request): """ Gets the application stats for the current user """ def _get_current_user_stats(user): videos_watched = (user.related_videos.filter(watched=True).count()) return UserStatsResponse( id=user.id, videos_watched=videos_watched, tags_added=user.owner_of_tag_instances.count()) return cache_manager.get_or_set(_get_current_user_stats, self.current_user, message_type=UserStatsResponse)
def projecttag_list(self, request): """ Lists all tags on the project """ project = self.get_project(request.project_id, assigned_only=True) def _projecttag_list(project): tags = list(ProjectTag.get_tree().filter( project=project).select_related('global_tag'). with_taginstance_sum().prefill_parent_cache()) return ProjectTagListResponse(items=map(self.slim_mapper.map, tags), is_list=True) return cache_manager.get_or_set(_projecttag_list, project, message_type=ProjectTagListResponse)
def project_list_user(self, request): """ Lists all projects that the current user is assigned to """ def _project_list_user(user, pending): qry = self.PROJECT_LIST_QUERYSET.get_projects_for( self.current_user) if pending is not None: qry = qry.filter( Q(projectusers__user=user) & Q(projectusers__is_pending=pending)) items = [self.slim_mapper.map(p, current_user=user) for p in qry] return ProjectListResponse(items=items, is_list=True) return cache_manager.get_or_set(_project_list_user, self.current_user, request.pending, message_type=ProjectListResponse)
def video_tag_filter(self, request): """ API endpoint to return tag instances applied to videos Accepts filters to restrict the set of videos to return tag instances for. """ project = self.get_project(request.project_id, assigned_only=True) def _video_tag_filter(request): if request.archived: qs = Video.archived_objects.all() else: qs = Video.objects.all() qs = qs.select_related("youtube_video") if has_video_search_args(request): video_search = VideoSearch.create("videos", VideoDocument, ids_only=True) video_search = video_search.multi_filter(request) # for now, this is a plain search on the video index. # We then get all of the tags from the database and # map them in memory ids = video_search[:1000] video_map = qs.in_bulk(ids) else: video_map = {v.id: v for v in qs.filter(project=project)} return self.video_tag_mapper.map(video_map) if has_video_search_args(request): # don't cache search results return _video_tag_filter(request) return cache_manager.get_or_set(_video_tag_filter, request, message_type=VideoTagListResponse)
def video_list(self, request): """ API Endpoint to list all videos within the passed project """ project = self.get_project(request.project_id, assigned_only=True) def _video_list(request, project): if request.archived: qs = Video.archived_objects.all() else: qs = Video.objects.all() ordered_video_ids = None if request.collection_id: collection = get_obj_or_api_404(VideoCollection, pk=request.collection_id, project_id=project.pk) ordered_video_ids = list( collection.videocollectionvideos.values_list('video_id', flat=True)) if has_video_search_args(request): # build search bot video_search = VideoSearch.create("videos", VideoDocument, ids_only=True) video_search = video_search.multi_filter(request) # grab 1000 results and run the pks into an ORM lookup so that # we can return database objects to the front end. ids = video_search[:1000] # DN: this must be a slice qs = qs.filter(pk__in=ids) else: qs = qs.filter(project=project) videos = (qs.select_related("youtube_video").prefetch_related( "videocollectionvideos").order_by('-modified')) if ordered_video_ids: video_dict = {v.pk: v for v in videos} videos = [ video_dict[vid] for vid in ordered_video_ids if vid in video_dict ] # build the response return VideoListResponse(items=map(self.slim_mapper.map, videos), is_list=True) if has_video_search_args(request): # don't cache search results return _video_list(request, project) else: return cache_manager.get_or_set(_video_list, request, project, message_type=VideoListResponse, timeout=10)