Exemplo n.º 1
0
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
Exemplo n.º 2
0
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"] = ""
Exemplo n.º 3
0
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