#!/usr/bin/env python # -*- coding: UTF-8 -*- # # Imports # from __future__ import absolute_import from future import standard_library standard_library.install_aliases() from builtins import str from builtins import object import os import requests import sys import urllib.request, urllib.parse, urllib.error import re import html.parser import xbmcgui import xbmcplugin from .hak5_const import ADDON, LANGUAGE, IMAGES_PATH, HEADERS, convertToUnicodeString, log, getSoup # # Main class # class Main(object): # # Init # def __init__(self): # Get the command line arguments # Get the plugin url in plugin:// notation self.plugin_url = sys.argv[0] # Get the plugin handle as an integer number self.plugin_handle = int(sys.argv[1]) log("ARGV", repr(sys.argv)) # Parse parameters self.video_list_page_url = urllib.parse.parse_qs(urllib.parse.urlparse(sys.argv[2]).query)['url'][0] self.next_page_possible = urllib.parse.parse_qs(urllib.parse.urlparse(sys.argv[2]).query)['next_page_possible'][0] self.video_list_page_url = str(self.video_list_page_url).replace('https', 'http') log("self.video_list_page_url", self.video_list_page_url) if self.next_page_possible == 'True': # Determine current item number, next item number, next_url pos_of_page = self.video_list_page_url.rfind('page/') if pos_of_page >= 0: page_number_str = str( self.video_list_page_url[pos_of_page + len('page/'):pos_of_page + len('page/') + len('000')]) page_number = int(page_number_str) page_number_next = page_number + 1 if page_number_next >= 100: page_number_next_str = str(page_number_next) elif page_number_next >= 10: page_number_next_str = '0' + str(page_number_next) else: page_number_next_str = '00' + str(page_number_next) self.next_url = str(self.video_list_page_url).replace(page_number_str, page_number_next_str) log("self.next_url", self.next_url) # # Get the videos... # self.getVideos() # # Get videos... # def getVideos(self): # # Init # previous_video_page_url = '' after_tab_episodes = False # Create a list for our items. listing = [] # # Get HTML page # response = requests.get(self.video_list_page_url, headers=HEADERS) html_source = response.text html_source = convertToUnicodeString(html_source) # Parse response soup = getSoup(html_source) # log("html_source", html_source) #
#
# # # #
#
#

Hak5 2216 – Pseudocode for Life 2 – Hack Across the Planet #

# #
# #
#
episodes = soup.findAll('div', attrs={'id': re.compile("^" + 'post')}) log("len(episodes", len(episodes)) for episode in episodes: # log("episode", episode) video_page_url = episode.a['href'] log("video_page_url", video_page_url) try: thumbnail_url = episode.img['src'] except: thumbnail_url = '' log("thumbnail_url", thumbnail_url) pos_of_title_start = str(episode).find('title="') + len('title="') pos_of_title_end = str(episode).find('"', pos_of_title_start) title = str(episode)[pos_of_title_start:pos_of_title_end] title = title.replace('-', ' ') title = title.replace('/', ' ') title = title.replace(' i ', ' I ') title = title.replace(' ii ', ' II ') title = title.replace(' iii ', ' III ') title = title.replace(' iv ', ' IV ') title = title.replace(' v ', ' V ') title = title.replace(' vi ', ' VI ') title = title.replace(' vii ', ' VII ') title = title.replace(' viii ', ' VIII ') title = title.replace(' ix ', ' IX ') title = title.replace(' x ', ' X ') title = title.replace(' xi ', ' XI ') title = title.replace(' xii ', ' XII ') title = title.replace(' xiii ', ' XIII ') title = title.replace(' xiv ', ' XIV ') title = title.replace(' xv ', ' XV ') title = title.replace(' xvi ', ' XVI ') title = title.replace(' xvii ', ' XVII ') title = title.replace(' xviii ', ' XVIII ') title = title.replace(' xix ', ' XIX ') title = title.replace(' xx ', ' XXX ') title = title.replace(' xxi ', ' XXI ') title = title.replace(' xxii ', ' XXII ') title = title.replace(' xxiii ', ' XXIII ') title = title.replace(' xxiv ', ' XXIV ') title = title.replace(' xxv ', ' XXV ') title = title.replace(' xxvi ', ' XXVI ') title = title.replace(' xxvii ', ' XXVII ') title = title.replace(' xxviii ', ' XXVIII ') title = title.replace(' xxix ', ' XXIX ') title = title.replace(' xxx ', ' XXX ') title = title.replace(' ', ' ') log("title", title) # lets find the blog date month and year search_for_string = 'https://www.hak5.org/wp-content/uploads/' blog_date = episode.findAll('img', attrs={'src': re.compile('^' + search_for_string)}) blog_date = str(blog_date) blog_date_year_start_pos = blog_date.find(search_for_string) + len(search_for_string) blog_date_year_end_pos = blog_date.find('/', blog_date_year_start_pos) blog_date_year = blog_date[blog_date_year_start_pos: blog_date_year_end_pos] log("blog_data_year", blog_date_year) blog_date_month_start_pos = blog_date_year_end_pos + 1 blog_date_month_end_pos = blog_date_month_start_pos + 2 blog_date_month = blog_date[blog_date_month_start_pos:blog_date_month_end_pos] log("blog_date_month", blog_date_month) # lets find the blog date day blog_date = episode.findAll('span', attrs={'class': re.compile("^" + 'item-date')}) if len(blog_date) == 0: blog_date_day = '00' else: blog_date = str(blog_date[0].text) blog_date_day_start_pos = blog_date.find(',') - 2 blog_date_day_end_pos = blog_date_day_start_pos + 2 blog_date_day = blog_date[blog_date_day_start_pos:blog_date_day_end_pos] log("blog_date_day", blog_date_day) video_date = blog_date_year + '-' + blog_date_month + '-' + blog_date_day + ' 00:00:01' log("video_date", video_date) # Unescaping the plot try: plot = html.parser.HTMLParser().unescape(episode.p.text) except: plot = title log("plot", plot) add_sort_methods() context_menu_items = [] # Add refresh option to context menu context_menu_items.append((LANGUAGE(30104), 'Container.Refresh')) # Add episode info to context menu context_menu_items.append((LANGUAGE(30105), 'XBMC.Action(Info)')) list_item = xbmcgui.ListItem(label=title, thumbnailImage=thumbnail_url) list_item.setInfo("video", {"title": title, "studio": ADDON, "dateadded": video_date, "year": blog_date_year, "plot": plot}) list_item.setInfo("mediatype", "video") list_item.setArt({'thumb': thumbnail_url, 'icon': thumbnail_url, 'fanart': os.path.join(IMAGES_PATH, 'fanart-blur.jpg')}) list_item.setProperty('IsPlayable', 'true') parameters = {"action": "play", "video_page_url": video_page_url} url = self.plugin_url + '?' + urllib.parse.urlencode(parameters) is_folder = False # Adding context menu items to context menu list_item.addContextMenuItems(context_menu_items, replaceItems=False) # Add our item to the listing as a 3-element tuple. listing.append((url, list_item, is_folder)) # Next page entry if self.next_page_possible == 'True': list_item = xbmcgui.ListItem(LANGUAGE(30200), thumbnailImage=os.path.join(IMAGES_PATH, 'next-page.png')) list_item.setArt({'fanart': os.path.join(IMAGES_PATH, 'fanart-blur.jpg')}) list_item.setProperty('IsPlayable', 'false') parameters = {"action": "list-episodes", "url": str(self.next_url), "next_page_possible": self.next_page_possible} url = self.plugin_url + '?' + urllib.parse.urlencode(parameters) is_folder = True # Adding context menu items to context menu list_item.addContextMenuItems(context_menu_items, replaceItems=False) # Add our item to the listing as a 3-element tuple. listing.append((url, list_item, is_folder)) # Add our listing to Kodi. # Large lists and/or slower systems benefit from adding all items at once via addDirectoryItems # instead of adding one by ove via addDirectoryItem. xbmcplugin.addDirectoryItems(self.plugin_handle, listing, len(listing)) # Disable sorting xbmcplugin.addSortMethod(handle=self.plugin_handle, sortMethod=xbmcplugin.SORT_METHOD_NONE) # Finish creating a virtual folder. xbmcplugin.endOfDirectory(self.plugin_handle) def add_sort_methods(): sort_methods = [xbmcplugin.SORT_METHOD_UNSORTED,xbmcplugin.SORT_METHOD_LABEL,xbmcplugin.SORT_METHOD_DATE,xbmcplugin.SORT_METHOD_DURATION,xbmcplugin.SORT_METHOD_EPISODE] for method in sort_methods: xbmcplugin.addSortMethod(int(sys.argv[1]), sortMethod=method)