diff --git a/python/src/video_library.py b/python/src/video_library.py index 57140e6c..4359c0b4 100644 --- a/python/src/video_library.py +++ b/python/src/video_library.py @@ -43,3 +43,16 @@ def get_video(self, video_id): does not exist. """ return self._videos.get(video_id, None) + + def get_sorted_videos(self): + """Returns list of video objects sorted lexicographically""" + sorted_list = [] + for video in self.get_all_videos(): + sorted_list.append(video.video_id) + sorted_list.sort() + + sorted_videos = [] + for id in sorted_list: + sorted_videos.append(self.get_video(id)) + + return sorted_videos diff --git a/python/src/video_player.py b/python/src/video_player.py index bb79af87..0397d086 100644 --- a/python/src/video_player.py +++ b/python/src/video_player.py @@ -1,55 +1,156 @@ """A video player class.""" from .video_library import VideoLibrary - +from .video_library import VideoLibrary +from .video_playlist import Playlist +from random import choice class VideoPlayer: """A class used to represent a Video Player.""" def __init__(self): self._video_library = VideoLibrary() + self._playlist = Playlist() + self._stack = [] + self._play = False + self._pause = False + self._flag = {} def number_of_videos(self): num_videos = len(self._video_library.get_all_videos()) print(f"{num_videos} videos in the library") - def show_all_videos(self): - """Returns all videos.""" + def number_of_videos(self): + num_videos = len(self._video_library.get_all_videos()) + print(f"{num_videos} videos in the library") - print("show_all_videos needs implementation") + def _standard_form(self, video): + """Returns video description & details in specified form""" + title = video.title + url = video.video_id + tags = video.tags + + tag_string = "" + for i, tag in enumerate(tags): + if i == 0: + tag_string += tag + else: + tag_string += " " + tag + + return (str(title) + ' (' + str(url) + ') ' + '[' + tag_string + ']') + + def _get_tagstring(self, video): + """Returns list of tags in lowercase""" + tags = video.tags + + tag_string = "" + for i, tag in enumerate(tags): + if i == 0: + tag_string += tag.lower() + else: + tag_string += " " + tag.lower() + return tag_string.split() + + def _non_flag(self): + """Returns a list of non-flagged videos""" + non = [] + for vid in self._video_library.get_all_videos(): + if vid not in self._flag: + non.append(vid) + return non + def show_all_videos(self): + """Returns a listing of all videos.""" + + print("Here's a list of all available videos:") + for video in self._video_library.get_sorted_videos(): + if video in self._flag: + print(f"{self._standard_form(video)} - FLAGGED {self._flag[video]}") + else: + print(self._standard_form(video)) + def play_video(self, video_id): """Plays the respective video. Args: video_id: The video_id to be played. """ - print("play_video needs implementation") + curr_vid = self._video_library.get_video(video_id) + + if curr_vid in self._flag: + print(f"Cannot play video: Video is currently flagged {self._flag[curr_vid]}") + return + if not self._stack and curr_vid: + print(f"Playing video: {curr_vid.title}") + self._stack.append(curr_vid) + self._play = True + self._pause = False + elif self._stack and curr_vid: + print(f"Stopping video: {self._stack.pop().title}") + print(f"Playing video: {curr_vid.title}") + self._stack.append(curr_vid) + self._play = True + self._pause = False + elif not curr_vid: + print("Cannot play video: Video does not exist") def stop_video(self): """Stops the current video.""" - print("stop_video needs implementation") + if not self._stack: + print("Cannot stop video: No video is currently playing") + else: + print(f"Stopping video: {self._stack.pop().title}") + self._play = False + self._pause = False def play_random_video(self): """Plays a random video from the video library.""" - - print("play_random_video needs implementation") + if not self._non_flag(): + print("No videos available") + return + + video = choice(self._non_flag()) + if not self._stack: + print(f"Playing video: {video.title}") + self._stack.append(video) + self._play = True + self._pause = False + else: + print(f"Stopping video: {self._stack.pop().title}") + print(f"Playing video: {video.title}") + self._stack.append(video) + self._play = True + self._pause = False def pause_video(self): """Pauses the current video.""" - - print("pause_video needs implementation") + if self._play and not self._pause: + print(f"Pausing video: {self._stack[-1].title}") + self._pause = True + elif self._play and self._pause: + print(f"Video already paused: {self._stack[-1].title}") + elif not self._play: + print("Cannot pause video: No video is currently playing") def continue_video(self): """Resumes playing the current video.""" - - print("continue_video needs implementation") + if self._play and not self._pause: + print("Cannot continue video: Video is not paused") + elif self._pause: + print(f"Continuing video: {self._stack[-1].title}") + else: + print("Cannot continue video: No video is currently playing") def show_playing(self): """Displays video currently playing.""" - print("show_playing needs implementation") + if self._play and not self._pause: + print(f"Currently playing: {self._standard_form(self._stack[-1])}") + elif self._pause: + print(f"Currently playing: {self._standard_form(self._stack[-1])} - PAUSED") + else: + print("No video is currently playing") def create_playlist(self, playlist_name): """Creates a playlist with a given name. @@ -57,7 +158,7 @@ def create_playlist(self, playlist_name): Args: playlist_name: The playlist name. """ - print("create_playlist needs implementation") + self._playlist.create(playlist_name) def add_to_playlist(self, playlist_name, video_id): """Adds a video to a playlist with a given name. @@ -66,12 +167,12 @@ def add_to_playlist(self, playlist_name, video_id): playlist_name: The playlist name. video_id: The video_id to be added. """ - print("add_to_playlist needs implementation") + self._playlist.add(playlist_name, self._video_library.get_video(video_id), self._flag) def show_all_playlists(self): """Display all playlists.""" - print("show_all_playlists needs implementation") + self._playlist.show_all() def show_playlist(self, playlist_name): """Display all videos in a playlist with a given name. @@ -79,7 +180,21 @@ def show_playlist(self, playlist_name): Args: playlist_name: The playlist name. """ - print("show_playlist needs implementation") + for list in self._playlist.lists: + if list.lower() == playlist_name.lower(): + print(f"Showing playlist: {playlist_name}") + if not self._playlist.lists[list]: + print("No videos here yet") + return + else: + for video in self._playlist.lists[list]: + if video in self._flag: + print(f"{self._standard_form(video)} - FLAGGED {self._flag[video]}") + else: + print(self._standard_form(video)) + return + + print("Cannot show playlist another_playlist: Playlist does not exist") def remove_from_playlist(self, playlist_name, video_id): """Removes a video to a playlist with a given name. @@ -88,7 +203,7 @@ def remove_from_playlist(self, playlist_name, video_id): playlist_name: The playlist name. video_id: The video_id to be removed. """ - print("remove_from_playlist needs implementation") + self._playlist.remove(playlist_name, self._video_library.get_video(video_id)) def clear_playlist(self, playlist_name): """Removes all videos from a playlist with a given name. @@ -96,7 +211,7 @@ def clear_playlist(self, playlist_name): Args: playlist_name: The playlist name. """ - print("clears_playlist needs implementation") + self._playlist.clear(playlist_name) def delete_playlist(self, playlist_name): """Deletes a playlist with a given name. @@ -104,7 +219,7 @@ def delete_playlist(self, playlist_name): Args: playlist_name: The playlist name. """ - print("deletes_playlist needs implementation") + self._playlist.delete(playlist_name) def search_videos(self, search_term): """Display all the videos whose titles contain the search_term. @@ -112,7 +227,27 @@ def search_videos(self, search_term): Args: search_term: The query to be used in search. """ - print("search_videos needs implementation") + cont = [] + for vid in self._non_flag(): + if search_term.lower() in vid.title.lower(): + cont.append(vid.video_id) + + if not cont: + print(f"No search results for {search_term}") + else: + cont.sort() + print(f"Here are the results for {search_term}:") + for i,vid_id in enumerate(cont): + print(f"{i + 1}) {self._standard_form(self._video_library.get_video(vid_id))}") + + print("Would you like to play any of the above? If yes, specify the number of the video.") + print("If your answer is not a valid number, we will assume it's a no.") + number = input("") + try: + if 1 <= int(number) <= len(cont): + print(f"Playing video: {self._video_library.get_video(cont[int(number) - 1]).title}") + except: + return def search_videos_tag(self, video_tag): """Display all videos whose tags contains the provided tag. @@ -120,7 +255,27 @@ def search_videos_tag(self, video_tag): Args: video_tag: The video tag to be used in search. """ - print("search_videos_tag needs implementation") + cont = [] + for vid in self._non_flag(): + if video_tag.lower() in self._get_tagstring(vid): + cont.append(vid.video_id) + + if not cont: + print(f"No search results for {video_tag}") + else: + cont.sort() + print(f"Here are the results for {video_tag}:") + for i,vid_id in enumerate(cont): + print(f"{i + 1}) {self._standard_form(self._video_library.get_video(vid_id))}") + + print("Would you like to play any of the above? If yes, specify the number of the video.") + print("If your answer is not a valid number, we will assume it's a no.") + number = input("") + try: + if 1 <= int(number) <= len(cont): + print(f"Playing video: {self._video_library.get_video(cont[int(number) - 1]).title}") + except: + return def flag_video(self, video_id, flag_reason=""): """Mark a video as flagged. @@ -129,7 +284,34 @@ def flag_video(self, video_id, flag_reason=""): video_id: The video_id to be flagged. flag_reason: Reason for flagging the video. """ - print("flag_video needs implementation") + if not self._video_library.get_video(video_id): + print("Cannot flag video: Video does not exist") + return + elif (self._pause or self._play) and self._stack[-1] == self._video_library.get_video(video_id): + print(f"Stopping video: {self._video_library.get_video(video_id).title}") + print(f"Successfully flagged video: {self._video_library.get_video(video_id).title} (reason: {flag_reason})") + self._flag[self._video_library.get_video(video_id)] = "(reason: " + flag_reason + ")" + self._stack.pop() + self._play = False + self._pause = False + return + elif (self._pause or self._play) and self._stack[-1] == self._video_library.get_video(video_id): + print(f"Stopping video: {self._video_library.get_video(video_id).title}") + print(f"Successfully flagged video: {self._video_library.get_video(video_id).title} (reason: Not supplied)") + self._flag[self._video_library.get_video(video_id)] = "(reason: Not supplied)" + self._stack.pop() + self._play = False + self._pause = False + return + elif not self._flag or not self._video_library.get_video(video_id) in self._flag: + if not flag_reason: + print(f"Successfully flagged video: {self._video_library.get_video(video_id).title} (reason: Not supplied)") + self._flag[self._video_library.get_video(video_id)] = "(reason: Not supplied)" + else: + print(f"Successfully flagged video: {self._video_library.get_video(video_id).title} (reason: {flag_reason})") + self._flag[self._video_library.get_video(video_id)] = "(reason: " + flag_reason + ")" + else: + print("Cannot flag video: Video is already flagged") def allow_video(self, video_id): """Removes a flag from a video. @@ -137,4 +319,11 @@ def allow_video(self, video_id): Args: video_id: The video_id to be allowed again. """ - print("allow_video needs implementation") + if not self._video_library.get_video(video_id): + print("Cannot remove flag from video: Video does not exist") + return + elif self._video_library.get_video(video_id) in self._flag: + print(f"Successfully removed flag from video: {self._video_library.get_video(video_id).title}") + del self._flag[self._video_library.get_video(video_id)] + else: + print("Cannot remove flag from video: Video is not flagged") diff --git a/python/src/video_playlist.py b/python/src/video_playlist.py index 5836da4a..17c71e34 100644 --- a/python/src/video_playlist.py +++ b/python/src/video_playlist.py @@ -3,3 +3,106 @@ class Playlist: """A class used to represent a Playlist.""" + def __init__(self): + self._lists = {} + + @property + def lists(self): + return self._lists + + def _checkCase(self, val): + """Checks if there is a match between a playist and any + of the playlists regardless of case + """ + for list in self._lists: + if list.lower() == val: + return True + return False + + def create(self, playlist): + """Creates a new playlist""" + temp = playlist.lower() + if not self._lists or not self._checkCase(temp): + self._lists[playlist] = [] + print(f"Successfully created new playlist: {playlist}") + + elif self._checkCase(temp): + print("Cannot create playlist: A playlist with the same name already exists") + + def add(self, playlist_name, video_id, flag): + """Adds videos to a playlist""" + for list in self._lists: + temp = list.lower() + temp2 = playlist_name.lower() + if temp == temp2: + if not (video_id): + print(f"Cannot add video to {playlist_name}: Video does not exist") + return + elif video_id in flag: + print(f"Cannot add video to {playlist_name}: Video is currently flagged {flag[video_id]}") + return + elif (video_id) in self._lists[list]: + print(f"Cannot add video to {playlist_name}: Video already added") + return + else: + print(f"Added video to {playlist_name}: {(video_id).title}") + self._lists[list].append(video_id) + return + + print(f"Cannot add video to {playlist_name}: Playlist does not exist") + + def show_all(self): + """Displays all playlists sorted lexicographically""" + if not self._lists: + print("No playlists exist yet") + else: + print("Showing all playlists:") + temp = [] + map = {} + + # first create list of playlists in lowercase and map lower case to actual case + for list in self._lists: + temp.append(list.lower()) + map[list.lower()] = list + + # sort list of playlists in lowercase + temp.sort() + for list in temp: + print(map[list]) + + def remove(self, playlist_name, video_id): + """Remove given playlist from list of playlists- case insensitive""" + for list in self._lists: + if list.lower() == playlist_name.lower(): + if not video_id: + print(f"Cannot remove video from {playlist_name}: Video does not exist") + return + elif video_id in self._lists[list]: + print(f"Removed video from {playlist_name}: {video_id.title}") + self._lists[list].remove(video_id) + return + else: + print(f"Cannot remove video from {playlist_name}: Video is not in playlist") + return + + print(f"Cannot remove video from {playlist_name}: Playlist does not exist") + + def clear(self, playlist): + """Remove all videos from given playlist""" + for list in self._lists: + if list.lower() == playlist.lower(): + print(f"Successfully removed all videos from {playlist}") + self._lists[list] = [] + return + + print(f"Cannot clear playlist {playlist}: Playlist does not exist") + + def delete(self, playlist): + """Delete given playlist - case insensitive""" + for list in self._lists: + if list.lower() == playlist.lower(): + print(f"Deleted playlist: {playlist}") + del self._lists[list] + return + + print(f"Cannot delete playlist {playlist}: Playlist does not exist") \ No newline at end of file