def hlsStrip(videoUrl): """ Extracts the stream that supports the highest bandwidth and is not using the avc1.77.30 codec. """ common.log("Stripping file: " + videoUrl) ufile = urllib.urlopen(videoUrl) lines = ufile.readlines() hlsurl = "" bandwidth = 0 foundhigherquality = False for line in lines: if foundhigherquality: # The stream url is on the line proceeding the header foundhigherquality = False hlsurl = line if "EXT-X-STREAM-INF" in line: # The header if not "avc1.77.30" in line: match = re.match(r'.*BANDWIDTH=(\d+).+', line) if match: if bandwidth < int(match.group(1)): foundhigherquality = True bandwidth = int(match.group(1)) continue if bandwidth == 0: return None ufile.close() hlsurl = hlsurl.rstrip() common.log("Returned stream url : " + hlsurl) return hlsurl
def viewProgramType(url, page, type): r = requests.get("http://tv.aftonbladet.se/" + url + "/" + type + "?page=" + page + "&pageSize=30") common.log("http://tv.aftonbladet.se/" + url + "/" + type + "?page=" + page + "&pageSize=30" + " -> ") common.log(len(r.text)) articles = common.parseDOM(r.text, "article") for article in articles: art = {} link = art["link"] = common.parseDOM(article, "a", ret="href")[0] img = common.parseDOM(article, "img", ret="srcset")[0] listimg = img.split(",") lastimg = art["img"] = listimg[len(listimg) - 1].replace( " http", "http") title = art["title"] = common.parseDOM( article, "div", attrs={"class": "sidescroll-item-header"})[0] desc = art["desc"] = common.parseDOM( article, "div", attrs={"class": "sidescroll-item-description"})[0] #art["epi"] = common.parseDOM(article, "div", attrs = {"class":"abLabelThin sidescroll-item-episode"})[0] art["date"] = common.parseDOM(article, "div", attrs={"class": "abLabelThin"})[0] addDirectoryItem(title, { "mode": MODE_VIDEO, "url": link }, lastimg, False, False, desc) if len(articles) == 30: addDirectoryItem(localize(30101), { "mode": MODE_PROGRAM, "url": url, "prg": type, "page": int(page) + 1 }, None, True, False, None)
def getProgramsByLetter(letter): """ Returns a list of all program starting with the supplied letter. """ letter = urllib.unquote(letter) url = BASE_URL+API_URL+"all_titles" r = requests.get(url) if r.status_code != 200: common.log("Did not get any response for: "+url) return None letter = letter.decode("utf-8") pattern = "[%s]" % letter.upper() titles = r.json() items = [] programs = [] for title in titles: if re.search(pattern, title["programTitle"][0].upper()): item = {} item["url"] = "/" + title["contentUrl"] item["title"] = common.replaceHTMLCodes(title["programTitle"]) item["thumbnail"] = "" items.append(item) return items
def mp4Handler(jsonObj): """ Returns a mp4 stream URL. If there are several mp4 streams in the JSON object: pick the one with the highest bandwidth. Some programs are available with multiple mp4 streams for different bitrates. This function ensures that the one with the highest bitrate is chosen. Can possibly be extended to support some kind of quality setting in the plugin. """ videos = [] # Find all mp4 videos for video in jsonObj["video"]["videoReferences"]: if video["url"].endswith(".mp4"): videos.append(video) if len(videos) == 1: return videos[0]["url"] bitrate = 0 url = "" # Find the video with the highest bitrate for video in videos: if video["bitrate"] > bitrate: bitrate = video["bitrate"] url = video["url"] common.log("Info: bitrate=" + str(bitrate) + " url=" + url) return url
def getVideoJSON(video_url): url = BASE_URL + API_URL + "title_page;title=" + video_url r = requests.get(url) if r.status_code != 200: common.log("Failed to get JSON for "+url) return None return r.json()
def deleteFile(subject, folder): common.log(subject) global m file = findInFolder(subject, folder) if file: delay = 1 res = False while not res and delay < 10: try: res = m.destroy(file[0]) except errors.RequestError as e: if e[0] == -3: common.log( "[%s] EAGAIN: Retrying with exponential backoff: %s " % (repr(e[0]), repr(delay))) time.sleep(delay) delay += 1 else: common.log("errors.RequestError: " + repr(e)) sys.exit(1) common.log("Done: " + repr(res)) return True else: common.log("Failure") return False
def viewProgram(url, page): if ARG_PRG: viewProgramType(url, page, ARG_PRG) else: r = requests.get("http://tv.aftonbladet.se/" + url) headers = common.parseDOM(r.text, "div", attrs={"class": "header"}) for header in headers: common.log(header) if header == "Senaste avsnitten": addDirectoryItem(localize(30701), { "mode": MODE_PROGRAM, "prg": MODE_PRG_LAST_EP, "url": url }) if header == "Senaste klippen": addDirectoryItem(localize(30702), { "mode": MODE_PROGRAM, "prg": MODE_PRG_LAST_CUT, "url": url }) if header == "Populära klipp": addDirectoryItem(localize(30703), { "mode": MODE_PROGRAM, "prg": MODE_PRG_POP_CUT, "url": url })
def getEpisodes(title): """ Returns the episodes for a program URL. """ url = BASE_URL+API_URL+"video_title_page;title="+title r = requests.get(url) if r.status_code != 200: common.log("Could not get JSON for "+url) return None programs = [] for item in r.json()["relatedVideos"]["episodes"]: program = {} program["title"] = item["title"] try: program["title"] = program["title"] + "[COLOR green] (S%sE%s)[/COLOR]" % (str(item["season"]), str(item["episodeNumber"])) except KeyError as e: # Supress pass program["url"] = "video/" + str(item["id"]) program["thumbnail"] = helper.prepareThumb(item.get("thumbnail", ""), BASE_URL) info = {} info["plot"] = item.get("description", "") info["fanart"] = helper.prepareFanart(item.get("poster", ""), BASE_URL) program["info"] = info programs.append(program) return programs
def getFile(subject, filename, folder): common.log(subject) global m file = findInFolder(subject, folder) if file: dest, dest_filename = os.path.split(filename) delay = 1 res = False while not res and delay < 10: try: #m.download(file, dest_path=dest, dest_filename=dest_filename) megaDownload(file, dest_path=dest, dest_filename=dest_filename) res = True except errors.RequestError as e: if e[0] == -3: common.log("[%s] EAGAIN: Retrying with exponential backoff: %s " %( repr(e[0]), repr(delay))) time.sleep(delay) delay += 1 else: common.log("errors.RequestError: " + repr(e)) sys.exit(1) common.log("Done: " + repr(res)) return True else: common.log("Failure") return False
def deleteFile(subject, folder): common.log(subject) global m file = findInFolder(subject, folder) if file: delay = 1 res = False while not res and delay < 10: try: res = m.destroy(file[0]) except errors.RequestError as e: if e[0] == -3: common.log("[%s] EAGAIN: Retrying with exponential backoff: %s " %( repr(e[0]), repr(delay))) time.sleep(delay) delay += 1 else: common.log("errors.RequestError: " + repr(e)) sys.exit(1) common.log("Done: " + repr(res)) return True else: common.log("Failure") return False
def getChannels(): """ Returns the live channels from the page "Kanaler". """ url = BASE_URL+API_URL+"channel_page" r = requests.get(url) if r.status_code != 200: common.log("Could not get response for: "+url) return None contents = r.json() items = [] for channel in contents["channels"]: item = {} program_title = channel["schedule"][0]["title"] item["title"] = channel["name"]+" - "+program_title item["thumbnail"] = \ "http://svtplay.se//public/images/channels/posters/%s.png" % channel["title"] item["info"] = {} try: item["info"]["plot"] = channel["schedule"][0]["titlePage"]["description"] item["info"]["fanart"] = channel["schedule"][0]["titlePage"]["thumbnailLarge"] item["info"]["title"] = channel["schedule"][0]["titlePage"]["title"] except KeyError as e: # Some items are missing titlePage, skip them pass for videoRef in channel["videoReferences"]: if videoRef["playerType"] == "ios": item["url"] = videoRef["url"] items.append(item) return items
def mp4Handler(jsonObj): """ Returns a mp4 stream URL. If there are several mp4 streams in the JSON object: pick the one with the highest bandwidth. Some programs are available with multiple mp4 streams for different bitrates. This function ensures that the one with the highest bitrate is chosen. Can possibly be extended to support some kind of quality setting in the plugin. """ videos = [] # Find all mp4 videos for video in jsonObj["video"]["videoReferences"]: if video["url"].endswith(".mp4"): videos.append(video) if len(videos) == 1: return videos[0]["url"] bitrate = 0 url = "" # Find the video with the highest bitrate for video in videos: if video["bitrate"] > bitrate: bitrate = video["bitrate"] url = video["url"] common.log("Info: bitrate="+str(bitrate)+" url="+url) return url
def getFile(subject, filename, folder): common.log(subject) global m file = findInFolder(subject, folder) if file: dest, dest_filename = os.path.split(filename) delay = 1 res = False while not res and delay < 10: try: #m.download(file, dest_path=dest, dest_filename=dest_filename) megaDownload(file, dest_path=dest, dest_filename=dest_filename) res = True except errors.RequestError as e: if e[0] == -3: common.log( "[%s] EAGAIN: Retrying with exponential backoff: %s " % (repr(e[0]), repr(delay))) time.sleep(delay) delay += 1 else: common.log("errors.RequestError: " + repr(e)) sys.exit(1) common.log("Done: " + repr(res)) return True else: common.log("Failure") return False
def getLatestNews(): """ Returns a list of latest news programs. """ url = BASE_URL+API_URL+"cluster_latest;cluster=nyheter" r = requests.get(url) if r.status_code != 200: common.log("Could not get JSON for url: "+url) return None programs = [] for item in r.json(): live_str = "" thumbnail = item.get("poster", "") if not thumbnail: thumbnail = item.get("thumbnail", "") if item["broadcastedNow"]: live_str = " " + "[COLOR red](Live)[/COLOR]" program = { "title" : common.replaceHTMLCodes(item["programTitle"] + " " + item["title"] + live_str), "thumbnail" : helper.prepareThumb(thumbnail, baseUrl=BASE_URL), "url" : "video/" + str(item["versions"][0]["articleId"]) } programs.append(program) return programs
def remove(line): common.log("") folder = setFolder(conf["folder"], common.ask("DIRHASH " + line[1])) if deleteFile(line[1], folder): common.sprint('REMOVE-SUCCESS ' + line[1] + '') else: common.sprint('REMOVE-FAILURE ' + line[1] + ' This file could not be removed') common.log("Done")
def postFile(subject, filename, folder, git_top_level): common.log("%s to %s - %s" % ( filename, repr(folder), subject)) def func(progress, done): common.log("func: %s - %s" % (repr(progress), repr(done))) if len(done): print("Done uploading") else: print("At %s%%" % progress) width, height, pixels, meta, text = png.Reader(filename=pwd + "/logo_small.png").read() upper_limit = 40234050 if os.path.getsize(filename) > upper_limit: print("%s size: %s more than %s. Skipping" % ( filename, os.path.getsize(filename), upper_limit)) sys.exit(1) tags = [] if conf["encrypted"]: tfile = pwd + "/temp/encoded-" + subject f = open(tfile, 'wb') text = readFile(filename, "rb") text = base64.b64encode(text) w = png.Writer(width, height, text={"data": text}) w.write(f, pixels) f.close() else: tfile = filename if git_top_level: common.log("git top level directory: %s" % git_top_level) dirpath = os.path.relpath(os.path.dirname(tfile), git_top_level) if dirpath.find(".git") == -1: tags = dirpath.split(os.sep) common.log("Tags added to photo " + repr(tags)) common.log("Uploading: " + tfile) res = flickr.upload(filename=tfile, is_public=0, title=subject, description=os.path.basename(tfile), tags = '"' + '" "'.join(tags) + '"', callback=func) if len(res): if isinstance(folder, int) or isinstance(folder, long): flickr.photosets_addPhoto(photoset_id=folder, photo_id=res[0].text) else: flickr.photosets_create(title=folder, primary_photo_id=res[0].text) if conf["encrypted"]: os.unlink(pwd + "/temp/encoded-" + subject) if len(res): common.log("Done: " + repr(res)) else: print("Failed to store: " + repr(res)) sys.exit(1)
def checkpresent(line): common.log("") folder = setFolder(conf["folder"], common.ask("DIRHASH " + line[1])) if not len(folder): common.sprint('CHECKPRESENT-UNKNOWN ' + line[1] + ' this remote is not currently available') return None if checkFile(line[1], folder): common.sprint('CHECKPRESENT-SUCCESS ' + line[1] + '') else: common.sprint('CHECKPRESENT-FAILURE ' + line[1] + '') common.log("Done")
def getSubtitleUrl(json_obj): """ Returns a subtitleURL from a SVT JSON object. """ url = None for subtitle in json_obj["video"]["subtitleReferences"]: if subtitle["url"].endswith(".wsrt"): url = subtitle["url"] else: if len(subtitle["url"]) > 0: common.log("Skipping unknown subtitle: " + subtitle["url"]) return url
def getFile(subject, filename, folder): common.log(subject) file = findFile(subject, folder) if file: url = flickr.photos_getSizes(photo_id=file) url = url.find('sizes').findall('size') url = url[len(url) - 1] common.log( "Using: " + repr(url.attrib["label"]) + " - " + repr(url.attrib["source"]), 3) res = common.fetchPage({"link": url.attrib["source"]}) if "encrypted" in conf and conf["encrypted"]: r = png.Reader(bytes=res["content"]) width, height, pixels, meta, text = r.read() text = base64.b64decode(text["data"]) saveFile(filename, text, "wb") else: saveFile(filename, res["content"], "wb") common.log("Done") else: common.log("Failure")
def viewRequest(url, page, rurl): common.log(rurl) r = requests.get(rurl) common.log(len(r.text)) articles = common.parseDOM(r.text, "article") common.log(len(articles)) for article in articles: art = {} link = art["link"] = common.parseDOM(article, "a", ret="href")[0] img = common.parseDOM(article, "img", ret="srcset")[0] listimg = img.split(",") lastimg = art["img"] = listimg[len(listimg) - 1].replace( " http", "http") title = art["title"] = common.parseDOM(article, "a", attrs={"class": "title"})[0] art["date"] = common.parseDOM(article, "div", attrs={"class": "abLabelThin"})[0] addDirectoryItem(title, { "mode": MODE_VIDEO, "url": link }, lastimg, False, False, None) common.log(ARG_MODE) if len(articles) == 30: addDirectoryItem(localize(30101), { "mode": ARG_MODE, "url": url, "page": int(page) + 1 }, None, True, False, None)
def findInFolder(subject, folder): common.log("%s - %s" % (repr(subject), repr(folder)), 3) result = [] page_token = None errors = 0 while True: try: param = {'q': "title = '%s'" % subject, "fields": "items"} #param = {'q': "title = '%s'" % subject} #param = {"fields": "items"} if folder: param["q"] += " and '%s' in parents" % folder["id"] if page_token: param['pageToken'] = page_token common.log("Calling with: " + repr(param), 1) files = service.files().list(**param).execute() result.extend(files['items']) page_token = files.get('nextPageToken') if not page_token: common.log("Breaking with: " + repr(result) + " - " + repr(files), 1) break except errors.HttpError, error: common.log('An error occurred(%s): %s' % (errors, error)) errors += 1 if errors < 4: time.sleep(errors) else: print("Fatal error: " + repr(error)) sys.exit(1)
def getFile(subject, filename, folder): common.log(subject) file = findFile(subject, folder) if file: url = flickr.photos_getSizes(photo_id=file) url = url.find('sizes').findall('size') url = url[len(url) -1] common.log("Using: " + repr(url.attrib["label"]) + " - " + repr(url.attrib["source"]), 3) res = common.fetchPage({"link": url.attrib["source"]}) if "encrypted" in conf and conf["encrypted"]: r=png.Reader(bytes=res["content"]) width, height, pixels, meta, text = r.read() text = base64.b64decode(text["data"]) saveFile(filename, text, "wb") else: saveFile(filename, res["content"], "wb") common.log("Done") else: common.log("Failure")
def initremote(line): common.log("") uname = os.getenv("USERNAME") or "" pword = os.getenv("PASSWORD") or "" encryption = common.getConfig("encryption") myfolder = common.getConfig("folder") if len(uname) and len(pword) and len(myfolder): common.sprint('SETCREDS mycreds ' + uname + ' ' + pword) common.sprint('INITREMOTE-SUCCESS') else: common.sprint('INITREMOTE-FAILURE You need to set USERNAME and PASSWORD environment variables and folder and encryption parameters when running initremote.') common.log("Done")
def transfer(line): common.log("") folder = setFolder(conf["folder"], common.ask("DIRHASH " + line[2])) if line[1] == "STORE": if postFile(line[2], " ".join(line[3:]), folder): common.sprint('TRANSFER-SUCCESS STORE ' + line[2] + '') else: common.sprint('TRANSFER-FAILURE STORE ' + line[2] + ' File could not be stored') if line[1] == "RETRIEVE": if getFile(line[2], " ".join(line[3:]), folder): common.sprint('TRANSFER-SUCCESS RETRIEVE ' + line[2] + '') else: common.sprint('TRANSFER-FAILURE RETRIEVE ' + line[2] + ' File could not be retrieved') common.log("Done")
def initremote(line): common.log("") uname = os.getenv("USERNAME") or "" pword = os.getenv("PASSWORD") or "" encryption = common.getConfig("encryption") myfolder = common.getConfig("folder") if len(uname) and len(pword) and len(myfolder): common.sprint('SETCREDS mycreds ' + uname + ' ' + pword) common.sprint('INITREMOTE-SUCCESS') else: common.sprint( 'INITREMOTE-FAILURE You need to set USERNAME and PASSWORD environment variables and folder and encryption parameters when running initremote.' ) common.log("Done")
def getFile(subject, filename, folder): common.log(subject) global m tmp_file = findInFolder(subject, folder) if tmp_file: base = conf["url"][conf["url"].find("/", 8):] tmp_file = (base + tmp_file).replace("//", "/") common.log("tmp_file: " + repr(tmp_file)) response = client.get(tmp_file, encAuth) if response.status == 200: cont = response.read() common.log("Got data: " + repr(len(cont))) saveFile(filename, cont, "wb") common.log("Done") return True common.log("Failure")
def getAtoO(): """ Returns a list of all items, sorted A-Z. """ r = requests.get(BASE_URL+API_URL+"all_titles") if r.status_code != 200: common.log("Could not fetch JSON!") return None items = [] for program in r.json(): item = {} item["title"] = common.replaceHTMLCodes(program["programTitle"]) item["thumbnail"] = "" item["url"] = program["contentUrl"] items.append(item) return sorted(items, key=lambda item: item["title"])
def getCategories(): """ Returns a list of all categories. """ r = requests.get(BASE_URL+API_URL+"active_clusters") if r.status_code != 200: common.log("Could not fetch JSON!") return None categories = [] for cluster in r.json(): category = {} category["title"] = cluster["name"] category["url"] = cluster["contentUrl"] category["genre"] = cluster["slug"] categories.append(category) return categories
def prepare(line): common.log("") creds = common.getCreds() myfolder = common.getConfig("folder") encryption = common.getConfig("encryption") if len(creds) > 1 and len(myfolder) and ( len(creds[1]) and len(creds[2])): conf["uname"] = creds[1] conf["pword"] = creds[2] conf["folder"] = myfolder common.updateWanted(False, False) common.sprint('DEBUG ' + plugin) if login(conf["uname"], conf["pword"]): common.sprint('PREPARE-SUCCESS') else: common.sprint('PREPARE-FAILURE Login failure.') else: common.sprint('PREPARE-FAILURE You need to set USERNAME and PASSWORD environment variables and folder and encryption parameters for the remote.') common.log("")
def getSearchResults(search_term): """ Returns a list of both clips and programs for the supplied search URL. """ url = BASE_URL+API_URL+"search_page;q="+search_term r = requests.get(url) if r.status_code != 200: common.log("Did not get any response for: "+url) return None items = [] contents = r.json() for program in contents["titles"]: item = {} item["title"] = common.replaceHTMLCodes(program["title"]) item["url"] = program["contentUrl"] item["thumbnail"] = helper.prepareThumb(program.get("imageMedium", ""), baseUrl=BASE_URL) item["info"] = {} item["info"]["plot"] = program.get("description", "") items.append({"item": item, "type" : "program"}) for video in contents["episodes"]: item = {} item["title"] = common.replaceHTMLCodes(video["title"]) item["url"] = video["contentUrl"] item["thumbnail"] = helper.prepareThumb(video.get("imageMedium", ""), baseUrl=BASE_URL) item["info"] = {} item["info"]["plot"] = video.get("description", "") items.append({"item": item, "type": "video"}) for clip in contents["clips"]: item = {} item["title"] = common.replaceHTMLCodes(clip["title"]) item["url"] = clip["contentUrl"] item["thumbnail"] = helper.prepareThumb(clip.get("imageMedium", ""), baseUrl=BASE_URL) item["info"] = {} item["info"]["plot"] = clip.get("description", "") items.append({"item": item, "type": "video"}) return items
def getClips(title): """ Returns the clips for a program URL. """ url = BASE_URL+API_URL+"video_title_page;title="+title r = requests.get(url) if r.status_code != 200: common.log("Could not get JSON for "+url) return None clips = [] for item in r.json()["relatedVideos"]["clipsResult"]["entries"]: clip = {} clip["title"] = item["title"] clip["url"] = "klipp/" + str(item["id"]) clip["thumbnail"] = helper.prepareThumb(item.get("thumbnailMedium", ""), BASE_URL) info = {} info["plot"] = item.get("description", "") clip["info"] = info clips.append(clip) return clips
def prepare(line): common.log("") creds = common.getCreds() myfolder = common.getConfig("folder") encryption = common.getConfig("encryption") if len(creds) > 1 and len(myfolder) and (len(creds[1]) and len(creds[2])): conf["uname"] = creds[1] conf["pword"] = creds[2] conf["folder"] = myfolder common.updateWanted(False, False) common.sprint('DEBUG ' + plugin) if login(conf["uname"], conf["pword"]): common.sprint('PREPARE-SUCCESS') else: common.sprint('PREPARE-FAILURE Login failure.') else: common.sprint( 'PREPARE-FAILURE You need to set USERNAME and PASSWORD environment variables and folder and encryption parameters for the remote.' ) common.log("")
def deleteFile(subject, folder): common.log(subject) global m tmp_file = findInFolder(subject, folder) if tmp_file: base = conf["url"][conf["url"].find("/", 8):] response = client.delete(base + tmp_file, encAuth) common.log("response: " + repr(response)) if response.status == 204: common.log("Done: " + repr(response.read())) return True common.log("Failure")
def postFile(subject, filename, folder): common.log("%s to %s - %s" % ( filename, folder[0], subject)) tmp_file = findInFolder(subject, folder) if tmp_file: common.log("File already exists: " + repr(tmp_file)) return True base = conf["url"][conf["url"].find("/", 8):] tpath = ("%s%s%s" % (base, folder, subject)).replace("//", "/") common.log("tpath: " + repr(tpath)) response = False with open(filename, "rb") as fh: response = client.put(tpath, fh, "application/octet-stream", None, encAuth) if response: cont = response.read() if response.status == 201: common.log("Done: " + repr(cont)) return True common.log("Failure") sys.exit(1)
def getProgramsForGenre(genre): """ Returns a list of all programs for a genre. """ url = BASE_URL+API_URL+"cluster_titles_and_episodes/?cluster="+genre r = requests.get(url) if r.status_code != 200: common.log("Could not get JSON for url: "+url) return None programs = [] for item in r.json(): url = item["contentUrl"] title = item["programTitle"] plot = item.get("description", "") thumbnail = helper.prepareThumb(item.get("thumbnail", ""), BASE_URL) if not thumbnail: thumbnail = helper.prepareThumb(item.get("poster", ""), BASE_URL) info = {"plot": plot, "thumbnail": thumbnail, "fanart": thumbnail} program = { "title": title, "url": url, "thumbnail": thumbnail, "info": info} programs.append(program) return programs
def readFile(fname, flags="r"): common.log(repr(fname) + " - " + repr(flags)) if not os.path.exists(fname): common.log("File doesn't exist") return False d = "" try: t = open(fname, flags) d = t.read() t.close() except Exception as e: common.log("Exception: " + repr(e), -1) common.log("Done") return d
def findInFolder(subject, folder="/"): common.log("%s(%s) - %s(%s)" % (repr(subject), type(subject), repr(folder), type(folder)), 0) if folder[0] != "/": folder = "/" + folder host = conf["url"][:conf["url"].find("/", 8)] base = conf["url"][conf["url"].find("/", 8):] tpath = (base + folder).replace("//", "/") tpath = tpath[:len(tpath)-1] bla = client.propfind(tpath, depth=1, extra_hdrs=encAuth) content = bla.read() content = content.replace("<D:", "<d:").replace("</D:", "</d:") # Box.com fix common.log("propfind: " + tpath + " - " + repr(content)) for tmp_file in common.parseDOM(content, "d:href"): tmp_file = urllib.unquote_plus(tmp_file) tmp_file = tmp_file.replace(host, "") tmp_path = (base + folder + subject).replace("//", "/") common.log("folder: " + tmp_file + " - " + tmp_path, 3) if tmp_file == tmp_path or tmp_file == tmp_path + "/": tmp_file = folder + subject common.log("Done: " + repr(tmp_file)) return tmp_file common.log("Failure")
def getItems(section_name, page): if not page: page = 1 url = BASE_URL+API_URL+section_name+"_page?page="+str(page) r = requests.get(url) if r.status_code != 200: common.log("Did not get any response for: "+url) return None returned_items = [] contents = r.json() for video in contents["videos"]: item = {} item["title"] = video["programTitle"] item["url"] = video["contentUrl"] item["thumbnail"] = helper.prepareThumb(video.get("thumbnail", ""), baseUrl=BASE_URL) info = {} info["title"] = item["title"] try: info["plot"] = video["description"] except KeyError: # Some videos do not have description (Rapport etc) info["plot"] = "" info["aired"] = video["broadcastDate"] try: info["duration"] = video["materialLength"] except KeyError: # Some programs are missing duration, default to 0 info["duration"] = 0 try: info["fanart"] = helper.prepareFanart(video["poster"], baseUrl=BASE_URL) except KeyError: pass item["info"] = info returned_items.append(item) return (returned_items, contents["paginationData"]["totalPages"] > contents["paginationData"]["currentPage"])
def viewAtoO(): r = requests.get("http://tv.aftonbladet.se/abtv/programs") containers = common.parseDOM(r.text, "div", attrs={"class": "site-index-link-wrapper"}) programs = [] for container in containers: program = {} links = common.parseDOM(container, "a", attrs={"class": "site-index-link"}, ret="href") imgs = common.parseDOM(container, "img", ret="srcset") titles = common.parseDOM(container, "div", attrs={"class": "site-index-link-title"}) descs = common.parseDOM(container, "div", attrs={"class": "site-index-link-desc"}) for i in range(len(links)): program = {} program["title"] = titles[i] program["desc"] = descs[i] listimg = imgs[i].split(",") lastimg = listimg[len(listimg) - 1] imglink = lastimg #.split(" ")[0] imglink = imglink.replace(" https", "http") program["img"] = imglink program["link"] = links[i] programs.append(program) common.log(program) addDirectoryItem(titles[i], { "mode": MODE_PROGRAM, "url": links[i] }, imglink, True, False, descs[i])
def deleteFile(subject, folder): common.log(subject + " - " + repr(folder)) file = findFile(subject, folder) if file: res = flickr.photos_delete(photo_id=file) common.log("Done: " + repr(res)) else: common.log("Failure: " + repr(file))
def checkFile(subject, folder): common.log(subject) global m file = findInFolder(subject, folder) if file: common.log("Found: " + repr(file)) return True else: common.log("Failure") return False
def verifyFileType(filename): common.log(filename) status = False fname, ext = os.path.splitext(os.path.basename(filename)) # Video gets converted to flv. # pdf gets (Horribly badly) converted to jpg if ext.lower() in [".jpg", ".jpeg", ".gif", ".png"]: common.log("Filetype can be uploaded: " + ext) status = True common.log("Done: " + repr(status)) return status
def checkFile(subject, folder): common.log(subject + " - " + repr(folder) + " - " + repr(user_id)) if not isinstance(folder, int) and not isinstance(folder, long): common.log("No set exists, thus no files exists: " + repr(folder) + " - " + repr(type(folder))) return False org_sub = subject file = findFile(subject, folder) if file: common.log("Found: " + repr(file)) print(org_sub) return True else: common.log("Failure") return False
def getPage(url): if not url.startswith("/") and not url.startswith("http://"): url = "/" + url result = common.fetchPage({"link": url}) if result["status"] == 200: return result["content"] if result["status"] == 500: common.log("redirect url: %s" % result["new_url"]) common.log("header: %s" % result["header"]) common.log("content: %s" % result["content"]) return None
def createFolder(subject, folder): common.log("%s - %s" % (subject, folder)) delay = 1 res = False while not res and delay < 10: try: res = m.create_folder(subject, folder) except errors.RequestError as e: if e[0] == -3: common.log( "[%s] EAGAIN: Retrying with exponential backoff: %s " % (repr(e[0]), repr(delay))) time.sleep(delay) delay += 1 else: common.log("errors.RequestError: " + repr(e)) sys.exit(1) if res: common.log("Done: " + repr(res)) return res else: return False
def login(uname): common.log(uname) (token, frob) = flickr.get_token_part_one(perms='delete') if not token: try: raw_input("Press ENTER after you authorized this program") except Exception as e: common.log( "Sleeping for 60s while waiting for user to authorize program: " + repr(e)) time.sleep(60) flickr.get_token_part_two((token, frob)) global user_id user_id = flickr.people_findByEmail(find_email=uname) user_id = user_id[0].attrib["nsid"] common.log("Done: " + repr(token) + " - " + repr(frob) + " - " + repr(user_id))
def getStreamForBW(url): """ Returns a stream URL for the set bandwidth, and an error message, if applicable. """ low_bandwidth = int(float(addon.getSetting("bandwidth"))) high_bandwidth = getHighBw(low_bandwidth) f = urllib.urlopen(url) lines = f.readlines() hlsurl = "" marker = "#EXT-X-STREAM-INF" found = False for line in lines: if found: # The stream url is on the line proceeding the header hlsurl = line break if marker in line: # The header match = re.match(r'.*BANDWIDTH=(\d+)000.+', line) if match: if low_bandwidth < int(match.group(1)) < high_bandwidth: common.log("Found stream with bandwidth " + match.group(1) + " for selected bandwidth " + str(low_bandwidth)) found = True f.close() if found: hlsurl = hlsurl.rstrip() common.log("Returned stream url: " + hlsurl) return (hlsurl, '') else: errormsg = "No stream found for bandwidth setting " + str( low_bandwidth) common.log(errormsg) return (None, errormsg)
def func(progress, done): common.log("func: %s - %s" % (repr(progress), repr(done))) if len(done): print("Done uploading") else: print("At %s%%" % progress)
def postFile(subject, filename, folder, git_top_level): common.log("%s to %s - %s" % (filename, repr(folder), subject)) def func(progress, done): common.log("func: %s - %s" % (repr(progress), repr(done))) if len(done): print("Done uploading") else: print("At %s%%" % progress) width, height, pixels, meta, text = png.Reader(filename=pwd + "/logo_small.png").read() upper_limit = 40234050 if os.path.getsize(filename) > upper_limit: print("%s size: %s more than %s. Skipping" % (filename, os.path.getsize(filename), upper_limit)) sys.exit(1) tags = [] if conf["encrypted"]: tfile = pwd + "/temp/encoded-" + subject f = open(tfile, 'wb') text = readFile(filename, "rb") text = base64.b64encode(text) w = png.Writer(width, height, text={"data": text}) w.write(f, pixels) f.close() else: tfile = filename if git_top_level: common.log("git top level directory: %s" % git_top_level) dirpath = os.path.relpath(os.path.dirname(tfile), git_top_level) if dirpath.find(".git") == -1: tags = dirpath.split(os.sep) common.log("Tags added to photo " + repr(tags)) common.log("Uploading: " + tfile) res = flickr.upload(filename=tfile, is_public=0, title=subject, description=os.path.basename(tfile), tags='"' + '" "'.join(tags) + '"', callback=func) if len(res): if isinstance(folder, int) or isinstance(folder, long): flickr.photosets_addPhoto(photoset_id=folder, photo_id=res[0].text) else: flickr.photosets_create(title=folder, primary_photo_id=res[0].text) if conf["encrypted"]: os.unlink(pwd + "/temp/encoded-" + subject) if len(res): common.log("Done: " + repr(res)) else: print("Failed to store: " + repr(res)) sys.exit(1)
def main(): global conf args = sys.argv ANNEX_ACTION = os.getenv("ANNEX_ACTION") ANNEX_KEY = os.getenv("ANNEX_KEY") ANNEX_HASH_1 = os.getenv("ANNEX_HASH_1") ANNEX_HASH_2 = os.getenv("ANNEX_HASH_2") ANNEX_FILE = os.getenv("ANNEX_FILE") GIT_TOP_LEVEL = os.getenv("GIT_TOP_LEVEL") envargs = [] if ANNEX_ACTION: envargs += ["ANNEX_ACTION=" + ANNEX_ACTION] if ANNEX_KEY: envargs += ["ANNEX_KEY=" + ANNEX_KEY] if ANNEX_HASH_1: envargs += ["ANNEX_HASH_1=" + ANNEX_HASH_1] if ANNEX_HASH_2: envargs += ["ANNEX_HASH_2=" + ANNEX_HASH_2] if ANNEX_FILE: envargs += ["ANNEX_FILE=" + ANNEX_FILE] if GIT_TOP_LEVEL: envargs += ["GIT_TOP_LEVEL=" + GIT_TOP_LEVEL] common.log("ARGS: " + repr(" ".join(envargs + args))) conf = readFile(configfile) try: conf = json.loads(conf) except Exception as e: common.log("Traceback EXCEPTION: " + repr(e)) common.log("Couldn't parse conf: " + repr(conf)) conf = {"folder": "gitannex"} common.log("Conf: " + repr(conf), 2) changed = False if "uname" not in conf: common.log("Asking user for email address") print( "Please make sure your email address has been associated flickr.") conf["uname"] = raw_input("Please enter your flickr email address: ") common.log("e-mail set to: " + conf["uname"]) changed = True if "encrypted" not in conf: conf["encrypted"] = "?" common.log("Asking user for encryption") while (conf["encrypted"].lower().find("y") == -1 and conf["encrypted"].lower().find("n") == -1): conf["encrypted"] = raw_input( "Should uploaded files be encrypted [yes/no]: ") conf["encrypted"] = conf["encrypted"].lower().find("y") > -1 common.log("encryption set to: " + repr(conf["encrypted"])) changed = True login(conf["uname"]) ANNEX_FOLDER = conf["folder"] page = 1 common.log("Photoset %s searching for %s" % (repr(ANNEX_FOLDER), repr(conf["folder"]))) while ANNEX_FOLDER == conf["folder"]: common.log("Trying page: " + repr(page)) sets = flickr.photosets_getList(per_page=500) sets = sets.find('photosets') for s in sets.findall('photoset'): if s[0].text == conf["folder"]: common.log("Photoset %s found: %s" % (s[0].text, repr(s[0].text))) ANNEX_FOLDER = long(s.attrib["id"]) break if int(sets.attrib["pages"]) > page: page += 1 else: common.log("Error. found nothing:" + repr(sets.attrib)) break if not conf["encrypted"] and ANNEX_KEY and not verifyFileType(ANNEX_KEY): print("Unencrypted flickr can only accept picture and video files") sys.exit(1) if ANNEX_FILE and os.path.exists( ANNEX_FILE) and os.path.getsize(ANNEX_FILE) > 31457280: print("flickr won't accept files larger than ~30mb") sys.exit(1) if "store" == ANNEX_ACTION: postFile(ANNEX_KEY, ANNEX_FILE, ANNEX_FOLDER, GIT_TOP_LEVEL) elif "checkpresent" == ANNEX_ACTION: checkFile(ANNEX_KEY, ANNEX_FOLDER) elif "retrieve" == ANNEX_ACTION: getFile(ANNEX_KEY, ANNEX_FILE, ANNEX_FOLDER) elif "remove" == ANNEX_ACTION: deleteFile(ANNEX_KEY, ANNEX_FOLDER) elif changed or True: if user_id: print("Program sucessfully setup") if conf["encrypted"]: encryption = "shared" else: encryption = "none" setup = ''' Please run the following commands in your annex directory: git config annex.flickr-hook '/usr/bin/python2 %s/flickrannex.py' # If you have a direct mode repository and want to use your directores as tags, use this hook instead git config annex.flickr-hook 'GIT_TOP_LEVEL=`git rev-parse --show-toplevel` /usr/bin/python2 %s/flickrannex.py' git annex initremote flickr type=hook hooktype=flickr encryption=%s git annex describe flickr "the flickr library" git annex content flickr exclude=largerthan=30mb # If you have an unencrypted repository also use this git annex content flickr uuid include=*.jpg or include=*.jpeg or include=*.gif or include=*.png ''' % (os.getcwd(), os.getcwd(), encryption) print setup common.log("Saving " + repr(configfile), 0) saveFile(configfile, json.dumps(conf)) else: print("Error during setup. Please try again") else: print("ERROR") sys.exit(1)
def saveFile(fname, content, flags="w"): common.log(fname + " - " + str(len(content)) + " - " + repr(flags)) t = open(fname, flags) t.write(content) t.close() common.log("Done")
setup = ''' Please run the following commands in your annex directory: git config annex.flickr-hook '/usr/bin/python2 %s/flickrannex.py' # If you have a direct mode repository and want to use your directores as tags, use this hook instead git config annex.flickr-hook 'GIT_TOP_LEVEL=`git rev-parse --show-toplevel` /usr/bin/python2 %s/flickrannex.py' git annex initremote flickr type=hook hooktype=flickr encryption=%s git annex describe flickr "the flickr library" git annex content flickr exclude=largerthan=30mb # If you have an unencrypted repository also use this git annex content flickr uuid include=*.jpg or include=*.jpeg or include=*.gif or include=*.png ''' % (os.getcwd(), os.getcwd(), encryption) print setup common.log("Saving " + repr(configfile), 0) saveFile(configfile, json.dumps(conf)) else: print("Error during setup. Please try again") else: print("ERROR") sys.exit(1) t = time.time() common.log("START") if __name__ == '__main__': main() common.log("STOP: %ss" % int(time.time() - t))
def findFile(subject, folder, root=False): common.log(subject + " - " + repr(folder) + " - " + repr(user_id)) file = False page = 1 while not file: common.log("Trying page: " + repr(page)) if root: photos = flickr.photosets_getPhotos(photoset_id=folder, per_page=500, page=page) else: photos = flickr.photosets_getPhotos(photoset_id=folder, per_page=500, page=page) photos = photos.find("photoset") for s in photos.findall('photo'): ttitle = s.attrib["title"] common.log("Found title: " + repr(ttitle), 2) if ttitle == subject: if root: file = ttitle else: file = long(s.attrib["id"]) common.log("Done: " + repr(file)) return file if int(photos.attrib["pages"]) > page: page += 1 else: common.log("Error, found nothing:" + repr(photos)) common.log("Error, found nothing:" + repr(photos.attrib)) break common.log("Failure: " + repr(file)) return False