class PixabaySkill(MycroftSkill): # The constructor of the skill, which calls MycroftSkill's constructor def __init__(self): super(PixabaySkill, self).__init__(name="PixabaySkill") def initialize(self): self.add_event('pixabay-skill.aiix.home', self.handle_pixabay_homescreen) self.gui.register_handler("pixabay.show.image", self.handle_pixabay_show_image) self.gui.register_handler("pixabay.show.video", self.handle_pixabay_show_video) self.gui.register_handler("pixabay.gallery.next", self.handle_gallery_next_page) self.gui.register_handler("pixabay.gallery.previous", self.handle_gallery_previous_page) self.gui.register_handler("pixabay.idle.set_idle", self.handle_set_idlescreen_type) self.gui.register_handler("pixabay.idle.enableTime", self.handle_idle_enable_time) self.gui.register_handler("pixabay.idle.disableTime", self.handle_idle_disable_time) self.gui.register_handler("pixabay.idle.updateTime", self.handle_idle_update_time) self.gui.register_handler("pixabay.idle.removeConfigPage", self.handle_remove_configure_idle_screen) self.entKey = base64.b64decode( "MTcyMjI5NDctYTlmNTQxNmQ2ODhkNDVmNmJkZmY4ZWEzYQ==") self.video = Video(self.entKey) self.image = Image(self.entKey) self.shownPageNumber = None self.numberOfAvailablePages = None self.previousQuery = None self.currentType = None self.currentDir = dirname(dirname(abspath(__file__))) self.wantedDir = "pixabayData" self.dataPath = join(self.currentDir, self.wantedDir) self.videoPath = join(self.dataPath, "video.mp4") # Set All Paths try: os.mkdir(self.dataPath) except OSError as error: print("Directory Already Exist Skipping") self.storeDB = join(self.dataPath, 'pixabay-idle.db') self.idle_db = JsonStorage(self.storeDB) self.configDB = join(self.dataPath, 'pixabay-config.db') self.idle_config_db = JsonStorage(self.configDB) # Make Import For TimeData try: time_date_path = "/opt/mycroft/skills/mycroft-date-time.mycroftai/__init__.py" time_date_id = "datetimeskill" datetimeskill = load_skill_module(time_date_path, time_date_id) from datetimeskill import TimeSkill self.dt_skill = TimeSkill() except: print("Failed To Import DateTime Skill") def handle_pixabay_homescreen(self, message): self.handle_pixabay_display("Homescreen") @intent_file_handler("PixabaySearchImage.intent") def handle_pixabay_search_image_type(self, message): query = message.data["query"] self.previousQuery = query self.shownPageNumber = 1 self.currentType = "Image" ims = self.image.search(q=query, lang='en', image_type='photo', orientation='vertical', category='all', safesearch='true', order='latest', page=1, per_page=6) totalImages = ims['total'] totalHits = ims['totalHits'] self.handle_number_of_pages(totalImages, totalHits) self.gui["currentPageNumber"] = self.shownPageNumber self.gui["showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["imageGalleryModel"] = ims['hits'] self.handle_pixabay_display("ImageGallery") def handle_pixabay_show_image(self, message): self.gui["imageURL"] = message.data["largeImageURL"] self.handle_pixabay_display("Image") @intent_file_handler("PixabaySearchVideo.intent") def handle_pixabay_search_video_type(self, message): query = message.data["query"] self.previousQuery = query self.shownPageNumber = 1 self.currentType = "Video" vis = self.video.search(q=query, lang='en', video_type='all', category='all', page=1, per_page=6) totalImages = vis['total'] totalHits = vis['totalHits'] print(totalImages) print(totalHits) self.handle_number_of_pages(totalImages, totalHits) self.gui["currentPageNumber"] = self.shownPageNumber self.gui["showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["videoGalleryModel"] = vis['hits'] addr = vis['hits'] print(addr) self.handle_pixabay_display("VideoGallery") def handle_pixabay_show_video(self, message): orignalurl = message.data['videourl'] videoURL = self.handle_pixabay_extract_video(orignalurl) self.gui["videoURL"] = videoURL self.handle_pixabay_display("Video") def handle_pixabay_extract_video(self, videoURL): extractvideofromloc = requests.get(videoURL, allow_redirects=False) actualVideoUrl = extractvideofromloc.headers['location'] r = requests.get(actualVideoUrl, stream=True) with open(self.videoPath, 'wb') as f: for chunk in r.iter_content(chunk_size=1024 * 1024): if chunk: f.write(chunk) videoURL = self.videoPath return videoURL def handle_pixabay_display(self, state): if state is "Image": self.gui["setMessage"] = "" self.gui.show_page("Image.qml", override_idle=True) elif state is "Video": self.gui["setMessage"] = "" self.gui.show_page("Video.qml", override_idle=True) elif state is "Homescreen": self.gui.show_page("Homepage.qml", override_idle=True) else: self.gui["pageState"] = state self.gui.show_page("pixabayLoader.qml", override_idle=True) def handle_gallery_next_page(self, message): galleryType = message.data["galleryType"] pageNumber = message.data["currentPageNumber"] if pageNumber < self.numberOfAvailablePages: pageNumber = self.shownPageNumber + 1 self.shownPageNumber = pageNumber if galleryType == "Image": ims = self.image.search(q=self.previousQuery, lang='en', image_type='all', orientation='vertical', category='all', safesearch='true', order='latest', page=self.shownPageNumber, per_page=6) self.gui["currentPageNumber"] = self.shownPageNumber self.gui[ "showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["imageGalleryModel"] = ims['hits'] elif galleryType == "Video": vis = self.video.search(q=self.previousQuery, lang='en', video_type='all', category='all', page=self.shownPageNumber, per_page=6) self.gui["currentPageNumber"] = self.shownPageNumber self.gui[ "showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["videoGalleryModel"] = vis['hits'] self.handle_pixabay_display("VideoGallery") else: print("Valid Type Not Found") def handle_gallery_previous_page(self, message): galleryType = message.data["galleryType"] pageNumber = message.data["currentPageNumber"] if pageNumber > 1: pageNumber = self.shownPageNumber - 1 self.shownPageNumber = pageNumber if galleryType == "Image": ims = self.image.search(q=self.previousQuery, lang='en', image_type='all', orientation='all', category='all', safesearch='true', order='latest', page=self.shownPageNumber, per_page=6) self.gui["currentPageNumber"] = self.shownPageNumber self.gui[ "showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["imageGalleryModel"] = ims['hits'] elif galleryType == "Video": vis = self.video.search(q=self.previousQuery, lang='en', video_type='all', category='all', page=self.shownPageNumber, per_page=6) self.gui["currentPageNumber"] = self.shownPageNumber self.gui[ "showMoreAvailable"] = self.handle_show_more_available( self.shownPageNumber) self.gui["videoGalleryModel"] = vis['hits'] self.handle_pixabay_display("VideoGallery") else: print("Valid Type Not Found") @intent_handler( IntentBuilder("HandleAudioGalleryNext").require( "PixabayGalleryNextKeyword").build()) def handle_audio_gallery_next(self): currentPageNumber = self.shownPageNumber self.handle_gallery_next_page( Message( "data", { "currentPageNumber": currentPageNumber, "galleryType": self.currentType })) @intent_handler( IntentBuilder("HandleAudioGalleryNext").require( "PixabayGalleryPreviousKeyword").build()) def handle_audio_gallery_previous(self): currentPageNumber = self.shownPageNumber self.handle_gallery_previous_page( Message( "data", { "currentPageNumber": currentPageNumber, "galleryType": self.currentType })) def handle_number_of_pages(self, total, totalhits): if total > totalhits: orgNumPage = totalhits / 6 if orgNumPage > 10: self.numberOfAvailablePages = 10 return 10 else: orgNumPage = totalhits / 6 self.numberOfAvailablePages = orgNumPage return orgNumPage elif total < totalhits: orgNumPage = total / 6 if orgNumPage > 10: self.numberOfAvailablePages = 10 return 10 else: orgNumPage = totalhits / 6 self.numberOfAvailablePages = orgNumPage return orgNumPage elif total == totalhits: orgNumPage = total / 6 if orgNumPage > 10: self.numberOfAvailablePages = 10 return 10 else: self.numberOfAvailablePages = orgNumPage return orgNumPage def handle_show_more_available(self, currentPage): if currentPage < self.numberOfAvailablePages: return True else: return False def handle_set_idlescreen_type(self, message): idleType = message.data["idleType"] self.idle_db.clear() if idleType == "Image": idleImageURL = message.data["idleImageURL"] imageType = idleImageURL.split('.')[-1] imagePath = join(self.dataPath, str("pixabay-idle" + "." + imageType)) self.extract_image_for_idle(idleImageURL, imagePath) self.gui["idleType"] = "ImageIdle" self.gui["idleGenericURL"] = imagePath self.idle_db["idleInfo"] = { "idleType": "ImageIdle", "idleGenericURL": imagePath } self.idle_db.store() self.gui["setMessage"] = "New Homescreen Set" if idleType == "Video": idleVideoURL = message.data["idleVideoURL"] self.gui["idleType"] = "VideoIdle" self.gui["idleGenericURL"] = idleVideoURL self.idle_db["idleInfo"] = { "idleType": "VideoIdle", "idleGenericURL": idleVideoURL } self.idle_db.store() self.gui["setMessage"] = "New Homescreen Set" def handle_idlescreen_first_run(self): # Check If Idle Screen DB Exist and Not Empty # Retrive and Set Idle Screen if Available # If idle unset, get random and store if 'idleInfo' in self.idle_db.keys(): self.gui["idleType"] = self.idle_db["idleInfo"]["idleType"] self.gui["idleGenericURL"] = self.idle_db["idleInfo"][ "idleGenericURL"] else: imageURL = self.generate_random_idle() imageType = imageURL.split('.')[-1] imagePath = join(self.dataPath, str("pixabay-idle" + "." + imageType)) self.extract_image_for_idle(imageURL, imagePath) self.idle_db["idleInfo"] = { "idleType": "ImageIdle", "idleGenericURL": imagePath } self.idle_db.store() self.gui["idleType"] = "ImageIdle" self.gui["idleGenericURL"] = imagePath if 'showTime' in self.idle_config_db.keys(): if self.idle_config_db["showTime"] == True: self.gui["showTime"] = True self.gui[ 'time_string'] = self.dt_skill.get_display_current_time() else: self.gui["showTime"] = False self.gui["time_string"] = "" else: self.gui["showTime"] = False self.gui["time_string"] = "" def generate_random_idle(self): ims = self.image.search(q="galaxy", lang='en', image_type='photo', orientation='vertical', category='all', safesearch='true', order='latest', page=4, per_page=6) randomImageUrl = ims['hits'][4]["largeImageURL"] return randomImageUrl @resting_screen_handler('Pixabay') def handle_idle(self, message): self.gui.clear() self.log.debug('Activating Time/Date resting page') self.handle_idlescreen_first_run() self.gui.show_page('pixabayIdleLoader.qml') def extract_image_for_idle(self, url, localpath): try: image = requests.get(url) except OSError: return False if image.status_code == 200: with open(localpath, "wb") as k: k.write(image.content) else: print("Saving Image Failed") def handle_idle_enable_time(self): self.speak("I am enabling time") self.idle_config_db["showTime"] = True self.gui["showTime"] = True self.idle_config_db.store() # Send Time Data Here First self.handle_idle_update_time() def handle_idle_disable_time(self): self.speak("I am disabling time") self.idle_config_db["showTime"] = False self.gui["showTime"] = False self.idle_config_db.store() def handle_idle_update_time(self): self.gui['time_string'] = self.dt_skill.get_display_current_time() @intent_handler( IntentBuilder("PixabayIdleConfigure").require( "PixabayIdleConfigure").build()) def handle_configure_idle_screen(self): self.gui.show_page("ConfigurePixabayIdle.qml") def handle_remove_configure_idle_screen(self): self.gui.remove_page("ConfigurePixabayIdle.qml") def stop(self): pass
class YoutubeSkill(MycroftSkill): def __init__(self): super(YoutubeSkill, self).__init__(name="YoutubeSkill") self.nextpage_url = None self.previouspage_url = None self.live_category = None self.recentList = deque() self.recentPageObject = {} self.nextSongList = None self.lastSong = None self.videoPageObject = {} self.isTitle = None self.newsCategoryList = {} self.musicCategoryList = {} self.techCategoryList = {} self.polCategoryList = {} self.gamingCategoryList = {} self.searchCategoryList = {} self.storeDB = dirname(__file__) + '-recent.db' self.recent_db = JsonStorage(self.storeDB) self.ytkey = base64.b64decode("QUl6YVN5RE9tSXhSemI0RzFhaXFzYnBaQ3IwQTlFN1NrT0pVRURr") pafy.set_api_key(self.ytkey) def initialize(self): self.load_data_files(dirname(__file__)) self.bus.on('youtube-skill.aiix.home', self.launcherId) youtubepause = IntentBuilder("YoutubePauseKeyword"). \ require("YoutubePauseKeyword").build() self.register_intent(youtubepause, self.youtubepause) youtuberesume = IntentBuilder("YoutubeResumeKeyword"). \ require("YoutubeResumeKeyword").build() self.register_intent(youtuberesume, self.youtuberesume) youtubesearchpage = IntentBuilder("YoutubeSearchPageKeyword"). \ require("YoutubeSearchPageKeyword").build() self.register_intent(youtubesearchpage, self.youtubesearchpage) youtubelauncherId = IntentBuilder("YoutubeLauncherId"). \ require("YoutubeLauncherIdKeyword").build() self.register_intent(youtubelauncherId, self.launcherId) self.add_event('aiix.youtube-skill.playvideo_id', self.play_event) self.gui.register_handler('YoutubeSkill.SearchLive', self.searchLive) self.gui.register_handler('YoutubeSkill.NextPage', self.searchNextPage) self.gui.register_handler('YoutubeSkill.PreviousPage', self.searchPreviousPage) self.gui.register_handler('YoutubeSkill.NextAutoPlaySong', self.nextSongForAutoPlay) self.gui.register_handler('YoutubeSkill.RefreshWatchList', self.refreshWatchList) self.gui.register_handler('YoutubeSkill.ClearDB', self.clear_db) def launcherId(self, message): self.show_homepage({}) def getListSearch(self, text): query = quote(text) url = "https://www.youtube.com/results?search_query=" + quote(query) response = urlopen(url) html = response.read() a_tag = SoupStrainer('a') soup = BeautifulSoup(html, 'html.parser', parse_only=a_tag) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): id = vid['href'].split("v=")[1].split("&")[0] return id def moreRandomListSearch(self, text): LOG.info(text) query = quote(text) try: querySplit = text.split() LOG.info(querySplit) searchQuery = "*," + quote(querySplit[0]) + quote(querySplit[1]) + ",*" except: LOG.info("fail") searchQuery = "*," + quote(query) + ",*" LOG.info(searchQuery) return searchQuery def searchLive(self, message): videoList = [] videoList.clear() videoPageObject = {} try: query = message.data["Query"] LOG.info("I am in search Live") self.searchCategoryList["videoList"] = self.build_category_list(quote(query)) self.gui["searchListBlob"] = self.searchCategoryList self.gui["previousAvailable"] = False self.gui["nextAvailable"] = True self.gui["bgImage"] = quote(query) self.gui.show_page("YoutubeLiveSearch.qml", override_idle=True) except: LOG.debug("error") def searchNextPage(self, message): getCategory = message.data["Category"] LOG.info(getCategory) if getCategory == "News": LOG.info("In Category News") newsAdditionalPages = self.process_additional_pages("news") self.newsCategoryList['videoList'] = self.build_category_list_from_url("https://www.youtube.com" + newsAdditionalPages[0]) self.gui["newsNextAvailable"] = False self.gui["newsListBlob"] = self.newsCategoryList if getCategory == "Music": LOG.info("In Category Music") musicAdditionalPages = self.process_additional_pages("music") self.musicCategoryList['videoList'] = self.build_category_list_from_url("https://www.youtube.com" + musicAdditionalPages[0]) self.gui["musicNextAvailable"] = False self.gui["musicListBlob"] = self.musicCategoryList if getCategory == "Technology": LOG.info("In Category Technology") technologyAdditionalPages = self.process_additional_pages("technology") self.techCategoryList['videoList'] = self.build_category_list_from_url("https://www.youtube.com" + technologyAdditionalPages[0]) self.gui["techNextAvailable"] = False self.gui["techListBlob"] = self.techCategoryList if getCategory == "Politics": LOG.info("In Category Politics") politicsAdditionalPages = self.process_additional_pages("politics") self.polCategoryList['videoList'] = self.build_category_list_from_url("https://www.youtube.com" + politicsAdditionalPages[0]) self.gui["polNextAvailable"] = False self.gui["polListBlob"] = self.polCategoryList if getCategory == "Gaming": LOG.info("In Category Gaming") gamingAdditionalPages = self.process_additional_pages("gaming") self.gamingCategoryList['videoList'] = self.build_category_list_from_url("https://www.youtube.com" + gamingAdditionalPages[0]) self.gui["gamingNextAvailable"] = False self.gui["gamingListBlob"] = self.gamingCategoryList if getCategory == "Search": LOG.info("In Search") def searchPreviousPage(self, message): getCategory = message.data["Category"] LOG.info(getCategory) if getCategory == "News": LOG.info("In Category News") newsAdditionalPages = self.process_additional_pages("news") self.newsCategoryList['videoList'] = self.build_category_list_from_url(newsAdditionalPages[1]) self.gui["newsNextAvailable"] = True self.gui["newsListBlob"] = self.newsCategoryList if getCategory == "Music": LOG.info("In Category Music") musicAdditionalPages = self.process_additional_pages("music") self.musicCategoryList['videoList'] = self.build_category_list_from_url(musicAdditionalPages[1]) self.gui["musicNextAvailable"] = True self.gui["musicListBlob"] = self.musicCategoryList if getCategory == "Technology": LOG.info("In Category Technology") technologyAdditionalPages = self.process_additional_pages("technology") self.techCategoryList['videoList'] = self.build_category_list_from_url(technologyAdditionalPages[1]) self.gui["techNextAvailable"] = True self.gui["techListBlob"] = self.techCategoryList if getCategory == "Politics": LOG.info("In Category Politics") politicsAdditionalPages = self.process_additional_pages("politics") self.polCategoryList['videoList'] = self.build_category_list_from_url(politicsAdditionalPages[1]) self.gui["polNextAvailable"] = True self.gui["polListBlob"] = self.polCategoryList if getCategory == "Gaming": LOG.info("In Category Gaming") gamingAdditionalPages = self.process_additional_pages("gaming") self.gamingCategoryList['videoList'] = self.build_category_list_from_url(gamingAdditionalPages[1]) self.gui["gamingNextAvailable"] = True self.gui["gamingListBlob"] = self.gamingCategoryList if getCategory == "Search": LOG.info("In Search") def getTitle(self, text): query = quote(text) url = "https://www.youtube.com/results?search_query=" + quote(query) response = urlopen(url) html = response.read() soup = BeautifulSoup(html) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): videoTitle = vid['title'] return videoTitle @intent_file_handler('youtube.intent') def youtube(self, message): self.stop() self.gui.clear() self.enclosure.display_manager.remove_active() utterance = message.data['videoname'].lower() self.youtube_play_video(utterance) def youtube_play_video(self, utterance): self.gui["setTitle"] = "" self.gui["video"] = "" self.gui["status"] = "stop" self.gui["currenturl"] = "" self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["videoThumb"] = "" url = "https://www.youtube.com/results?search_query=" + quote(utterance) response = urlopen(url) html = response.read() a_tag = SoupStrainer('a') soup = BeautifulSoup(html, 'html.parser', parse_only=a_tag) self.gui["video"] = "" self.gui["status"] = "stop" self.gui["currenturl"] = "" self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["videoThumb"] = "" self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) rfind = soup.findAll(attrs={'class': 'yt-uix-tile-link'}) try: vid = str(rfind[0].attrs['href']) veid = "https://www.youtube.com{0}".format(vid) LOG.info(veid) getvid = vid.split("v=")[1].split("&")[0] except: vid = str(rfind[1].attrs['href']) veid = "https://www.youtube.com{0}".format(vid) LOG.info(veid) getvid = vid.split("v=")[1].split("&")[0] thumb = "https://img.youtube.com/vi/{0}/maxresdefault.jpg".format(getvid) self.gui["videoThumb"] = thumb self.lastSong = veid video = pafy.new(veid) playstream = video.streams[0] playurl = playstream.url self.gui["status"] = str("play") self.gui["video"] = str(playurl) self.gui["currenturl"] = str(vid) self.gui["currenttitle"] = video.title self.gui["setTitle"] = video.title self.gui["viewCount"] = video.viewcount self.gui["publishedDate"] = video.published self.gui["videoAuthor"] = video.username self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["nextSongTitle"] = "" self.gui["nextSongImage"] = "" self.gui["nextSongID"] = "" self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) self.gui["currenttitle"] = self.getTitle(utterance) if 'recentList' in self.recent_db.keys(): recentVideoList = self.recent_db['recentList'] else: recentVideoList = [] recentVideoList.insert(0, {"videoID": getvid, "videoTitle": video.title, "videoImage": video.thumb}) self.recent_db['recentList'] = recentVideoList self.recent_db.store() self.gui["recentListBlob"] = self.recent_db self.youtubesearchpagesimple(utterance) self.isTitle = video.title self.gui["recentListBlob"] = self.recent_db def youtubepause(self, message): self.gui["status"] = str("pause") self.gui.show_page("YoutubePlayer.qml") def youtuberesume(self, message): self.gui["status"] = str("play") self.gui.show_page("YoutubePlayer.qml") def youtubesearchpage(self, message): self.stop() videoList = [] videoList.clear() videoPageObject = {} utterance = message.data.get('utterance').lower() utterance = utterance.replace( message.data.get('YoutubeSearchPageKeyword'), '') vid = self.getListSearch(utterance) url = "https://www.youtube.com/results?search_query=" + vid response = urlopen(url) html = response.read() videoList = self.process_soup_additional(html) videoPageObject['videoList'] = videoList self.gui["videoListBlob"] = videoPageObject self.gui["recentListBlob"] = self.recent_db self.gui.show_page("YoutubeSearch.qml") def youtubesearchpagesimple(self, query): LOG.info(query) videoList = [] videoList.clear() videoPageObject = {} vid = self.moreRandomListSearch(query) url = "https://www.youtube.com/results?search_query=" + vid response = urlopen(url) html = response.read() videoList = self.process_soup_additional(html) videoPageObject['videoList'] = videoList self.gui["videoListBlob"] = videoPageObject self.gui["recentListBlob"] = self.recent_db def show_homepage(self, message): LOG.info("I AM IN HOME PAGE FUNCTION") self.gui.clear() self.enclosure.display_manager.remove_active() self.gui["loadingStatus"] = "" self.gui.show_page("YoutubeLogo.qml") self.process_home_page() def process_home_page(self): LOG.info("I AM IN HOME PROCESS PAGE FUNCTION") self.gui.show_page("YoutubeLogo.qml") self.gui["loadingStatus"] = "Fetching News" self.newsCategoryList['videoList'] = self.build_category_list("news") self.gui["loadingStatus"] = "Fetching Music" self.musicCategoryList['videoList'] = self.build_category_list("music") self.gui.clear() self.enclosure.display_manager.remove_active() self.show_search_page() self.techCategoryList['videoList'] = self.build_category_list("technology") self.gui["techListBlob"] = self.techCategoryList self.polCategoryList['videoList'] = self.build_category_list("politics") self.gui["polListBlob"] = self.polCategoryList self.gamingCategoryList['videoList'] = self.build_category_list("gaming") self.gui["gamingListBlob"] = self.gamingCategoryList LOG.info("I AM NOW IN REMOVE LOGO PAGE FUNCTION") def show_search_page(self): LOG.info("I AM NOW IN SHOW SEARCH PAGE FUNCTION") LOG.info(self.techCategoryList) self.gui["newsListBlob"] = self.newsCategoryList self.gui["newsNextAvailable"] = True self.gui["musicListBlob"] = self.musicCategoryList self.gui["musicNextAvailable"] = True self.gui["techListBlob"] = self.techCategoryList self.gui["techNextAvailable"] = True self.gui["polListBlob"] = self.polCategoryList self.gui["polNextAvailable"] = True self.gui["gamingListBlob"] = self.gamingCategoryList self.gui["gamingNextAvailable"] = True self.gui["searchListBlob"] = "" self.gui["previousAvailable"] = False self.gui["nextAvailable"] = True self.gui["bgImage"] = self.live_category self.gui.show_page("YoutubeLiveSearch.qml", override_idle=True) def play_event(self, message): urlvideo = "http://www.youtube.com/watch?v={0}".format(message.data['vidID']) self.lastSong = message.data['vidID'] video = pafy.new(urlvideo) playstream = video.getbest(preftype="mp4", ftypestrict=True) playurl = playstream.url self.speak("Playing") self.gui["video"] = str(playurl) self.gui["status"] = str("play") self.gui["currenturl"] = str(message.data['vidID']) self.gui["currenttitle"] = str(message.data['vidTitle']) self.gui["setTitle"] = video.title self.gui["viewCount"] = video.viewcount self.gui["publishedDate"] = video.published self.gui["videoAuthor"] = video.username self.gui["nextSongTitle"] = "" self.gui["nextSongImage"] = "" self.gui["nextSongID"] = "" videoTitleSearch = str(message.data['vidTitle']).join(str(message.data['vidTitle']).split()[:-1]) self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) thumb = "https://img.youtube.com/vi/{0}/maxresdefault.jpg".format(message.data['vidID']) if 'recentList' in self.recent_db.keys(): recentVideoList = self.recent_db['recentList'] else: recentVideoList = [] recentVideoList.insert(0, {"videoID": str(message.data['vidID']), "videoTitle": str(message.data['vidTitle']), "videoImage": video.thumb}) self.recent_db['recentList'] = recentVideoList self.recent_db.store() self.gui["recentListBlob"] = self.recent_db self.isTitle = video.title def stop(self): self.enclosure.bus.emit(Message("metadata", {"type": "stop"})) pass def process_soup(self, htmltype): videoList = [] videoList.clear() soup = BeautifulSoup(htmltype) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): LOG.info(vid) videoID = vid['href'].split("v=")[1].split("&")[0] videoTitle = vid['title'] videoImage = "https://i.ytimg.com/vi/{0}/hqdefault.jpg".format(videoID) videoList.append({"videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage}) if len(videoList) > 1: self.nextSongList = videoList[1] else: self.nextSongList = videoList[0] return videoList def process_soup_additional(self, htmltype): videoList = [] videoList.clear() soup = BeautifulSoup(htmltype) getVideoDetails = zip(soup.findAll(attrs={'class': 'yt-uix-tile-link'}), soup.findAll(attrs={'class': 'yt-lockup-byline'}), soup.findAll(attrs={'class': 'yt-lockup-meta-info'}), soup.findAll(attrs={'class': 'video-time'})) for vid in getVideoDetails: if "googleads" not in vid[0]['href'] and not vid[0]['href'].startswith( u"/user") and not vid[0]['href'].startswith(u"/channel"): videoID = vid[0]['href'].split("v=")[1].split("&")[0] videoTitle = vid[0]['title'] videoImage = "https://i.ytimg.com/vi/{0}/hqdefault.jpg".format(videoID) videoChannel = vid[1].contents[0].string videoUploadDate = vid[2].contents[0].string videoDuration = vid[3].contents[0].string if "watching" in vid[2].contents[0].string: videoViews = "Live" else: try: videoViews = vid[2].contents[1].string except: videoViews = "Playlist" videoList.append({"videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration}) #if len(videoList) > 1: #self.nextSongList = videoList[1] #else: #self.nextSongList = videoList[0] return videoList def process_additional_pages(self, category): url = "https://www.youtube.com/results?search_query={0}".format(category) response = urlopen(url) html = response.read() soup = BeautifulSoup(html) buttons = soup.findAll('a', attrs={'class':"yt-uix-button vve-check yt-uix-sessionlink yt-uix-button-default yt-uix-button-size-default"}) try: nPage = buttons[0]['href'] except: nPage = self.process_additional_pages_fail(category) pPage = url addPgObj = [nPage, pPage] return addPgObj def process_additional_pages_fail(self, category): url = None if category == "news": url = "/results?search_query=world+news" if category == "music": url = "/results?search_query=latest+music" if category == "technology": url = "/results?search_query=latest+tech" if category == "politics": url = "/results?search_query=latest+politics" if category == "gaming": url = "/results?search_query=latest+games" return url def nextSongForAutoPlay(self): self.gui["nextSongTitle"] = self.nextSongList["videoTitle"] self.gui["nextSongImage"] = self.nextSongList["videoImage"] self.gui["nextSongID"] = self.nextSongList["videoID"] def refreshWatchList(self, message): try: self.youtubesearchpagesimple(message.data["title"]) except: self.youtubesearchpagesimple(self.isTitle) @intent_file_handler('youtube-repeat.intent') def youtube_repeat_last(self): video = pafy.new(self.lastSong) thumb = video.thumb playstream = video.streams[0] playurl = playstream.url self.gui["status"] = str("play") self.gui["video"] = str(playurl) self.gui["currenturl"] = "" self.gui["currenttitle"] = video.title self.gui["setTitle"] = video.title self.gui["viewCount"] = video.viewcount self.gui["publishedDate"] = video.published self.gui["videoAuthor"] = video.username self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["nextSongTitle"] = "" self.gui["nextSongImage"] = "" self.gui["nextSongID"] = "" self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) self.youtubesearchpagesimple(video.title) self.isTitle = video.title def build_category_list(self, category): url = "https://www.youtube.com/results?search_query={0}".format(category) response = urlopen(url) html = response.read() videoList = self.process_soup_additional(html) return videoList def build_category_list_from_url(self, link): url = link print(url) response = urlopen(url) html = response.read() videoList = self.process_soup_additional(html) return videoList def clear_db(self): LOG.info("In DB Clear") self.recent_db.clear() self.recent_db.store() self.gui["recentListBlob"] = ""
class YoutubeSkill(MycroftSkill): def __init__(self): super(YoutubeSkill, self).__init__(name="YoutubeSkill") self.nextpage_url = None self.previouspage_url = None self.live_category = None self.recentList = deque() self.recentPageObject = {} self.nextSongList = None self.lastSong = None self.videoPageObject = {} self.isTitle = None self.trendCategoryList = {} self.newsCategoryList = {} self.musicCategoryList = {} self.techCategoryList = {} self.polCategoryList = {} self.gamingCategoryList = {} self.searchCategoryList = {} self.recentCategoryList = {} self.recentWatchListObj = {} self.storeDB = dirname(__file__) + '-recent.db' self.recent_db = JsonStorage(self.storeDB) self.ytkey = base64.b64decode( "QUl6YVN5RE9tSXhSemI0RzFhaXFzYnBaQ3IwQTlFN1NrT0pVRURr") pafy.set_api_key(self.ytkey) self.quackAPIWorker = "J0dvb2dsZWJvdC8yLjEgKCtodHRwOi8vd3d3Lmdvb2dsZS5jb20vYm90Lmh0bWwpJw==" self.quackagent = {'User-Agent': base64.b64decode(self.quackAPIWorker)} self.yts = YoutubeSearcher() def initialize(self): self.load_data_files(dirname(__file__)) self.bus.on('youtube-skill.aiix.home', self.launcherId) youtubepause = IntentBuilder("YoutubePauseKeyword"). \ require("YoutubePauseKeyword").build() self.register_intent(youtubepause, self.youtubepause) youtuberesume = IntentBuilder("YoutubeResumeKeyword"). \ require("YoutubeResumeKeyword").build() self.register_intent(youtuberesume, self.youtuberesume) youtubesearchpage = IntentBuilder("YoutubeSearchPageKeyword"). \ require("YoutubeSearchPageKeyword").build() self.register_intent(youtubesearchpage, self.youtubesearchpage) youtubelauncherId = IntentBuilder("YoutubeLauncherId"). \ require("YoutubeLauncherIdKeyword").build() self.register_intent(youtubelauncherId, self.launcherId) self.add_event('aiix.youtube-skill.playvideo_id', self.play_event) self.gui.register_handler('YoutubeSkill.SearchLive', self.searchLive) self.gui.register_handler('YoutubeSkill.NextPage', self.searchNextPage) self.gui.register_handler('YoutubeSkill.PreviousPage', self.searchPreviousPage) self.gui.register_handler('YoutubeSkill.NextAutoPlaySong', self.nextSongForAutoPlay) self.gui.register_handler('YoutubeSkill.RefreshWatchList', self.refreshWatchList) self.gui.register_handler('YoutubeSkill.ClearDB', self.clear_db) self.gui.register_handler('YoutubeSkill.ReplayLast', self.youtube_repeat_last) def launcherId(self, message): self.show_homepage({}) @intent_file_handler('youtubeopenapp.intent') def launch_home_and_search_category(self, message): self.speak("Loading Up Youtube For You") self.show_homepage({}) def getListSearch(self, text): query = quote(text) url = "https://www.youtube.com/results?search_query=" + quote(query) response = requests.get(url, headers=self.quackagent) html = response.text a_tag = SoupStrainer('a') soup = BeautifulSoup(html, 'html.parser', parse_only=a_tag) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): id = vid['href'].split("v=")[1].split("&")[0] return id def moreRandomListSearch(self, text): LOG.info(text) query = quote(text) try: querySplit = text.split() LOG.info(querySplit) searchQuery = "*," + quote(querySplit[0]) + quote( querySplit[1]) + ",*" except: LOG.info("fail") searchQuery = "*," + quote(query) + ",*" LOG.info(searchQuery) return searchQuery def searchLive(self, message): videoList = [] videoList.clear() videoPageObject = {} try: query = message.data["Query"] LOG.info("I am in search Live") self.searchCategoryList["videoList"] = self.build_category_list( quote(query)) self.gui["searchListBlob"] = self.searchCategoryList self.gui["previousAvailable"] = False self.gui["nextAvailable"] = True self.gui["bgImage"] = quote(query) self.gui.show_page("YoutubeLiveSearch.qml", override_idle=True) except: LOG.debug("error") def searchNextPage(self, message): getCategory = message.data["Category"] LOG.info(getCategory) if getCategory == "News": LOG.info("In Category News") newsAdditionalPages = self.process_additional_pages("news") self.newsCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com" + newsAdditionalPages[0]) self.gui["newsNextAvailable"] = False self.gui["newsListBlob"] = self.newsCategoryList if getCategory == "Music": LOG.info("In Category Music") musicAdditionalPages = self.process_additional_pages("music") self.musicCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com" + musicAdditionalPages[0]) self.gui["musicNextAvailable"] = False self.gui["musicListBlob"] = self.musicCategoryList if getCategory == "Technology": LOG.info("In Category Technology") technologyAdditionalPages = self.process_additional_pages( "technology") self.techCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com" + technologyAdditionalPages[0]) self.gui["techNextAvailable"] = False self.gui["techListBlob"] = self.techCategoryList if getCategory == "Politics": LOG.info("In Category Politics") politicsAdditionalPages = self.process_additional_pages("politics") self.polCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com" + politicsAdditionalPages[0]) self.gui["polNextAvailable"] = False self.gui["polListBlob"] = self.polCategoryList if getCategory == "Gaming": LOG.info("In Category Gaming") gamingAdditionalPages = self.process_additional_pages("gaming") self.gamingCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com" + gamingAdditionalPages[0]) self.gui["gamingNextAvailable"] = False self.gui["gamingListBlob"] = self.gamingCategoryList if getCategory == "Search": LOG.info("In Search") def searchPreviousPage(self, message): getCategory = message.data["Category"] LOG.info(getCategory) if getCategory == "News": LOG.info("In Category News") newsAdditionalPages = self.process_additional_pages("news") self.newsCategoryList[ 'videoList'] = self.build_category_list_from_url( newsAdditionalPages[1]) self.gui["newsNextAvailable"] = True self.gui["newsListBlob"] = self.newsCategoryList if getCategory == "Music": LOG.info("In Category Music") musicAdditionalPages = self.process_additional_pages("music") self.musicCategoryList[ 'videoList'] = self.build_category_list_from_url( musicAdditionalPages[1]) self.gui["musicNextAvailable"] = True self.gui["musicListBlob"] = self.musicCategoryList if getCategory == "Technology": LOG.info("In Category Technology") technologyAdditionalPages = self.process_additional_pages( "technology") self.techCategoryList[ 'videoList'] = self.build_category_list_from_url( technologyAdditionalPages[1]) self.gui["techNextAvailable"] = True self.gui["techListBlob"] = self.techCategoryList if getCategory == "Politics": LOG.info("In Category Politics") politicsAdditionalPages = self.process_additional_pages("politics") self.polCategoryList[ 'videoList'] = self.build_category_list_from_url( politicsAdditionalPages[1]) self.gui["polNextAvailable"] = True self.gui["polListBlob"] = self.polCategoryList if getCategory == "Gaming": LOG.info("In Category Gaming") gamingAdditionalPages = self.process_additional_pages("gaming") self.gamingCategoryList[ 'videoList'] = self.build_category_list_from_url( gamingAdditionalPages[1]) self.gui["gamingNextAvailable"] = True self.gui["gamingListBlob"] = self.gamingCategoryList if getCategory == "Search": LOG.info("In Search") def getTitle(self, text): query = quote(text) url = "https://www.youtube.com/results?search_query=" + quote(query) response = requests.get(url, headers=self.quackagent) html = response.text soup = BeautifulSoup(html) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): videoTitle = vid['title'] return videoTitle @intent_file_handler('youtube.intent') def youtube(self, message): self.stop() self.gui.clear() self.enclosure.display_manager.remove_active() utterance = message.data['videoname'].lower() self.youtube_play_video(utterance) def youtube_play_video(self, utterance): self.gui["setTitle"] = "" self.gui["video"] = "" self.gui["status"] = "stop" self.gui["currenturl"] = "" self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["videoThumb"] = "" url = "https://www.youtube.com/results?search_query=" + quote( utterance) response = requests.get(url, headers=self.quackagent) html = response.text a_tag = SoupStrainer('a') soup = BeautifulSoup(html, 'html.parser', parse_only=a_tag) self.gui["video"] = "" self.gui["status"] = "stop" self.gui["currenturl"] = "" self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["videoThumb"] = "" video_query_str = str(quote(utterance)) print(video_query_str) abc = self.yts.search_youtube(video_query_str, render="videos") vid = abc['videos'][0]['url'] ydl = youtube_dl.YoutubeDL({'outtmpl': '%(id)s%(ext)s'}) with ydl: ytresult = ydl.extract_info( vid, download=False # We just want to extract the info ) if 'entries' in ytresult: ytvideo = ytresult['entries'][0] else: ytvideo = ytresult stream_url = self.process_ytl_stream(ytvideo["formats"]) getvid = vid.split("v=")[1].split("&")[0] thumb = "https://img.youtube.com/vi/{0}/0.jpg".format(getvid) self.gui["videoThumb"] = thumb self.lastSong = vid self.gui["status"] = str("play") self.gui["video"] = str(stream_url) self.gui["currenturl"] = str(vid) self.gui["currenttitle"] = abc['videos'][0]['title'] self.gui["setTitle"] = abc['videos'][0]['title'] self.gui["viewCount"] = abc['videos'][0]['views'] self.gui["publishedDate"] = abc['videos'][0]['published_time'] self.gui["videoAuthor"] = abc['videos'][0]['channel_name'] self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["nextSongBlob"] = "" self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) self.gui["currenttitle"] = self.getTitle(utterance) LOG.info("Video Published On") recentVideoDict = { "videoID": getvid, "videoTitle": abc['videos'][0]['title'], "videoImage": thumb, "videoChannel": abc['videos'][0]['channel_name'], "videoViews": abc['videos'][0]['views'], "videoUploadDate": abc['videos'][0]['published_time'], "videoDuration": abc['videos'][0]['length'] } self.buildHistoryModel(recentVideoDict) self.gui["recentListBlob"] = self.recent_db self.youtubesearchpagesimple(getvid) self.isTitle = abc['videos'][0]['title'] self.gui["recentListBlob"] = self.recent_db def process_ytl_stream(self, streams): _videostreams = [] for z in range(len(streams)): if streams[z].get("vcodec") != "none": if streams[z].get("acodec") != "none": _videostreams.append(streams[z]) for a in range(len(_videostreams)): if _videostreams[a]["format_note"] == "720p": return _videostreams[a]["url"] elif _videostreams[a]["format_note"] == "480p": return _videostreams[a]["url"] elif _videostreams[a]["format_note"] == "360p": return _videostreams[a]["url"] elif _videostreams[a]["format_note"] == "240p": return _videostreams[a]["url"] elif _videostreams[a]["format_note"] == "144p": return _videostreams[a]["url"] def youtubepause(self, message): self.gui["status"] = str("pause") self.gui.show_page("YoutubePlayer.qml") def youtuberesume(self, message): self.gui["status"] = str("play") self.gui.show_page("YoutubePlayer.qml") def youtubesearchpage(self, message): self.stop() videoList = [] videoList.clear() videoPageObject = {} utterance = message.data.get('utterance').lower() utterance = utterance.replace( message.data.get('YoutubeSearchPageKeyword'), '') vid = self.getListSearch(utterance) url = "https://www.youtube.com/results?search_query=" + vid response = requests.get(url, headers=self.quackagent) html = response.text videoList = self.process_soup_additional(html) videoPageObject['videoList'] = videoList self.gui["videoListBlob"] = videoPageObject self.gui["recentListBlob"] = self.recent_db self.gui.show_page("YoutubeSearch.qml") def youtubesearchpagesimple(self, query): LOG.info(query) videoList = [] videoList.clear() videoPageObject = {} yts = YoutubeSearcher() vidslist = yts.watchlist_search(video_id=query) for x in range(len(vidslist['watchlist_videos'])): videoID = vidslist['watchlist_videos'][x]['videoId'] videoTitle = vidslist['watchlist_videos'][x]['title'] videoImage = "https://img.youtube.com/vi/{0}/0.jpg".format(videoID) videoUploadDate = vidslist['watchlist_videos'][x]['published_time'] videoDuration = vidslist['watchlist_videos'][x]['length'] videoViews = vidslist['watchlist_videos'][x]['views'] videoChannel = vidslist['watchlist_videos'][x]['channel_name'] videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration }) videoPageObject['videoList'] = videoList self.gui["videoListBlob"] = videoPageObject self.gui["recentListBlob"] = self.recent_db def show_homepage(self, message): LOG.info("I AM IN HOME PAGE FUNCTION") self.gui.clear() self.enclosure.display_manager.remove_active() self.gui["loadingStatus"] = "" self.gui.show_page("YoutubeLogo.qml") self.process_home_page() def process_home_page(self): LOG.info("I AM IN HOME PROCESS PAGE FUNCTION") self.gui["loadingStatus"] = "Fetching Trends" self.trendCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com/feed/trending") if self.trendCategoryList['videoList']: LOG.info("Trends Not Empty") else: LOG.info("Trying To Rebuild Trends List") self.trendCategoryList[ 'videoList'] = self.build_category_list_from_url( "https://www.youtube.com/feed/trending") self.gui["loadingStatus"] = "Fetching News" self.newsCategoryList['videoList'] = self.build_category_list("news") if self.newsCategoryList['videoList']: LOG.info("News Not Empty") else: LOG.info("Trying To Rebuild News List") self.newsCategoryList['videoList'] = self.build_category_list( "news") self.build_recent_watch_list(20) self.gui.clear() self.enclosure.display_manager.remove_active() self.show_search_page() self.musicCategoryList['videoList'] = self.build_category_list("music") if self.musicCategoryList['videoList']: LOG.info("Music Not Empty") else: LOG.info("Trying To Rebuild Music List") self.musicCategoryList['videoList'] = self.build_category_list( "music") self.gui["musicListBlob"] = self.musicCategoryList self.techCategoryList['videoList'] = self.build_category_list( "technology") if self.techCategoryList['videoList']: LOG.info("Tech Not Empty") else: LOG.info("Trying To Rebuild Tech List") self.techCategoryList['videoList'] = self.build_category_list( "technology") self.gui["techListBlob"] = self.techCategoryList self.polCategoryList['videoList'] = self.build_category_list( "politics") if self.polCategoryList['videoList']: LOG.info("Pol Not Empty") else: LOG.info("Trying To Rebuild Pol List") self.polCategoryList['videoList'] = self.build_category_list( "politics") self.gui["polListBlob"] = self.polCategoryList self.gamingCategoryList['videoList'] = self.build_category_list( "gaming") if self.gamingCategoryList['videoList']: LOG.info("Gaming Not Empty") else: LOG.info("Trying To Rebuild Pol List") self.gamingCategoryList['videoList'] = self.build_category_list( "gaming") self.gui["gamingListBlob"] = self.gamingCategoryList LOG.info("I AM NOW IN REMOVE LOGO PAGE FUNCTION") def show_search_page(self): LOG.info("I AM NOW IN SHOW SEARCH PAGE FUNCTION") LOG.info(self.techCategoryList) self.gui["recentHomeListBlob"] = self.recentWatchListObj self.gui["recentListBlob"] = self.recent_db self.gui["trendListBlob"] = self.trendCategoryList self.gui["newsListBlob"] = self.newsCategoryList self.gui["newsNextAvailable"] = True self.gui["musicListBlob"] = self.musicCategoryList self.gui["musicNextAvailable"] = True self.gui["techListBlob"] = self.techCategoryList self.gui["techNextAvailable"] = True self.gui["polListBlob"] = self.polCategoryList self.gui["polNextAvailable"] = True self.gui["gamingListBlob"] = self.gamingCategoryList self.gui["gamingNextAvailable"] = True self.gui["searchListBlob"] = "" self.gui["previousAvailable"] = False self.gui["nextAvailable"] = True self.gui["bgImage"] = self.live_category self.gui.show_page("YoutubeLiveSearch.qml", override_idle=True) def play_event(self, message): urlvideo = "http://www.youtube.com/watch?v={0}".format( message.data['vidID']) self.lastSong = message.data['vidID'] video = pafy.new(urlvideo) playstream = video.getbest(preftype="mp4", ftypestrict=True) playurl = playstream.url self.speak("Playing") self.gui["video"] = str(playurl) self.gui["status"] = str("play") self.gui["currenturl"] = str(message.data['vidID']) self.gui["currenttitle"] = str(message.data['vidTitle']) self.gui["setTitle"] = video.title self.gui["viewCount"] = video.viewcount self.gui["publishedDate"] = video.published self.gui["videoAuthor"] = video.username self.gui["nextSongBlob"] = "" videoTitleSearch = str(message.data['vidTitle']).join( str(message.data['vidTitle']).split()[:-1]) self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) thumb = "https://img.youtube.com/vi/{0}/maxresdefault.jpg".format( message.data['vidID']) recentVideoDict = { "videoID": message.data['vidID'], "videoTitle": message.data['vidTitle'], "videoImage": message.data['vidImage'], "videoChannel": message.data['vidChannel'], "videoViews": message.data['vidViews'], "videoUploadDate": message.data['vidUploadDate'], "videoDuration": message.data['vidDuration'] } self.buildHistoryModel(recentVideoDict) self.gui["recentListBlob"] = self.recent_db self.isTitle = video.title def stop(self): self.enclosure.bus.emit(Message("metadata", {"type": "stop"})) pass def process_soup(self, htmltype): videoList = [] videoList.clear() soup = BeautifulSoup(htmltype) for vid in soup.findAll(attrs={'class': 'yt-uix-tile-link'}): if "googleads" not in vid['href'] and not vid['href'].startswith( u"/user") and not vid['href'].startswith(u"/channel"): LOG.info(vid) videoID = vid['href'].split("v=")[1].split("&")[0] videoTitle = vid['title'] videoImage = "https://i.ytimg.com/vi/{0}/hqdefault.jpg".format( videoID) videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage }) if len(videoList) > 1: self.nextSongList = videoList[1] else: self.nextSongList = videoList[0] return videoList def process_soup_additional(self, htmltype): videoList = [] videoList.clear() soup = BeautifulSoup(htmltype) getVideoDetails = zip( soup.findAll(attrs={'class': 'yt-uix-tile-link'}), soup.findAll(attrs={'class': 'yt-lockup-byline'}), soup.findAll(attrs={'class': 'yt-lockup-meta-info'}), soup.findAll(attrs={'class': 'video-time'})) for vid in getVideoDetails: if "googleads" not in vid[0][ 'href'] and not vid[0]['href'].startswith( u"/user") and not vid[0]['href'].startswith( u"/channel") and not vid[0]['href'].startswith( '/news') and not vid[0]['href'].startswith( '/music' ) and not vid[0]['href'].startswith( '/technology' ) and not vid[0]['href'].startswith( '/politics' ) and not vid[0]['href'].startswith('/gaming'): videoID = vid[0]['href'].split("v=")[1].split("&")[0] videoTitle = vid[0]['title'] videoImage = "https://i.ytimg.com/vi/{0}/hqdefault.jpg".format( videoID) videoChannel = vid[1].contents[0].string videoUploadDate = vid[2].contents[0].string videoDuration = vid[3].contents[0].string if "watching" in vid[2].contents[0].string: videoViews = "Live" else: try: videoViews = vid[2].contents[1].string except: videoViews = "Playlist" videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration }) return videoList def process_additional_pages(self, category): url = "https://www.youtube.com/results?search_query={0}".format( category) response = requests.get(url, headers=self.quackagent) html = response.text soup = BeautifulSoup(html) buttons = soup.findAll( 'a', attrs={ 'class': "yt-uix-button vve-check yt-uix-sessionlink yt-uix-button-default yt-uix-button-size-default" }) try: nPage = buttons[0]['href'] except: nPage = self.process_additional_pages_fail(category) pPage = url addPgObj = [nPage, pPage] return addPgObj def process_additional_pages_fail(self, category): url = None if category == "news": url = "/results?search_query=world+news" if category == "music": url = "/results?search_query=latest+music" if category == "technology": url = "/results?search_query=latest+tech" if category == "politics": url = "/results?search_query=latest+politics" if category == "gaming": url = "/results?search_query=latest+games" return url def nextSongForAutoPlay(self): self.gui["nextSongBlob"] = self.nextSongList def refreshWatchList(self, message): print("Currently Disabled, Skipping Step") #try: #print("todo") #self.youtubesearchpagesimple(self.lastSong) #except: #self.youtubesearchpagesimple(self.lastSong) @intent_file_handler('youtube-repeat.intent') def youtube_repeat_last(self): video = pafy.new(self.lastSong) thumb = video.thumb playstream = video.streams[0] playurl = playstream.url self.gui["status"] = str("play") self.gui["video"] = str(playurl) self.gui["currenturl"] = "" self.gui["currenttitle"] = video.title self.gui["setTitle"] = video.title self.gui["viewCount"] = video.viewcount self.gui["publishedDate"] = video.published self.gui["videoAuthor"] = video.username self.gui["videoListBlob"] = "" self.gui["recentListBlob"] = "" self.gui["nextSongTitle"] = "" self.gui["nextSongImage"] = "" self.gui["nextSongID"] = "" self.gui.show_pages(["YoutubePlayer.qml", "YoutubeSearch.qml"], 0, override_idle=True) self.youtubesearchpagesimple(self.lastSong) self.isTitle = video.title def build_category_list(self, category): LOG.info("Building For Category" + category) videoList = [] yts = YoutubeSearcher() vidslist = yts.search_youtube(category, render="videos") for x in range(len(vidslist['videos'])): videoID = vidslist['videos'][x]['videoId'] videoTitle = vidslist['videos'][x]['title'] videoImage = vidslist['videos'][x]['thumbnails'][0]['url'] vidImgFix = str(videoImage).split("?")[0] videoUploadDate = vidslist['videos'][x]['published_time'] videoDuration = vidslist['videos'][x]['length'] videoViews = vidslist['videos'][x]['views'] videoChannel = vidslist['videos'][x]['channel_name'] videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": vidImgFix, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration }) return videoList def build_category_list_from_url(self, category): videoList = [] yts = YoutubeSearcher() vidslist = yts.page_search(page_type=category) for x in range(len(vidslist['page_videos'])): videoID = vidslist['page_videos'][x]['videoId'] videoTitle = vidslist['page_videos'][x]['title'] videoImage = vidslist['page_videos'][x]['thumbnails'][0]['url'] vidImgFix = str(videoImage).split("?")[0] videoUploadDate = vidslist['page_videos'][x]['published_time'] videoDuration = vidslist['page_videos'][x]['length'] videoViews = vidslist['page_videos'][x]['views'] videoChannel = vidslist['page_videos'][x]['channel_name'] videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": vidImgFix, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration }) return videoList def clear_db(self): LOG.info("In DB Clear") self.recent_db.clear() self.recent_db.store() self.gui["recentListBlob"] = "" def buildHistoryModel(self, dictItem): LOG.info("In Build History Model") if 'recentList' in self.recent_db.keys(): myCheck = self.checkIfHistoryItem(dictItem) if myCheck == True: LOG.info("In true") LOG.info(dictItem) self.moveHistoryEntry(dictItem) elif myCheck == False: LOG.info("In false") LOG.info(dictItem) self.addHistoryEntry(dictItem) else: recentListItem = [] recentListItem.insert(0, dictItem) self.recent_db['recentList'] = recentListItem LOG.info("In Build History Recent Not Found Creating") self.recent_db.store() self.build_recent_watch_list(20) self.gui["recentHomeListBlob"] = self.recentWatchListObj def checkIfHistoryItem(self, dictItem): hasHistoryItem = False for dict_ in [ x for x in self.recent_db['recentList'] if x["videoID"] == dictItem["videoID"] ]: hasHistoryItem = True return hasHistoryItem def moveHistoryEntry(self, dictItem): res = [ i for i in self.recent_db['recentList'] if not (i['videoID'] == dictItem["videoID"]) ] self.recent_db['recentList'] = res self.recent_db['recentList'].insert(0, dictItem) self.recent_db.store() self.build_recent_watch_list(20) self.gui["recentHomeListBlob"] = self.recentWatchListObj def addHistoryEntry(self, dictItem): self.recent_db['recentList'].insert(0, dictItem) self.recent_db.store() self.build_recent_watch_list(20) self.gui["recentHomeListBlob"] = self.recentWatchListObj def build_recent_watch_list(self, count): if 'recentList' in self.recent_db.keys(): recentWatchListRaw = self.recent_db['recentList'] recentWatchListModded = recentWatchListRaw[0:count] self.recentWatchListObj['recentList'] = recentWatchListModded else: emptyList = [] self.recentWatchListObj['recentList'] = emptyList def build_upload_date(self, update): now = datetime.datetime.now() + datetime.timedelta(seconds=60 * 3.4) date = dateutil.parser.parse(update) naive = date.replace(tzinfo=None) dtstring = timeago.format(naive, now) return dtstring def add_view_string(self, viewcount): val = viewcount count = re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%d" % val) views = count + " views" LOG.info(views) return views def process_soup_watchlist(self, html): videoList = [] videoList.clear() soup = BeautifulSoup(html) currentVideoSection = soup.find('div', attrs={'class': 'watch-sidebar'}) getVideoDetails = zip( currentVideoSection.findAll(attrs={'class': 'yt-uix-sessionlink'}), currentVideoSection.findAll(attrs={'class': 'attribution'}), currentVideoSection.findAll( attrs={'class': 'yt-uix-simple-thumb-wrap'}), currentVideoSection.findAll(attrs={'class': 'video-time'}), currentVideoSection.findAll(attrs={'class': 'view-count'})) for vid in getVideoDetails: if "googleads" not in vid[0][ 'href'] and not vid[0]['href'].startswith( u"/user") and not vid[0]['href'].startswith( u"/channel") and not vid[0]['href'].startswith( '/news') and not vid[0]['href'].startswith( '/music' ) and not vid[0]['href'].startswith( '/technology' ) and not vid[0]['href'].startswith( '/politics' ) and not vid[0]['href'].startswith( '/gaming') and "title" in vid[0].attrs: videoID = vid[0]['href'].split("v=")[1].split("&")[0] videoTitle = vid[0]['title'] videoImage = "https://i.ytimg.com/vi/{0}/hqdefault.jpg".format( videoID) videoChannel = vid[1].contents[0].string videoUploadDate = " " videoDuration = vid[3].contents[0].string videoViews = vid[4].text videoList.append({ "videoID": videoID, "videoTitle": videoTitle, "videoImage": videoImage, "videoChannel": videoChannel, "videoViews": videoViews, "videoUploadDate": videoUploadDate, "videoDuration": videoDuration }) return videoList