Test Download (aggiunta di nuove librerie da Alfa)
This commit is contained in:
+78
-44
@@ -17,23 +17,33 @@ metodos:
|
||||
stop(erase = False) Detiene la descarga, con erase = True elimina los datos descargados
|
||||
|
||||
"""
|
||||
from __future__ import division
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from future.builtins import range
|
||||
from future.builtins import object
|
||||
from past.utils import old_div
|
||||
#from builtins import str
|
||||
import sys
|
||||
PY3 = False
|
||||
VFS = True
|
||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int; VFS = False
|
||||
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import urllib
|
||||
|
||||
from threading import Thread, Lock
|
||||
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
from core import filetools
|
||||
from core import filetools, jsontools
|
||||
from platformcode import logger, config
|
||||
|
||||
|
||||
class Downloader:
|
||||
class Downloader(object):
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
@@ -58,7 +68,7 @@ class Downloader:
|
||||
@property
|
||||
def remaining_time(self):
|
||||
if self.speed[0] and self._file_size:
|
||||
t = (self.size[0] - self.downloaded[0]) / self.speed[0]
|
||||
t = old_div((self.size[0] - self.downloaded[0]), self.speed[0])
|
||||
else:
|
||||
t = 0
|
||||
|
||||
@@ -139,9 +149,17 @@ class Downloader:
|
||||
if self._seekable:
|
||||
# Guardamos la info al final del archivo
|
||||
self.file.seek(0, 2)
|
||||
offset = self.file.tell()
|
||||
self.file.write(str(self._download_info))
|
||||
self.file.write("%0.16d" % offset)
|
||||
try:
|
||||
offset = self.file.tell()
|
||||
except:
|
||||
offset = self.file.seek(0, 1)
|
||||
if not PY3:
|
||||
self.file.write(str(self._download_info))
|
||||
self.file.write("%0.16d" % offset)
|
||||
else:
|
||||
download_info_dump = jsontools.dump(self._download_info).encode('utf-8')
|
||||
self.file.write(download_info_dump)
|
||||
self.file.write(b"%0.16d" % offset)
|
||||
|
||||
self.file.close()
|
||||
|
||||
@@ -158,8 +176,8 @@ class Downloader:
|
||||
time.sleep(1)
|
||||
|
||||
while self.state == self.states.downloading:
|
||||
self._average_speed = (self.downloaded[0] - self._start_downloaded) / (time.time() - self._start_time)
|
||||
self._speed = (self.downloaded[0] - self._start_downloaded) / (time.time() - self._start_time)
|
||||
self._average_speed = old_div((self.downloaded[0] - self._start_downloaded), (time.time() - self._start_time))
|
||||
self._speed = old_div((self.downloaded[0] - self._start_downloaded), (time.time() - self._start_time))
|
||||
# self._speed = (self.downloaded[0] - downloaded) / (time.time() -t)
|
||||
|
||||
if time.time() - t > 5:
|
||||
@@ -224,20 +242,27 @@ class Downloader:
|
||||
self.__get_download_filename__()
|
||||
|
||||
# Abrimos en modo "a+" para que cree el archivo si no existe, luego en modo "r+b" para poder hacer seek()
|
||||
self.file = filetools.file_open(filetools.join(self._path, self._filename), "a+")
|
||||
self.file = filetools.file_open(filetools.join(self._path, self._filename), "r+b")
|
||||
self.file = filetools.file_open(filetools.join(self._path, self._filename), "a+", vfs=VFS)
|
||||
if self.file: self.file.close()
|
||||
self.file = filetools.file_open(filetools.join(self._path, self._filename), "r+b", vfs=VFS)
|
||||
if not self.file:
|
||||
return
|
||||
|
||||
if self._file_size >= 2 ** 31 or not self._file_size:
|
||||
try:
|
||||
self.file.seek(2 ** 31)
|
||||
self.file.seek(2 ** 31, 0)
|
||||
except OverflowError:
|
||||
self._seekable = False
|
||||
logger.info("Cannot do seek() or tell() in files larger than 2GB")
|
||||
|
||||
self.__get_download_info__()
|
||||
|
||||
logger.info("Initialized Download: Parts: %s | Path: %s | Archive: %s | Size: %s" % (
|
||||
len(self._download_info["parts"]), self._path, self._filename, self._download_info["size"]))
|
||||
try:
|
||||
logger.info("Initialized Download: Parts: %s | Path: %s | Archive: %s | Size: %s" % \
|
||||
(str(len(self._download_info["parts"])), self._pathencode('utf-8'), \
|
||||
self._filenameencode('utf-8'), str(self._download_info["size"])))
|
||||
except:
|
||||
pass
|
||||
|
||||
def __url_to_headers__(self, url):
|
||||
# Separamos la url de los headers adicionales
|
||||
@@ -245,13 +270,13 @@ class Downloader:
|
||||
|
||||
# headers adicionales
|
||||
if "|" in url:
|
||||
self._headers.update(dict([[header.split("=")[0], urllib.unquote_plus(header.split("=")[1])] for header in
|
||||
self._headers.update(dict([[header.split("=")[0], urllib.parse.unquote_plus(header.split("=")[1])] for header in
|
||||
url.split("|")[1].split("&")]))
|
||||
|
||||
def __get_download_headers__(self):
|
||||
if self.url.startswith("https"):
|
||||
try:
|
||||
conn = urllib2.urlopen(urllib2.Request(self.url.replace("https", "http"), headers=self._headers))
|
||||
conn = urllib.request.urlopen(urllib.request.Request(self.url.replace("https", "http"), headers=self._headers))
|
||||
conn.fp._sock.close()
|
||||
self.url = self.url.replace("https", "http")
|
||||
except:
|
||||
@@ -260,16 +285,16 @@ class Downloader:
|
||||
for x in range(3):
|
||||
try:
|
||||
if not sys.hexversion > 0x0204FFFF:
|
||||
conn = urllib2.urlopen(urllib2.Request(self.url, headers=self._headers))
|
||||
conn = urllib.request.urlopen(urllib.request.Request(self.url, headers=self._headers))
|
||||
conn.fp._sock.close()
|
||||
else:
|
||||
conn = urllib2.urlopen(urllib2.Request(self.url, headers=self._headers), timeout=5)
|
||||
conn = urllib.request.urlopen(urllib.request.Request(self.url, headers=self._headers), timeout=5)
|
||||
|
||||
except:
|
||||
self.response_headers = dict()
|
||||
self._state = self.states.error
|
||||
else:
|
||||
self.response_headers = conn.headers.dict
|
||||
self.response_headers = conn.headers
|
||||
self._state = self.states.stopped
|
||||
break
|
||||
|
||||
@@ -278,20 +303,20 @@ class Downloader:
|
||||
if "filename" in self.response_headers.get("content-disposition",
|
||||
"") and "attachment" in self.response_headers.get(
|
||||
"content-disposition", ""):
|
||||
cd_filename, cd_ext = os.path.splitext(urllib.unquote_plus(
|
||||
cd_filename, cd_ext = os.path.splitext(urllib.parse.unquote_plus(
|
||||
re.compile("attachment; filename ?= ?[\"|']?([^\"']+)[\"|']?").match(
|
||||
self.response_headers.get("content-disposition")).group(1)))
|
||||
if "filename" in self.response_headers.get("content-disposition", "") and "inline" in self.response_headers.get(
|
||||
elif "filename" in self.response_headers.get("content-disposition", "") and "inline" in self.response_headers.get(
|
||||
"content-disposition", ""):
|
||||
cd_filename, cd_ext = os.path.splitext(urllib.unquote_plus(
|
||||
cd_filename, cd_ext = os.path.splitext(urllib.parse.unquote_plus(
|
||||
re.compile("inline; filename ?= ?[\"|']?([^\"']+)[\"|']?").match(
|
||||
self.response_headers.get("content-disposition")).group(1)))
|
||||
else:
|
||||
cd_filename, cd_ext = "", ""
|
||||
|
||||
url_filename, url_ext = os.path.splitext(
|
||||
urllib.unquote_plus(filetools.basename(urlparse.urlparse(self.url)[2])))
|
||||
if self.response_headers.get("content-type", "application/octet-stream") <> "application/octet-stream":
|
||||
urllib.parse.unquote_plus(filetools.basename(urllib.parse.urlparse(self.url)[2])))
|
||||
if self.response_headers.get("content-type", "application/octet-stream") != "application/octet-stream":
|
||||
mime_ext = mimetypes.guess_extension(self.response_headers.get("content-type"))
|
||||
else:
|
||||
mime_ext = ""
|
||||
@@ -324,7 +349,7 @@ class Downloader:
|
||||
if value <= 0:
|
||||
return 0, 0, units[0]
|
||||
else:
|
||||
return value, value / 1024.0 ** int(math.log(value, 1024)), units[int(math.log(value, 1024))]
|
||||
return value, old_div(value, 1024.0 ** int(math.log(value, 1024))), units[int(math.log(value, 1024))]
|
||||
|
||||
def __get_download_info__(self):
|
||||
# Continuamos con una descarga que contiene la info al final del archivo
|
||||
@@ -335,13 +360,16 @@ class Downloader:
|
||||
raise Exception()
|
||||
self.file.seek(-16, 2)
|
||||
offset = int(self.file.read())
|
||||
self.file.seek(offset)
|
||||
self.file.seek(offset, 0)
|
||||
data = self.file.read()[:-16]
|
||||
self._download_info = eval(data)
|
||||
if not self._download_info["size"] == self._file_size:
|
||||
raise Exception()
|
||||
self.file.seek(offset)
|
||||
self.file.truncate()
|
||||
self.file.seek(offset, 0)
|
||||
try:
|
||||
self.file.truncate()
|
||||
except:
|
||||
pass
|
||||
|
||||
if not self._seekable:
|
||||
for part in self._download_info["parts"]:
|
||||
@@ -377,17 +405,20 @@ class Downloader:
|
||||
self.save_parts = set()
|
||||
self.download_parts = set()
|
||||
|
||||
self.file.seek(0)
|
||||
self.file.truncate()
|
||||
self.file.seek(0, 0)
|
||||
try:
|
||||
self.file.truncate()
|
||||
except:
|
||||
pass
|
||||
|
||||
def __open_connection__(self, start, end):
|
||||
headers = self._headers.copy()
|
||||
if not end: end = ""
|
||||
headers.update({"Range": "bytes=%s-%s" % (start, end)})
|
||||
if not sys.hexversion > 0x0204FFFF:
|
||||
conn = urllib2.urlopen(urllib2.Request(self.url, headers=headers))
|
||||
conn = urllib.request.urlopen(urllib.request.Request(self.url, headers=headers))
|
||||
else:
|
||||
conn = urllib2.urlopen(urllib2.Request(self.url, headers=headers), timeout=5)
|
||||
conn = urllib.request.urlopen(urllib.request.Request(self.url, headers=headers), timeout=5)
|
||||
return conn
|
||||
|
||||
def __check_consecutive__(self, id):
|
||||
@@ -412,7 +443,7 @@ class Downloader:
|
||||
continue
|
||||
|
||||
if self._seekable or self._download_info["parts"][save_id]["start"] < 2 ** 31:
|
||||
self.file.seek(self._download_info["parts"][save_id]["start"])
|
||||
self.file.seek(self._download_info["parts"][save_id]["start"], 0)
|
||||
|
||||
try:
|
||||
# file = open(os.path.join(self.tmp_path, self._filename + ".part%s" % save_id), "rb")
|
||||
@@ -477,9 +508,12 @@ class Downloader:
|
||||
self.pending_parts.add(id)
|
||||
|
||||
def __open_part_file__(self, id):
|
||||
file = open(os.path.join(self.tmp_path, self._filename + ".part%s" % id), "a+")
|
||||
file = open(os.path.join(self.tmp_path, self._filename + ".part%s" % id), "r+b")
|
||||
file.seek(self._download_info["parts"][id]["current"] - self._download_info["parts"][id]["start"])
|
||||
#file = open(os.path.join(self.tmp_path, self._filename + ".part%s" % id), "a+")
|
||||
#file = open(os.path.join(self.tmp_path, self._filename + ".part%s" % id), "r+b")
|
||||
self.file = filetools.file_open(filetools.join(self.tmp_path, self._filename + ".part%s" % id), "a+", vfs=VFS)
|
||||
self.file.close()
|
||||
self.file = filetools.file_open(filetools.join(self.tmp_path, self._filename + ".part%s" % id), "r+b", vfs=VFS)
|
||||
file.seek(self._download_info["parts"][id]["current"] - self._download_info["parts"][id]["start"], 0)
|
||||
return file
|
||||
|
||||
def __start_part__(self):
|
||||
@@ -509,7 +543,7 @@ class Downloader:
|
||||
try:
|
||||
start = time.time()
|
||||
buffer = connection.read(self._block_size)
|
||||
speed.append(len(buffer) / ((time.time() - start) or 0.001))
|
||||
speed.append(old_div(len(buffer), ((time.time() - start) or 0.001)))
|
||||
except:
|
||||
logger.info("ID: %s Error downloading data" % id)
|
||||
self._download_info["parts"][id]["status"] = self.states.error
|
||||
@@ -523,7 +557,7 @@ class Downloader:
|
||||
self._buffer[id].append(buffer)
|
||||
self._download_info["parts"][id]["current"] += len(buffer)
|
||||
if len(speed) > 10:
|
||||
velocidad_minima = sum(speed) / len(speed) / 3
|
||||
velocidad_minima = old_div(old_div(sum(speed), len(speed)), 3)
|
||||
velocidad = speed[-1]
|
||||
vm = self.__change_units__(velocidad_minima)
|
||||
v = self.__change_units__(velocidad)
|
||||
@@ -531,7 +565,7 @@ class Downloader:
|
||||
if velocidad_minima > speed[-1] and velocidad_minima > speed[-2] and \
|
||||
self._download_info["parts"][id]["current"] < \
|
||||
self._download_info["parts"][id]["end"]:
|
||||
connection.fp._sock.close()
|
||||
if connection.fp: connection.fp._sock.close()
|
||||
logger.info(
|
||||
"ID: %s Restarting connection! | Minimum Speed: %.2f %s/s | Speed: %.2f %s/s" % \
|
||||
(id, vm[1], vm[2], v[1], v[2]))
|
||||
@@ -539,7 +573,7 @@ class Downloader:
|
||||
break
|
||||
else:
|
||||
self.__set_part_completed__(id)
|
||||
connection.fp._sock.close()
|
||||
if connection.fp: connection.fp._sock.close()
|
||||
# file.close()
|
||||
break
|
||||
|
||||
|
||||
+58
-361
@@ -3,271 +3,26 @@
|
||||
# Download Tools - Original based from code of VideoMonkey XBMC Plugin
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os.path
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
#from builtins import str
|
||||
from past.utils import old_div
|
||||
import sys
|
||||
PY3 = False
|
||||
VFS = True
|
||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int; VFS = False
|
||||
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
|
||||
import urllib2
|
||||
|
||||
from platformcode import config, logger
|
||||
|
||||
entitydefs = {
|
||||
'AElig': u'\u00C6', # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1'
|
||||
'Aacute': u'\u00C1', # latin capital letter A with acute, U+00C1 ISOlat1'
|
||||
'Acirc': u'\u00C2', # latin capital letter A with circumflex, U+00C2 ISOlat1'
|
||||
'Agrave': u'\u00C0', # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1'
|
||||
'Alpha': u'\u0391', # greek capital letter alpha, U+0391'
|
||||
'Aring': u'\u00C5', # latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1'
|
||||
'Atilde': u'\u00C3', # latin capital letter A with tilde, U+00C3 ISOlat1'
|
||||
'Auml': u'\u00C4', # latin capital letter A with diaeresis, U+00C4 ISOlat1'
|
||||
'Beta': u'\u0392', # greek capital letter beta, U+0392'
|
||||
'Ccedil': u'\u00C7', # latin capital letter C with cedilla, U+00C7 ISOlat1'
|
||||
'Chi': u'\u03A7', # greek capital letter chi, U+03A7'
|
||||
'Dagger': u'\u2021', # double dagger, U+2021 ISOpub'
|
||||
'Delta': u'\u0394', # greek capital letter delta, U+0394 ISOgrk3'
|
||||
'ETH': u'\u00D0', # latin capital letter ETH, U+00D0 ISOlat1'
|
||||
'Eacute': u'\u00C9', # latin capital letter E with acute, U+00C9 ISOlat1'
|
||||
'Ecirc': u'\u00CA', # latin capital letter E with circumflex, U+00CA ISOlat1'
|
||||
'Egrave': u'\u00C8', # latin capital letter E with grave, U+00C8 ISOlat1'
|
||||
'Epsilon': u'\u0395', # grek capital letter epsilon, U+0395'
|
||||
'Eta': u'\u0397', # greek capital letter eta, U+0397'
|
||||
'Euml': u'\u00CB', # latin capital letter E with diaeresis, U+00CB ISOlat1'
|
||||
'Gamma': u'\u0393', # greek capital letter gamma, U+0393 ISOgrk3'
|
||||
'Iacute': u'\u00CD', # latin capital letter I with acute, U+00CD ISOlat1'
|
||||
'Icirc': u'\u00CE', # latin capital letter I with circumflex, U+00CE ISOlat1'
|
||||
'Igrave': u'\u00CC', # latin capital letter I with grave, U+00CC ISOlat1'
|
||||
'Iota': u'\u0399', # greek capital letter iota, U+0399'
|
||||
'Iuml': u'\u00CF', # latin capital letter I with diaeresis, U+00CF ISOlat1'
|
||||
'Kappa': u'\u039A', # greek capital letter kappa, U+039A'
|
||||
'Lambda': u'\u039B', # greek capital letter lambda, U+039B ISOgrk3'
|
||||
'Mu': u'\u039C', # greek capital letter mu, U+039C'
|
||||
'Ntilde': u'\u00D1', # latin capital letter N with tilde, U+00D1 ISOlat1'
|
||||
'Nu': u'\u039D', # greek capital letter nu, U+039D'
|
||||
'OElig': u'\u0152', # latin capital ligature OE, U+0152 ISOlat2'
|
||||
'Oacute': u'\u00D3', # latin capital letter O with acute, U+00D3 ISOlat1'
|
||||
'Ocirc': u'\u00D4', # latin capital letter O with circumflex, U+00D4 ISOlat1'
|
||||
'Ograve': u'\u00D2', # latin capital letter O with grave, U+00D2 ISOlat1'
|
||||
'Omega': u'\u03A9', # greek capital letter omega, U+03A9 ISOgrk3'
|
||||
'Omicron': u'\u039F', # greek capital letter omicron, U+039F'
|
||||
'Oslash': u'\u00D8', # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1'
|
||||
'Otilde': u'\u00D5', # latin capital letter O with tilde, U+00D5 ISOlat1'
|
||||
'Ouml': u'\u00D6', # latin capital letter O with diaeresis, U+00D6 ISOlat1'
|
||||
'Phi': u'\u03A6', # greek capital letter phi, U+03A6 ISOgrk3'
|
||||
'Pi': u'\u03A0', # greek capital letter pi, U+03A0 ISOgrk3'
|
||||
'Prime': u'\u2033', # double prime = seconds = inches, U+2033 ISOtech'
|
||||
'Psi': u'\u03A8', # greek capital letter psi, U+03A8 ISOgrk3'
|
||||
'Rho': u'\u03A1', # greek capital letter rho, U+03A1'
|
||||
'Scaron': u'\u0160', # latin capital letter S with caron, U+0160 ISOlat2'
|
||||
'Sigma': u'\u03A3', # greek capital letter sigma, U+03A3 ISOgrk3'
|
||||
'THORN': u'\u00DE', # latin capital letter THORN, U+00DE ISOlat1'
|
||||
'Tau': u'\u03A4', # greek capital letter tau, U+03A4'
|
||||
'Theta': u'\u0398', # greek capital letter theta, U+0398 ISOgrk3'
|
||||
'Uacute': u'\u00DA', # latin capital letter U with acute, U+00DA ISOlat1'
|
||||
'Ucirc': u'\u00DB', # latin capital letter U with circumflex, U+00DB ISOlat1'
|
||||
'Ugrave': u'\u00D9', # latin capital letter U with grave, U+00D9 ISOlat1'
|
||||
'Upsilon': u'\u03A5', # greek capital letter upsilon, U+03A5 ISOgrk3'
|
||||
'Uuml': u'\u00DC', # latin capital letter U with diaeresis, U+00DC ISOlat1'
|
||||
'Xi': u'\u039E', # greek capital letter xi, U+039E ISOgrk3'
|
||||
'Yacute': u'\u00DD', # latin capital letter Y with acute, U+00DD ISOlat1'
|
||||
'Yuml': u'\u0178', # latin capital letter Y with diaeresis, U+0178 ISOlat2'
|
||||
'Zeta': u'\u0396', # greek capital letter zeta, U+0396'
|
||||
'aacute': u'\u00E1', # latin small letter a with acute, U+00E1 ISOlat1'
|
||||
'acirc': u'\u00E2', # latin small letter a with circumflex, U+00E2 ISOlat1'
|
||||
'acute': u'\u00B4', # acute accent = spacing acute, U+00B4 ISOdia'
|
||||
'aelig': u'\u00E6', # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1'
|
||||
'agrave': u'\u00E0', # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1'
|
||||
'alefsym': u'\u2135', # alef symbol = first transfinite cardinal, U+2135 NEW'
|
||||
'alpha': u'\u03B1', # greek small letter alpha, U+03B1 ISOgrk3'
|
||||
'amp': u'\u0026', # ampersand, U+0026 ISOnum'
|
||||
'and': u'\u2227', # logical and = wedge, U+2227 ISOtech'
|
||||
'ang': u'\u2220', # angle, U+2220 ISOamso'
|
||||
'aring': u'\u00E5', # latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1'
|
||||
'asymp': u'\u2248', # almost equal to = asymptotic to, U+2248 ISOamsr'
|
||||
'atilde': u'\u00E3', # latin small letter a with tilde, U+00E3 ISOlat1'
|
||||
'auml': u'\u00E4', # latin small letter a with diaeresis, U+00E4 ISOlat1'
|
||||
'bdquo': u'\u201E', # double low-9 quotation mark, U+201E NEW'
|
||||
'beta': u'\u03B2', # greek small letter beta, U+03B2 ISOgrk3'
|
||||
'brvbar': u'\u00A6', # broken bar = broken vertical bar, U+00A6 ISOnum'
|
||||
'bull': u'\u2022', # bullet = black small circle, U+2022 ISOpub'
|
||||
'cap': u'\u2229', # intersection = cap, U+2229 ISOtech'
|
||||
'ccedil': u'\u00E7', # latin small letter c with cedilla, U+00E7 ISOlat1'
|
||||
'cedil': u'\u00B8', # cedilla = spacing cedilla, U+00B8 ISOdia'
|
||||
'cent': u'\u00A2', # cent sign, U+00A2 ISOnum'
|
||||
'chi': u'\u03C7', # greek small letter chi, U+03C7 ISOgrk3'
|
||||
'circ': u'\u02C6', # modifier letter circumflex accent, U+02C6 ISOpub'
|
||||
'clubs': u'\u2663', # black club suit = shamrock, U+2663 ISOpub'
|
||||
'cong': u'\u2245', # approximately equal to, U+2245 ISOtech'
|
||||
'copy': u'\u00A9', # copyright sign, U+00A9 ISOnum'
|
||||
'crarr': u'\u21B5', # downwards arrow with corner leftwards = carriage return, U+21B5 NEW'
|
||||
'cup': u'\u222A', # union = cup, U+222A ISOtech'
|
||||
'curren': u'\u00A4', # currency sign, U+00A4 ISOnum'
|
||||
'dArr': u'\u21D3', # downwards double arrow, U+21D3 ISOamsa'
|
||||
'dagger': u'\u2020', # dagger, U+2020 ISOpub'
|
||||
'darr': u'\u2193', # downwards arrow, U+2193 ISOnum'
|
||||
'deg': u'\u00B0', # degree sign, U+00B0 ISOnum'
|
||||
'delta': u'\u03B4', # greek small letter delta, U+03B4 ISOgrk3'
|
||||
'diams': u'\u2666', # black diamond suit, U+2666 ISOpub'
|
||||
'divide': u'\u00F7', # division sign, U+00F7 ISOnum'
|
||||
'eacute': u'\u00E9', # latin small letter e with acute, U+00E9 ISOlat1'
|
||||
'ecirc': u'\u00EA', # latin small letter e with circumflex, U+00EA ISOlat1'
|
||||
'egrave': u'\u00E8', # latin small letter e with grave, U+00E8 ISOlat1'
|
||||
'empty': u'\u2205', # empty set = null set = diameter, U+2205 ISOamso'
|
||||
'emsp': u'\u2003', # em space, U+2003 ISOpub'
|
||||
'ensp': u'\u2002', # en space, U+2002 ISOpub'
|
||||
'epsilon': u'\u03B5', # greek small letter epsilon, U+03B5 ISOgrk3'
|
||||
'equiv': u'\u2261', # identical to, U+2261 ISOtech'
|
||||
'eta': u'\u03B7', # greek small letter eta, U+03B7 ISOgrk3'
|
||||
'eth': u'\u00F0', # latin small letter eth, U+00F0 ISOlat1'
|
||||
'euml': u'\u00EB', # latin small letter e with diaeresis, U+00EB ISOlat1'
|
||||
'euro': u'\u20AC', # euro sign, U+20AC NEW'
|
||||
'exist': u'\u2203', # there exists, U+2203 ISOtech'
|
||||
'fnof': u'\u0192', # latin small f with hook = function = florin, U+0192 ISOtech'
|
||||
'forall': u'\u2200', # for all, U+2200 ISOtech'
|
||||
'frac12': u'\u00BD', # vulgar fraction one half = fraction one half, U+00BD ISOnum'
|
||||
'frac14': u'\u00BC', # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum'
|
||||
'frac34': u'\u00BE', # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum'
|
||||
'frasl': u'\u2044', # fraction slash, U+2044 NEW'
|
||||
'gamma': u'\u03B3', # greek small letter gamma, U+03B3 ISOgrk3'
|
||||
'ge': u'\u2265', # greater-than or equal to, U+2265 ISOtech'
|
||||
'gt': u'\u003E', # greater-than sign, U+003E ISOnum'
|
||||
'hArr': u'\u21D4', # left right double arrow, U+21D4 ISOamsa'
|
||||
'harr': u'\u2194', # left right arrow, U+2194 ISOamsa'
|
||||
'hearts': u'\u2665', # black heart suit = valentine, U+2665 ISOpub'
|
||||
'hellip': u'\u2026', # horizontal ellipsis = three dot leader, U+2026 ISOpub'
|
||||
'iacute': u'\u00ED', # latin small letter i with acute, U+00ED ISOlat1'
|
||||
'icirc': u'\u00EE', # latin small letter i with circumflex, U+00EE ISOlat1'
|
||||
'iexcl': u'\u00A1', # inverted exclamation mark, U+00A1 ISOnum'
|
||||
'igrave': u'\u00EC', # latin small letter i with grave, U+00EC ISOlat1'
|
||||
'image': u'\u2111', # blackletter capital I = imaginary part, U+2111 ISOamso'
|
||||
'infin': u'\u221E', # infinity, U+221E ISOtech'
|
||||
'int': u'\u222B', # integral, U+222B ISOtech'
|
||||
'iota': u'\u03B9', # greek small letter iota, U+03B9 ISOgrk3'
|
||||
'iquest': u'\u00BF', # inverted question mark = turned question mark, U+00BF ISOnum'
|
||||
'isin': u'\u2208', # element of, U+2208 ISOtech'
|
||||
'iuml': u'\u00EF', # latin small letter i with diaeresis, U+00EF ISOlat1'
|
||||
'kappa': u'\u03BA', # greek small letter kappa, U+03BA ISOgrk3'
|
||||
'lArr': u'\u21D0', # leftwards double arrow, U+21D0 ISOtech'
|
||||
'lambda': u'\u03BB', # greek small letter lambda, U+03BB ISOgrk3'
|
||||
'lang': u'\u2329', # left-pointing angle bracket = bra, U+2329 ISOtech'
|
||||
'laquo': u'\u00AB', # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum'
|
||||
'larr': u'\u2190', # leftwards arrow, U+2190 ISOnum'
|
||||
'lceil': u'\u2308', # left ceiling = apl upstile, U+2308 ISOamsc'
|
||||
'ldquo': u'\u201C', # left double quotation mark, U+201C ISOnum'
|
||||
'le': u'\u2264', # less-than or equal to, U+2264 ISOtech'
|
||||
'lfloor': u'\u230A', # left floor = apl downstile, U+230A ISOamsc'
|
||||
'lowast': u'\u2217', # asterisk operator, U+2217 ISOtech'
|
||||
'loz': u'\u25CA', # lozenge, U+25CA ISOpub'
|
||||
'lrm': u'\u200E', # left-to-right mark, U+200E NEW RFC 2070'
|
||||
'lsaquo': u'\u2039', # single left-pointing angle quotation mark, U+2039 ISO proposed'
|
||||
'lsquo': u'\u2018', # left single quotation mark, U+2018 ISOnum'
|
||||
'lt': u'\u003C', # less-than sign, U+003C ISOnum'
|
||||
'macr': u'\u00AF', # macron = spacing macron = overline = APL overbar, U+00AF ISOdia'
|
||||
'mdash': u'\u2014', # em dash, U+2014 ISOpub'
|
||||
'micro': u'\u00B5', # micro sign, U+00B5 ISOnum'
|
||||
'middot': u'\u00B7', # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum'
|
||||
'minus': u'\u2212', # minus sign, U+2212 ISOtech'
|
||||
'mu': u'\u03BC', # greek small letter mu, U+03BC ISOgrk3'
|
||||
'nabla': u'\u2207', # nabla = backward difference, U+2207 ISOtech'
|
||||
'nbsp': u'\u00A0', # no-break space = non-breaking space, U+00A0 ISOnum'
|
||||
'ndash': u'\u2013', # en dash, U+2013 ISOpub'
|
||||
'ne': u'\u2260', # not equal to, U+2260 ISOtech'
|
||||
'ni': u'\u220B', # contains as member, U+220B ISOtech'
|
||||
'not': u'\u00AC', # not sign, U+00AC ISOnum'
|
||||
'notin': u'\u2209', # not an element of, U+2209 ISOtech'
|
||||
'nsub': u'\u2284', # not a subset of, U+2284 ISOamsn'
|
||||
'ntilde': u'\u00F1', # latin small letter n with tilde, U+00F1 ISOlat1'
|
||||
'nu': u'\u03BD', # greek small letter nu, U+03BD ISOgrk3'
|
||||
'oacute': u'\u00F3', # latin small letter o with acute, U+00F3 ISOlat1'
|
||||
'ocirc': u'\u00F4', # latin small letter o with circumflex, U+00F4 ISOlat1'
|
||||
'oelig': u'\u0153', # latin small ligature oe, U+0153 ISOlat2'
|
||||
'ograve': u'\u00F2', # latin small letter o with grave, U+00F2 ISOlat1'
|
||||
'oline': u'\u203E', # overline = spacing overscore, U+203E NEW'
|
||||
'omega': u'\u03C9', # greek small letter omega, U+03C9 ISOgrk3'
|
||||
'omicron': u'\u03BF', # greek small letter omicron, U+03BF NEW'
|
||||
'oplus': u'\u2295', # circled plus = direct sum, U+2295 ISOamsb'
|
||||
'or': u'\u2228', # logical or = vee, U+2228 ISOtech'
|
||||
'ordf': u'\u00AA', # feminine ordinal indicator, U+00AA ISOnum'
|
||||
'ordm': u'\u00BA', # masculine ordinal indicator, U+00BA ISOnum'
|
||||
'oslash': u'\u00F8', # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1'
|
||||
'otilde': u'\u00F5', # latin small letter o with tilde, U+00F5 ISOlat1'
|
||||
'otimes': u'\u2297', # circled times = vector product, U+2297 ISOamsb'
|
||||
'ouml': u'\u00F6', # latin small letter o with diaeresis, U+00F6 ISOlat1'
|
||||
'para': u'\u00B6', # pilcrow sign = paragraph sign, U+00B6 ISOnum'
|
||||
'part': u'\u2202', # partial differential, U+2202 ISOtech'
|
||||
'permil': u'\u2030', # per mille sign, U+2030 ISOtech'
|
||||
'perp': u'\u22A5', # up tack = orthogonal to = perpendicular, U+22A5 ISOtech'
|
||||
'phi': u'\u03C6', # greek small letter phi, U+03C6 ISOgrk3'
|
||||
'pi': u'\u03C0', # greek small letter pi, U+03C0 ISOgrk3'
|
||||
'piv': u'\u03D6', # greek pi symbol, U+03D6 ISOgrk3'
|
||||
'plusmn': u'\u00B1', # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum'
|
||||
'pound': u'\u00A3', # pound sign, U+00A3 ISOnum'
|
||||
'prime': u'\u2032', # prime = minutes = feet, U+2032 ISOtech'
|
||||
'prod': u'\u220F', # n-ary product = product sign, U+220F ISOamsb'
|
||||
'prop': u'\u221D', # proportional to, U+221D ISOtech'
|
||||
'psi': u'\u03C8', # greek small letter psi, U+03C8 ISOgrk3'
|
||||
'quot': u'\u0022', # quotation mark = APL quote, U+0022 ISOnum'
|
||||
'rArr': u'\u21D2', # rightwards double arrow, U+21D2 ISOtech'
|
||||
'radic': u'\u221A', # square root = radical sign, U+221A ISOtech'
|
||||
'rang': u'\u232A', # right-pointing angle bracket = ket, U+232A ISOtech'
|
||||
'raquo': u'\u00BB', # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum'
|
||||
'rarr': u'\u2192', # rightwards arrow, U+2192 ISOnum'
|
||||
'rceil': u'\u2309', # right ceiling, U+2309 ISOamsc'
|
||||
'rdquo': u'\u201D', # right double quotation mark, U+201D ISOnum'
|
||||
'real': u'\u211C', # blackletter capital R = real part symbol, U+211C ISOamso'
|
||||
'reg': u'\u00AE', # registered sign = registered trade mark sign, U+00AE ISOnum'
|
||||
'rfloor': u'\u230B', # right floor, U+230B ISOamsc'
|
||||
'rho': u'\u03C1', # greek small letter rho, U+03C1 ISOgrk3'
|
||||
'rlm': u'\u200F', # right-to-left mark, U+200F NEW RFC 2070'
|
||||
'rsaquo': u'\u203A', # single right-pointing angle quotation mark, U+203A ISO proposed'
|
||||
'rsquo': u'\u2019', # right single quotation mark, U+2019 ISOnum'
|
||||
'sbquo': u'\u201A', # single low-9 quotation mark, U+201A NEW'
|
||||
'scaron': u'\u0161', # latin small letter s with caron, U+0161 ISOlat2'
|
||||
'sdot': u'\u22C5', # dot operator, U+22C5 ISOamsb'
|
||||
'sect': u'\u00A7', # section sign, U+00A7 ISOnum'
|
||||
'shy': u'\u00AD', # soft hyphen = discretionary hyphen, U+00AD ISOnum'
|
||||
'sigma': u'\u03C3', # greek small letter sigma, U+03C3 ISOgrk3'
|
||||
'sigmaf': u'\u03C2', # greek small letter final sigma, U+03C2 ISOgrk3'
|
||||
'sim': u'\u223C', # tilde operator = varies with = similar to, U+223C ISOtech'
|
||||
'spades': u'\u2660', # black spade suit, U+2660 ISOpub'
|
||||
'sub': u'\u2282', # subset of, U+2282 ISOtech'
|
||||
'sube': u'\u2286', # subset of or equal to, U+2286 ISOtech'
|
||||
'sum': u'\u2211', # n-ary sumation, U+2211 ISOamsb'
|
||||
'sup': u'\u2283', # superset of, U+2283 ISOtech'
|
||||
'sup1': u'\u00B9', # superscript one = superscript digit one, U+00B9 ISOnum'
|
||||
'sup2': u'\u00B2', # superscript two = superscript digit two = squared, U+00B2 ISOnum'
|
||||
'sup3': u'\u00B3', # superscript three = superscript digit three = cubed, U+00B3 ISOnum'
|
||||
'supe': u'\u2287', # superset of or equal to, U+2287 ISOtech'
|
||||
'szlig': u'\u00DF', # latin small letter sharp s = ess-zed, U+00DF ISOlat1'
|
||||
'tau': u'\u03C4', # greek small letter tau, U+03C4 ISOgrk3'
|
||||
'there4': u'\u2234', # therefore, U+2234 ISOtech'
|
||||
'theta': u'\u03B8', # greek small letter theta, U+03B8 ISOgrk3'
|
||||
'thetasym': u'\u03D1', # greek small letter theta symbol, U+03D1 NEW'
|
||||
'thinsp': u'\u2009', # thin space, U+2009 ISOpub'
|
||||
'thorn': u'\u00FE', # latin small letter thorn with, U+00FE ISOlat1'
|
||||
'tilde': u'\u02DC', # small tilde, U+02DC ISOdia'
|
||||
'times': u'\u00D7', # multiplication sign, U+00D7 ISOnum'
|
||||
'trade': u'\u2122', # trade mark sign, U+2122 ISOnum'
|
||||
'uArr': u'\u21D1', # upwards double arrow, U+21D1 ISOamsa'
|
||||
'uacute': u'\u00FA', # latin small letter u with acute, U+00FA ISOlat1'
|
||||
'uarr': u'\u2191', # upwards arrow, U+2191 ISOnum'
|
||||
'ucirc': u'\u00FB', # latin small letter u with circumflex, U+00FB ISOlat1'
|
||||
'ugrave': u'\u00F9', # latin small letter u with grave, U+00F9 ISOlat1'
|
||||
'uml': u'\u00A8', # diaeresis = spacing diaeresis, U+00A8 ISOdia'
|
||||
'upsih': u'\u03D2', # greek upsilon with hook symbol, U+03D2 NEW'
|
||||
'upsilon': u'\u03C5', # greek small letter upsilon, U+03C5 ISOgrk3'
|
||||
'uuml': u'\u00FC', # latin small letter u with diaeresis, U+00FC ISOlat1'
|
||||
'weierp': u'\u2118', # script capital P = power set = Weierstrass p, U+2118 ISOamso'
|
||||
'xi': u'\u03BE', # greek small letter xi, U+03BE ISOgrk3'
|
||||
'yacute': u'\u00FD', # latin small letter y with acute, U+00FD ISOlat1'
|
||||
'yen': u'\u00A5', # yen sign = yuan sign, U+00A5 ISOnum'
|
||||
'yuml': u'\u00FF', # latin small letter y with diaeresis, U+00FF ISOlat1'
|
||||
'zeta': u'\u03B6', # greek small letter zeta, U+03B6 ISOgrk3'
|
||||
'zwj': u'\u200D', # zero width joiner, U+200D NEW RFC 2070'
|
||||
'zwnj': u'\u200C' # zero width non-joiner, U+200C NEW RFC 2070'
|
||||
}
|
||||
from core import filetools
|
||||
|
||||
entitydefs2 = {
|
||||
'$': '%24',
|
||||
@@ -328,7 +83,7 @@ def limpia_nombre_caracteres_especiales(s):
|
||||
def limpia_nombre_sin_acentos(s):
|
||||
if not s:
|
||||
return ''
|
||||
for key, value in entitydefs3.iteritems():
|
||||
for key, value in entitydefs3.items():
|
||||
for c in key:
|
||||
s = s.replace(c, value)
|
||||
return s
|
||||
@@ -337,15 +92,7 @@ def limpia_nombre_sin_acentos(s):
|
||||
def limpia_nombre_excepto_1(s):
|
||||
if not s:
|
||||
return ''
|
||||
|
||||
# Titulo de entrada
|
||||
'''
|
||||
try:
|
||||
logger.info("s1="+urllib.quote_plus(s))
|
||||
except:
|
||||
logger.info("s1=no printable")
|
||||
'''
|
||||
|
||||
# Convierte a unicode
|
||||
try:
|
||||
s = unicode(s, "utf-8")
|
||||
@@ -356,41 +103,13 @@ def limpia_nombre_excepto_1(s):
|
||||
except UnicodeError:
|
||||
# logger.info("no es iso-8859-1")
|
||||
pass
|
||||
'''
|
||||
try:
|
||||
logger.info("s2="+urllib.quote_plus(s))
|
||||
except:
|
||||
logger.info("s2=no printable")
|
||||
'''
|
||||
|
||||
# Elimina acentos
|
||||
s = limpia_nombre_sin_acentos(s)
|
||||
'''
|
||||
try:
|
||||
logger.info("s3="+urllib.quote_plus(s))
|
||||
except:
|
||||
logger.info("s3=no printable")
|
||||
'''
|
||||
|
||||
# Elimina caracteres prohibidos
|
||||
validchars = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!#$%&'()-@[]^_`{}~."
|
||||
stripped = ''.join(c for c in s if c in validchars)
|
||||
'''
|
||||
try:
|
||||
logger.info("s4="+urllib.quote_plus(stripped))
|
||||
except:
|
||||
logger.info("s4=no printable")
|
||||
'''
|
||||
|
||||
# Convierte a iso
|
||||
s = stripped.encode("iso-8859-1")
|
||||
'''
|
||||
try:
|
||||
logger.info("s5="+urllib.quote_plus(s))
|
||||
except:
|
||||
logger.info("s5=no printable")
|
||||
'''
|
||||
|
||||
return s
|
||||
|
||||
|
||||
@@ -410,7 +129,7 @@ def getfilefromtitle(url, title):
|
||||
logger.info("platform=" + plataforma)
|
||||
|
||||
# nombrefichero = xbmc.makeLegalFilename(title + url[-4:])
|
||||
import scrapertools
|
||||
from . import scrapertools
|
||||
|
||||
nombrefichero = title + scrapertools.get_filename_from_url(url)[-4:]
|
||||
logger.info("filename=%s" % nombrefichero)
|
||||
@@ -425,7 +144,7 @@ def getfilefromtitle(url, title):
|
||||
|
||||
logger.info("filename=%s" % nombrefichero)
|
||||
|
||||
fullpath = os.path.join(config.get_setting("downloadpath"), nombrefichero)
|
||||
fullpath = filetools.join(config.get_setting("downloadpath"), nombrefichero)
|
||||
logger.info("fullpath=%s" % fullpath)
|
||||
|
||||
if config.is_xbmc() and fullpath.startswith("special://"):
|
||||
@@ -465,7 +184,7 @@ def downloadbest(video_urls, title, continuar=False):
|
||||
try:
|
||||
ret = downloadfile(url, fullpath, continuar=continuar)
|
||||
# Llegados a este punto, normalmente es un timeout
|
||||
except urllib2.URLError, e:
|
||||
except urllib.error.URLError as e:
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
ret = -2
|
||||
@@ -475,11 +194,11 @@ def downloadbest(video_urls, title, continuar=False):
|
||||
return -1
|
||||
else:
|
||||
# El fichero ni siquiera existe
|
||||
if not os.path.exists(fullpath):
|
||||
if not filetools.exists(fullpath):
|
||||
logger.info("-> You have not downloaded anything, testing with the following option if there is")
|
||||
# El fichero existe
|
||||
else:
|
||||
tamanyo = os.path.getsize(fullpath)
|
||||
tamanyo = filetools.getsize(fullpath)
|
||||
|
||||
# Tiene tamaño 0
|
||||
if tamanyo == 0:
|
||||
@@ -519,15 +238,10 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
logger.info("filename=" + nombrefichero)
|
||||
|
||||
# El fichero existe y se quiere continuar
|
||||
if os.path.exists(nombrefichero) and continuar:
|
||||
# try:
|
||||
# import xbmcvfs
|
||||
# f = xbmcvfs.File(nombrefichero)
|
||||
# existSize = f.size(nombrefichero)
|
||||
# except:
|
||||
f = open(nombrefichero, 'r+b')
|
||||
if filetools.exists(nombrefichero) and continuar:
|
||||
f = filetools.file_open(nombrefichero, 'r+b', vfs=VFS)
|
||||
if resumir:
|
||||
exist_size = os.path.getsize(nombrefichero)
|
||||
exist_size = filetools.getsize(nombrefichero)
|
||||
logger.info("the file exists, size=%d" % exist_size)
|
||||
grabado = exist_size
|
||||
f.seek(exist_size)
|
||||
@@ -536,7 +250,7 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
grabado = 0
|
||||
|
||||
# el fichero ya existe y no se quiere continuar, se aborta
|
||||
elif os.path.exists(nombrefichero) and not continuar:
|
||||
elif filetools.exists(nombrefichero) and not continuar:
|
||||
logger.info("the file exists, it does not download again")
|
||||
return -3
|
||||
|
||||
@@ -545,11 +259,7 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
exist_size = 0
|
||||
logger.info("the file does not exist")
|
||||
|
||||
# try:
|
||||
# import xbmcvfs
|
||||
# f = xbmcvfs.File(nombrefichero,"w")
|
||||
# except:
|
||||
f = open(nombrefichero, 'wb')
|
||||
f = filetools.file_open(nombrefichero, 'wb', vfs=VFS)
|
||||
grabado = 0
|
||||
|
||||
# Crea el diálogo de progreso
|
||||
@@ -570,7 +280,7 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
for additional_header in additional_headers:
|
||||
logger.info("additional_header: " + additional_header)
|
||||
name = re.findall("(.*?)=.*?", additional_header)[0]
|
||||
value = urllib.unquote_plus(re.findall(".*?=(.*?)$", additional_header)[0])
|
||||
value = urllib.parse.unquote_plus(re.findall(".*?=(.*?)$", additional_header)[0])
|
||||
headers.append([name, value])
|
||||
|
||||
url = url.split("|")[0]
|
||||
@@ -579,8 +289,8 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
# Timeout del socket a 60 segundos
|
||||
socket.setdefaulttimeout(60)
|
||||
|
||||
h = urllib2.HTTPHandler(debuglevel=0)
|
||||
request = urllib2.Request(url)
|
||||
h = urllib.request.HTTPHandler(debuglevel=0)
|
||||
request = urllib.request.Request(url)
|
||||
for header in headers:
|
||||
logger.info("Header=" + header[0] + ": " + header[1])
|
||||
request.add_header(header[0], header[1])
|
||||
@@ -588,17 +298,13 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
if exist_size > 0:
|
||||
request.add_header('Range', 'bytes=%d-' % (exist_size,))
|
||||
|
||||
opener = urllib2.build_opener(h)
|
||||
urllib2.install_opener(opener)
|
||||
opener = urllib.request.build_opener(h)
|
||||
urllib.request.install_opener(opener)
|
||||
try:
|
||||
connexion = opener.open(request)
|
||||
except urllib2.HTTPError, e:
|
||||
except urllib.error.HTTPError as e:
|
||||
logger.error("error %d (%s) al abrir la url %s" %
|
||||
(e.code, e.msg, url))
|
||||
# print e.code
|
||||
# print e.msg
|
||||
# print e.hdrs
|
||||
# print e.fp
|
||||
f.close()
|
||||
if not silent:
|
||||
progreso.close()
|
||||
@@ -642,19 +348,16 @@ def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False
|
||||
bloqueleido = connexion.read(blocksize)
|
||||
after = time.time()
|
||||
if (after - before) > 0:
|
||||
velocidad = len(bloqueleido) / (after - before)
|
||||
velocidad = old_div(len(bloqueleido), (after - before))
|
||||
falta = totalfichero - grabado
|
||||
if velocidad > 0:
|
||||
tiempofalta = falta / velocidad
|
||||
tiempofalta = old_div(falta, velocidad)
|
||||
else:
|
||||
tiempofalta = 0
|
||||
# logger.info(sec_to_hms(tiempofalta))
|
||||
if not silent:
|
||||
# progreso.update( percent , "Descargando %.2fMB de %.2fMB (%d%%)" % ( descargadosmb ,
|
||||
# totalmb , percent),"Falta %s - Velocidad %.2f Kb/s" % ( sec_to_hms(tiempofalta) ,
|
||||
# velocidad/1024 ), os.path.basename(nombrefichero) )
|
||||
progreso.update(percent, "%.2fMB/%.2fMB (%d%%) %.2f Kb/s %s falta " %
|
||||
(descargadosmb, totalmb, percent, velocidad / 1024,
|
||||
(descargadosmb, totalmb, percent, old_div(velocidad, 1024),
|
||||
sec_to_hms(tiempofalta)))
|
||||
break
|
||||
except:
|
||||
@@ -737,7 +440,7 @@ def downloadfileRTMP(url, nombrefichero, silent):
|
||||
else:
|
||||
rtmpdump_cmd = "/usr/bin/rtmpdump"
|
||||
|
||||
if not os.path.isfile(rtmpdump_cmd) and not silent:
|
||||
if not filetools.isfile(rtmpdump_cmd) and not silent:
|
||||
from platformcode import platformtools
|
||||
advertencia = platformtools.dialog_ok("Falta " + rtmpdump_cmd, "Comprueba que rtmpdump está instalado")
|
||||
return True
|
||||
@@ -818,22 +521,18 @@ def downloadfileGzipped(url, pathfichero):
|
||||
# Timeout del socket a 60 segundos
|
||||
socket.setdefaulttimeout(10)
|
||||
|
||||
h = urllib2.HTTPHandler(debuglevel=0)
|
||||
request = urllib2.Request(url, txdata, txheaders)
|
||||
h = urllib.request.HTTPHandler(debuglevel=0)
|
||||
request = urllib.request.Request(url, txdata, txheaders)
|
||||
# if existSize > 0:
|
||||
# request.add_header('Range', 'bytes=%d-' % (existSize, ))
|
||||
|
||||
opener = urllib2.build_opener(h)
|
||||
urllib2.install_opener(opener)
|
||||
opener = urllib.request.build_opener(h)
|
||||
urllib.request.install_opener(opener)
|
||||
try:
|
||||
connexion = opener.open(request)
|
||||
except urllib2.HTTPError, e:
|
||||
except urllib.error.HTTPError as e:
|
||||
logger.error("error %d (%s) al abrir la url %s" %
|
||||
(e.code, e.msg, url))
|
||||
# print e.code
|
||||
# print e.msg
|
||||
# print e.hdrs
|
||||
# print e.fp
|
||||
progreso.close()
|
||||
# El error 416 es que el rango pedido es mayor que el fichero => es que ya está completo
|
||||
if e.code == 416:
|
||||
@@ -841,7 +540,7 @@ def downloadfileGzipped(url, pathfichero):
|
||||
else:
|
||||
return -2
|
||||
|
||||
nombre_fichero_base = os.path.basename(nombrefichero)
|
||||
nombre_fichero_base = filetools.basename(nombrefichero)
|
||||
if len(nombre_fichero_base) == 0:
|
||||
logger.info("Searching for name in the answer Headers")
|
||||
nombre_base = connexion.headers["Content-Disposition"]
|
||||
@@ -851,15 +550,15 @@ def downloadfileGzipped(url, pathfichero):
|
||||
if len(matches) > 0:
|
||||
titulo = matches[0]
|
||||
titulo = GetTitleFromFile(titulo)
|
||||
nombrefichero = os.path.join(pathfichero, titulo)
|
||||
nombrefichero = filetools.join(pathfichero, titulo)
|
||||
else:
|
||||
logger.info("Name of the file not found, Placing temporary name: no_name.txt")
|
||||
titulo = "no_name.txt"
|
||||
nombrefichero = os.path.join(pathfichero, titulo)
|
||||
nombrefichero = filetools.join(pathfichero, titulo)
|
||||
totalfichero = int(connexion.headers["Content-Length"])
|
||||
|
||||
# despues
|
||||
f = open(nombrefichero, 'w')
|
||||
f = filetools.file_open(nombrefichero, 'w', vfs=VFS)
|
||||
|
||||
logger.info("new file open")
|
||||
|
||||
@@ -871,8 +570,8 @@ def downloadfileGzipped(url, pathfichero):
|
||||
bloqueleido = connexion.read(blocksize)
|
||||
|
||||
try:
|
||||
import StringIO
|
||||
compressedstream = StringIO.StringIO(bloqueleido)
|
||||
import io
|
||||
compressedstream = io.StringIO(bloqueleido)
|
||||
import gzip
|
||||
gzipper = gzip.GzipFile(fileobj=compressedstream)
|
||||
bloquedata = gzipper.read()
|
||||
@@ -903,26 +602,26 @@ def downloadfileGzipped(url, pathfichero):
|
||||
bloqueleido = connexion.read(blocksize)
|
||||
|
||||
import gzip
|
||||
import StringIO
|
||||
compressedstream = StringIO.StringIO(bloqueleido)
|
||||
import io
|
||||
compressedstream = io.StringIO(bloqueleido)
|
||||
gzipper = gzip.GzipFile(fileobj=compressedstream)
|
||||
bloquedata = gzipper.read()
|
||||
gzipper.close()
|
||||
after = time.time()
|
||||
if (after - before) > 0:
|
||||
velocidad = len(bloqueleido) / (after - before)
|
||||
velocidad = old_div(len(bloqueleido), (after - before))
|
||||
falta = totalfichero - grabado
|
||||
if velocidad > 0:
|
||||
tiempofalta = falta / velocidad
|
||||
tiempofalta = old_div(falta, velocidad)
|
||||
else:
|
||||
tiempofalta = 0
|
||||
logger.info(sec_to_hms(tiempofalta))
|
||||
progreso.update(percent, "%.2fMB/%.2fMB (%d%%) %.2f Kb/s %s falta " %
|
||||
(descargadosmb, totalmb, percent, velocidad / 1024, sec_to_hms(tiempofalta)))
|
||||
(descargadosmb, totalmb, percent, old_div(velocidad, 1024), sec_to_hms(tiempofalta)))
|
||||
break
|
||||
except:
|
||||
reintentos += 1
|
||||
logger.info("ERROR in block download, retry %d" % reintentos)
|
||||
logger.info("ERROR in block download, retry %dd" % reintentos)
|
||||
for line in sys.exc_info():
|
||||
logger.error("%s" % line)
|
||||
|
||||
@@ -983,7 +682,7 @@ def downloadIfNotModifiedSince(url, timestamp):
|
||||
|
||||
# Comprueba si ha cambiado
|
||||
inicio = time.clock()
|
||||
req = urllib2.Request(url)
|
||||
req = urllib.request.Request(url)
|
||||
req.add_header('If-Modified-Since', fecha_formateada)
|
||||
req.add_header('User-Agent',
|
||||
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12')
|
||||
@@ -991,16 +690,14 @@ def downloadIfNotModifiedSince(url, timestamp):
|
||||
updated = False
|
||||
|
||||
try:
|
||||
response = urllib2.urlopen(req)
|
||||
response = urllib.request.urlopen(req)
|
||||
data = response.read()
|
||||
# info = response.info()
|
||||
# logger.info( info.headers )
|
||||
|
||||
# Si llega hasta aquí, es que ha cambiado
|
||||
updated = True
|
||||
response.close()
|
||||
|
||||
except urllib2.URLError, e:
|
||||
except urllib.error.URLError as e:
|
||||
# Si devuelve 304 es que no ha cambiado
|
||||
if hasattr(e, 'code'):
|
||||
logger.info("HTTP response code: %d" % e.code)
|
||||
@@ -1072,7 +769,7 @@ def download_all_episodes(item, channel, first_episode="", preferred_server="vid
|
||||
mirrors_itemlist = channel.findvideos(episode_item)
|
||||
except:
|
||||
mirrors_itemlist = servertools.find_video_items(episode_item)
|
||||
print mirrors_itemlist
|
||||
print(mirrors_itemlist)
|
||||
|
||||
descargado = False
|
||||
|
||||
@@ -1188,7 +885,7 @@ def download_all_episodes(item, channel, first_episode="", preferred_server="vid
|
||||
|
||||
|
||||
def episodio_ya_descargado(show_title, episode_title):
|
||||
import scrapertools
|
||||
from . import scrapertools
|
||||
ficheros = os.listdir(".")
|
||||
|
||||
for fichero in ficheros:
|
||||
|
||||
+322
-85
@@ -1,20 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ------------------------------------------------------------
|
||||
# filetools
|
||||
# Gestion de archivos con discriminación samba/local
|
||||
# Gestion de archivos con discriminación xbmcvfs/samba/local
|
||||
# ------------------------------------------------------------
|
||||
|
||||
from __future__ import division
|
||||
#from builtins import str
|
||||
from future.builtins import range
|
||||
from past.utils import old_div
|
||||
import sys
|
||||
PY3 = False
|
||||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||||
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from core import scrapertools
|
||||
from platformcode import platformtools, logger
|
||||
|
||||
try:
|
||||
from lib.sambatools import libsmb as samba
|
||||
except:
|
||||
samba = None
|
||||
# Python 2.4 No compatible con modulo samba, hay que revisar
|
||||
xbmc_vfs = True # False para desactivar XbmcVFS, True para activar
|
||||
if xbmc_vfs:
|
||||
try:
|
||||
import xbmcvfs
|
||||
if not PY3:
|
||||
reload(sys) ### Workoround. Revisar en la migración a Python 3
|
||||
sys.setdefaultencoding('utf-8') # xbmcvfs degrada el valor de defaultencoding. Se reestablece
|
||||
xbmc_vfs = True
|
||||
except:
|
||||
xbmc_vfs = False
|
||||
|
||||
samba = None
|
||||
if not xbmc_vfs:
|
||||
try:
|
||||
from lib.sambatools import libsmb as samba
|
||||
except:
|
||||
samba = None
|
||||
# Python 2.4 No compatible con modulo samba, hay que revisar
|
||||
|
||||
# Windows es "mbcs" linux, osx, android es "utf8"
|
||||
if os.name == "nt":
|
||||
@@ -23,6 +44,7 @@ else:
|
||||
fs_encoding = "utf8"
|
||||
|
||||
|
||||
|
||||
def validate_path(path):
|
||||
"""
|
||||
Elimina cáracteres no permitidos
|
||||
@@ -32,10 +54,11 @@ def validate_path(path):
|
||||
@return: devuelve la cadena sin los caracteres no permitidos
|
||||
"""
|
||||
chars = ":*?<>|"
|
||||
if path.lower().startswith("smb://"):
|
||||
if scrapertools.find_single_match(path, '(^\w+:\/\/)'):
|
||||
protocolo = scrapertools.find_single_match(path, '(^\w+:\/\/)')
|
||||
import re
|
||||
parts = re.split(r'smb://(.+?)/(.+)', path)[1:3]
|
||||
return "smb://" + parts[0] + "/" + ''.join([c for c in parts[1] if c not in chars])
|
||||
parts = re.split(r'^\w+:\/\/(.+?)/(.+)', path)[1:3]
|
||||
return protocolo + parts[0] + "/" + ''.join([c for c in parts[1] if c not in chars])
|
||||
|
||||
else:
|
||||
if path.find(":\\") == 1:
|
||||
@@ -58,10 +81,10 @@ def encode(path, _samba=False):
|
||||
@rtype: str
|
||||
@return ruta codificada en juego de caracteres del sistema o utf-8 si samba
|
||||
"""
|
||||
if not type(path) == unicode:
|
||||
if not isinstance(path, unicode):
|
||||
path = unicode(path, "utf-8", "ignore")
|
||||
|
||||
if path.lower().startswith("smb://") or _samba:
|
||||
if scrapertools.find_single_match(path, '(^\w+:\/\/)') or _samba:
|
||||
path = path.encode("utf-8", "ignore")
|
||||
else:
|
||||
if fs_encoding:
|
||||
@@ -79,19 +102,19 @@ def decode(path):
|
||||
@rtype: str
|
||||
@return: ruta codificado en UTF-8
|
||||
"""
|
||||
if type(path) == list:
|
||||
if isinstance(path, list):
|
||||
for x in range(len(path)):
|
||||
if not type(path[x]) == unicode:
|
||||
if not isinstance(path[x], unicode):
|
||||
path[x] = path[x].decode(fs_encoding, "ignore")
|
||||
path[x] = path[x].encode("utf-8", "ignore")
|
||||
else:
|
||||
if not type(path) == unicode:
|
||||
if not isinstance(path, unicode):
|
||||
path = path.decode(fs_encoding, "ignore")
|
||||
path = path.encode("utf-8", "ignore")
|
||||
return path
|
||||
|
||||
|
||||
def read(path, linea_inicio=0, total_lineas=None):
|
||||
def read(path, linea_inicio=0, total_lineas=None, whence=0, silent=False, vfs=True):
|
||||
"""
|
||||
Lee el contenido de un archivo y devuelve los datos
|
||||
@param path: ruta del fichero
|
||||
@@ -106,7 +129,34 @@ def read(path, linea_inicio=0, total_lineas=None):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if not isinstance(linea_inicio, int):
|
||||
try:
|
||||
linea_inicio = int(linea_inicio)
|
||||
except:
|
||||
logger.error('Read: ERROR de linea_inicio: %s' % str(linea_inicio))
|
||||
linea_inicio = 0
|
||||
if total_lineas != None and not isinstance(total_lineas, int):
|
||||
try:
|
||||
total_lineas = int(total_lineas)
|
||||
except:
|
||||
logger.error('Read: ERROR de total_lineas: %s' % str(total_lineas))
|
||||
total_lineas = None
|
||||
if xbmc_vfs and vfs:
|
||||
if not exists(path): return False
|
||||
f = xbmcvfs.File(path, "rb")
|
||||
if linea_inicio > 0:
|
||||
if not isinstance(whence, int):
|
||||
try:
|
||||
whence = int(whence)
|
||||
except:
|
||||
return False
|
||||
f.seek(linea_inicio, whence)
|
||||
logger.debug('POSICIÓN de comienzo de lectura, tell(): %s' % f.seek(0, 1))
|
||||
if total_lineas == None:
|
||||
total_lineas = 0
|
||||
data = f.read(total_lineas)
|
||||
return "".join(data)
|
||||
elif path.lower().startswith("smb://"):
|
||||
f = samba.smb_open(path, "rb")
|
||||
else:
|
||||
f = open(path, "rb")
|
||||
@@ -118,15 +168,19 @@ def read(path, linea_inicio=0, total_lineas=None):
|
||||
data.append(line)
|
||||
f.close()
|
||||
except:
|
||||
logger.error("ERROR al leer el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error("ERROR al leer el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
else:
|
||||
return "".join(data)
|
||||
if not PY3:
|
||||
return "".join(data)
|
||||
else:
|
||||
return b"".join(data)
|
||||
|
||||
|
||||
def write(path, data):
|
||||
def write(path, data, mode="wb", silent=False, vfs=True):
|
||||
"""
|
||||
Guarda los datos en un archivo
|
||||
@param path: ruta del archivo a guardar
|
||||
@@ -138,22 +192,28 @@ def write(path, data):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
f = samba.smb_open(path, "wb")
|
||||
if xbmc_vfs and vfs:
|
||||
f = xbmcvfs.File(path, mode)
|
||||
result = f.write(data)
|
||||
f.close()
|
||||
return bool(result)
|
||||
elif path.lower().startswith("smb://"):
|
||||
f = samba.smb_open(path, mode)
|
||||
else:
|
||||
f = open(path, "wb")
|
||||
f = open(path, mode)
|
||||
|
||||
f.write(data)
|
||||
f.close()
|
||||
except:
|
||||
logger.error("ERROR al guardar el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def file_open(path, mode="r"):
|
||||
def file_open(path, mode="r", silent=False, vfs=True):
|
||||
"""
|
||||
Abre un archivo
|
||||
@param path: ruta
|
||||
@@ -163,18 +223,48 @@ def file_open(path, mode="r"):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if 'r' in mode and '+' in mode:
|
||||
mode = mode.replace('r', 'w').replace('+', '')
|
||||
logger.debug('Open MODE cambiado a: %s' % mode)
|
||||
if 'a' in mode:
|
||||
mode = mode.replace('a', 'w').replace('+', '')
|
||||
logger.debug('Open MODE cambiado a: %s' % mode)
|
||||
return xbmcvfs.File(path, mode)
|
||||
elif path.lower().startswith("smb://"):
|
||||
return samba.smb_open(path, mode)
|
||||
else:
|
||||
return open(path, mode)
|
||||
except:
|
||||
logger.error("ERROR al abrir el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al abrir", path)
|
||||
logger.error("ERROR al abrir el archivo: %s, %s" % (path, mode))
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al abrir", path)
|
||||
return False
|
||||
|
||||
|
||||
def rename(path, new_name):
|
||||
def file_stat(path, silent=False, vfs=True):
|
||||
"""
|
||||
Stat de un archivo
|
||||
@param path: ruta
|
||||
@type path: str
|
||||
@rtype: str
|
||||
@return: objeto file
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if xbmc_vfs and vfs:
|
||||
if not exists(path): return False
|
||||
return xbmcvfs.Stat(path)
|
||||
raise
|
||||
except:
|
||||
logger.error("File_Stat no soportado: %s" % path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def rename(path, new_name, silent=False, strict=False, vfs=True):
|
||||
"""
|
||||
Renombra un archivo o carpeta
|
||||
@param path: ruta del fichero o carpeta a renombrar
|
||||
@@ -186,7 +276,22 @@ def rename(path, new_name):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
path_end = path
|
||||
if path_end.endswith('/') or path_end.endswith('\\'):
|
||||
path_end = path_end[:-1]
|
||||
dest = encode(join(dirname(path_end), new_name))
|
||||
result = xbmcvfs.rename(path, dest)
|
||||
if not result and not strict:
|
||||
logger.error("ERROR al RENOMBRAR el archivo: %s. Copiando y borrando" % path)
|
||||
if not silent:
|
||||
dialogo = platformtools.dialog_progress("Copiando archivo", "")
|
||||
result = xbmcvfs.copy(path, dest)
|
||||
if not result:
|
||||
return False
|
||||
xbmcvfs.delete(path)
|
||||
return bool(result)
|
||||
elif path.lower().startswith("smb://"):
|
||||
new_name = encode(new_name, True)
|
||||
samba.rename(path, join(dirname(path), new_name))
|
||||
else:
|
||||
@@ -194,14 +299,15 @@ def rename(path, new_name):
|
||||
os.rename(path, os.path.join(os.path.dirname(path), new_name))
|
||||
except:
|
||||
logger.error("ERROR al renombrar el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al renombrar", path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al renombrar", path)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def move(path, dest):
|
||||
def move(path, dest, silent=False, strict=False, vfs=True):
|
||||
"""
|
||||
Mueve un archivo
|
||||
@param path: ruta del fichero a mover
|
||||
@@ -212,8 +318,22 @@ def move(path, dest):
|
||||
@return: devuelve False en caso de error
|
||||
"""
|
||||
try:
|
||||
if xbmc_vfs and vfs:
|
||||
if not exists(path): return False
|
||||
path = encode(path)
|
||||
dest = encode(dest)
|
||||
result = xbmcvfs.rename(path, dest)
|
||||
if not result and not strict:
|
||||
logger.error("ERROR al MOVER el archivo: %s. Copiando y borrando" % path)
|
||||
if not silent:
|
||||
dialogo = platformtools.dialog_progress("Copiando archivo", "")
|
||||
result = xbmcvfs.copy(path, dest)
|
||||
if not result:
|
||||
return False
|
||||
xbmcvfs.delete(path)
|
||||
return bool(result)
|
||||
# samba/samba
|
||||
if path.lower().startswith("smb://") and dest.lower().startswith("smb://"):
|
||||
elif path.lower().startswith("smb://") and dest.lower().startswith("smb://"):
|
||||
dest = encode(dest, True)
|
||||
path = encode(path, True)
|
||||
samba.rename(path, dest)
|
||||
@@ -225,15 +345,19 @@ def move(path, dest):
|
||||
os.rename(path, dest)
|
||||
# mixto En este caso se copia el archivo y luego se elimina el de origen
|
||||
else:
|
||||
if not silent:
|
||||
dialogo = platformtools.dialog_progress("Copiando archivo", "")
|
||||
return copy(path, dest) == True and remove(path) == True
|
||||
except:
|
||||
logger.error("ERROR al mover el archivo: %s" % path)
|
||||
logger.error("ERROR al mover el archivo: %s a %s" % (path, dest))
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def copy(path, dest, silent=False):
|
||||
def copy(path, dest, silent=False, vfs=True):
|
||||
"""
|
||||
Copia un archivo
|
||||
@param path: ruta del fichero a copiar
|
||||
@@ -246,6 +370,13 @@ def copy(path, dest, silent=False):
|
||||
@return: devuelve False en caso de error
|
||||
"""
|
||||
try:
|
||||
if xbmc_vfs and vfs:
|
||||
path = encode(path)
|
||||
dest = encode(dest)
|
||||
if not silent:
|
||||
dialogo = platformtools.dialog_progress("Copiando archivo", "")
|
||||
return bool(xbmcvfs.copy(path, dest))
|
||||
|
||||
fo = file_open(path, "rb")
|
||||
fd = file_open(dest, "wb")
|
||||
if fo and fd:
|
||||
@@ -255,7 +386,7 @@ def copy(path, dest, silent=False):
|
||||
copiado = 0
|
||||
while True:
|
||||
if not silent:
|
||||
dialogo.update(copiado * 100 / size, basename(path))
|
||||
dialogo.update(old_div(copiado * 100, size), basename(path))
|
||||
buf = fo.read(1024 * 1024)
|
||||
if not buf:
|
||||
break
|
||||
@@ -268,13 +399,14 @@ def copy(path, dest, silent=False):
|
||||
dialogo.close()
|
||||
except:
|
||||
logger.error("ERROR al copiar el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def exists(path):
|
||||
def exists(path, silent=False, vfs=True):
|
||||
"""
|
||||
Comprueba si existe una carpeta o fichero
|
||||
@param path: ruta
|
||||
@@ -284,17 +416,23 @@ def exists(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
result = bool(xbmcvfs.exists(path))
|
||||
if not result and not path.endswith('/') and not path.endswith('\\'):
|
||||
result = bool(xbmcvfs.exists(join(path, ' ').rstrip()))
|
||||
return result
|
||||
elif path.lower().startswith("smb://"):
|
||||
return samba.exists(path)
|
||||
else:
|
||||
return os.path.exists(path)
|
||||
except:
|
||||
logger.error("ERROR al comprobar la ruta: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def isfile(path):
|
||||
def isfile(path, silent=False, vfs=True):
|
||||
"""
|
||||
Comprueba si la ruta es un fichero
|
||||
@param path: ruta
|
||||
@@ -304,17 +442,29 @@ def isfile(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not scrapertools.find_single_match(path, '(^\w+:\/\/)'):
|
||||
return os.path.isfile(path)
|
||||
if path.endswith('/') or path.endswith('\\'):
|
||||
path = path[:-1]
|
||||
dirs, files = xbmcvfs.listdir(dirname(path))
|
||||
base_name = basename(path)
|
||||
for file in files:
|
||||
if base_name == file:
|
||||
return True
|
||||
return False
|
||||
elif path.lower().startswith("smb://"):
|
||||
return samba.isfile(path)
|
||||
else:
|
||||
return os.path.isfile(path)
|
||||
except:
|
||||
logger.error("ERROR al comprobar el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def isdir(path):
|
||||
def isdir(path, silent=False, vfs=True):
|
||||
"""
|
||||
Comprueba si la ruta es un directorio
|
||||
@param path: ruta
|
||||
@@ -324,17 +474,29 @@ def isdir(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not scrapertools.find_single_match(path, '(^\w+:\/\/)'):
|
||||
return os.path.isdir(path)
|
||||
if path.endswith('/') or path.endswith('\\'):
|
||||
path = path[:-1]
|
||||
dirs, files = xbmcvfs.listdir(dirname(path))
|
||||
base_name = basename(path)
|
||||
for dir in dirs:
|
||||
if base_name == dir:
|
||||
return True
|
||||
return False
|
||||
elif path.lower().startswith("smb://"):
|
||||
return samba.isdir(path)
|
||||
else:
|
||||
return os.path.isdir(path)
|
||||
except:
|
||||
logger.error("ERROR al comprobar el directorio: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def getsize(path):
|
||||
def getsize(path, silent=False, vfs=True):
|
||||
"""
|
||||
Obtiene el tamaño de un archivo
|
||||
@param path: ruta del fichero
|
||||
@@ -344,17 +506,24 @@ def getsize(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not exists(path): return long(0)
|
||||
f = xbmcvfs.File(path)
|
||||
s = f.size()
|
||||
f.close()
|
||||
return s
|
||||
elif path.lower().startswith("smb://"):
|
||||
return long(samba.get_attributes(path).file_size)
|
||||
else:
|
||||
return os.path.getsize(path)
|
||||
except:
|
||||
logger.error("ERROR al obtener el tamaño: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
return 0L
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return long(0)
|
||||
|
||||
|
||||
def remove(path):
|
||||
def remove(path, silent=False, vfs=True):
|
||||
"""
|
||||
Elimina un archivo
|
||||
@param path: ruta del fichero a eliminar
|
||||
@@ -364,20 +533,23 @@ def remove(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
return bool(xbmcvfs.delete(path))
|
||||
elif path.lower().startswith("smb://"):
|
||||
samba.remove(path)
|
||||
else:
|
||||
os.remove(path)
|
||||
except:
|
||||
logger.error("ERROR al eliminar el archivo: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el archivo", path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el archivo", path)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def rmdirtree(path):
|
||||
def rmdirtree(path, silent=False, vfs=True):
|
||||
"""
|
||||
Elimina un directorio y su contenido
|
||||
@param path: ruta a eliminar
|
||||
@@ -387,7 +559,17 @@ def rmdirtree(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not exists(path): return True
|
||||
if not path.endswith('/') and not path.endswith('\\'):
|
||||
path = join(path, ' ').rstrip()
|
||||
for raiz, subcarpetas, ficheros in walk(path, topdown=False):
|
||||
for f in ficheros:
|
||||
xbmcvfs.delete(join(raiz, f))
|
||||
for s in subcarpetas:
|
||||
xbmcvfs.rmdir(join(raiz, s))
|
||||
xbmcvfs.rmdir(path)
|
||||
elif path.lower().startswith("smb://"):
|
||||
for raiz, subcarpetas, ficheros in samba.walk(path, topdown=False):
|
||||
for f in ficheros:
|
||||
samba.remove(join(decode(raiz), decode(f)))
|
||||
@@ -399,14 +581,15 @@ def rmdirtree(path):
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
except:
|
||||
logger.error("ERROR al eliminar el directorio: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el directorio", path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el directorio", path)
|
||||
return False
|
||||
else:
|
||||
return not exists(path)
|
||||
|
||||
|
||||
def rmdir(path):
|
||||
def rmdir(path, silent=False, vfs=True):
|
||||
"""
|
||||
Elimina un directorio
|
||||
@param path: ruta a eliminar
|
||||
@@ -416,20 +599,25 @@ def rmdir(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not path.endswith('/') and not path.endswith('\\'):
|
||||
path = join(path, ' ').rstrip()
|
||||
return bool(xbmcvfs.rmdir(path))
|
||||
elif path.lower().startswith("smb://"):
|
||||
samba.rmdir(path)
|
||||
else:
|
||||
os.rmdir(path)
|
||||
except:
|
||||
logger.error("ERROR al eliminar el directorio: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el directorio", path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al eliminar el directorio", path)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
def mkdir(path, silent=False, vfs=True):
|
||||
"""
|
||||
Crea un directorio
|
||||
@param path: ruta a crear
|
||||
@@ -439,20 +627,30 @@ def mkdir(path):
|
||||
"""
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
if not path.endswith('/') and not path.endswith('\\'):
|
||||
path = join(path, ' ').rstrip()
|
||||
result = bool(xbmcvfs.mkdirs(path))
|
||||
if not result:
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
result = exists(path)
|
||||
return result
|
||||
elif path.lower().startswith("smb://"):
|
||||
samba.mkdir(path)
|
||||
else:
|
||||
os.mkdir(path)
|
||||
except:
|
||||
logger.error("ERROR al crear el directorio: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al crear el directorio", path)
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
platformtools.dialog_notification("Error al crear el directorio", path)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def walk(top, topdown=True, onerror=None):
|
||||
def walk(top, topdown=True, onerror=None, vfs=True):
|
||||
"""
|
||||
Lista un directorio de manera recursiva
|
||||
@param top: Directorio a listar, debe ser un str "UTF-8"
|
||||
@@ -464,7 +662,12 @@ def walk(top, topdown=True, onerror=None):
|
||||
***El parametro followlinks que por defecto es True, no se usa aqui, ya que en samba no discrimina los links
|
||||
"""
|
||||
top = encode(top)
|
||||
if top.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
for a, b, c in walk_vfs(top, topdown, onerror):
|
||||
# list(b) es para que haga una copia del listado de directorios
|
||||
# si no da error cuando tiene que entrar recursivamente en directorios con caracteres especiales
|
||||
yield a, list(b), c
|
||||
elif top.lower().startswith("smb://"):
|
||||
for a, b, c in samba.walk(top, topdown, onerror):
|
||||
# list(b) es para que haga una copia del listado de directorios
|
||||
# si no da error cuando tiene que entrar recursivamente en directorios con caracteres especiales
|
||||
@@ -476,7 +679,33 @@ def walk(top, topdown=True, onerror=None):
|
||||
yield decode(a), decode(list(b)), decode(c)
|
||||
|
||||
|
||||
def listdir(path):
|
||||
def walk_vfs(top, topdown=True, onerror=None):
|
||||
"""
|
||||
Lista un directorio de manera recursiva
|
||||
Como xmbcvfs no tiene esta función, se copia la lógica de libsmb(samba) para realizar la previa al Walk
|
||||
"""
|
||||
top = encode(top)
|
||||
dirs, nondirs = xbmcvfs.listdir(top)
|
||||
|
||||
if topdown:
|
||||
yield top, dirs, nondirs
|
||||
|
||||
for name in dirs:
|
||||
if isinstance(name, unicode):
|
||||
name = name.encode("utf8")
|
||||
if PY3: name = name.decode("utf8")
|
||||
elif PY3 and isinstance(name, bytes):
|
||||
name = name.decode("utf8")
|
||||
elif not PY3:
|
||||
name = unicode(name, "utf8")
|
||||
new_path = "/".join(top.split("/") + [name])
|
||||
for x in walk_vfs(new_path, topdown, onerror):
|
||||
yield x
|
||||
if not topdown:
|
||||
yield top, dirs, nondirs
|
||||
|
||||
|
||||
def listdir(path, silent=False, vfs=True):
|
||||
"""
|
||||
Lista un directorio
|
||||
@param path: Directorio a listar, debe ser un str "UTF-8"
|
||||
@@ -487,13 +716,17 @@ def listdir(path):
|
||||
|
||||
path = encode(path)
|
||||
try:
|
||||
if path.lower().startswith("smb://"):
|
||||
if xbmc_vfs and vfs:
|
||||
dirs, files = xbmcvfs.listdir(path)
|
||||
return dirs + files
|
||||
elif path.lower().startswith("smb://"):
|
||||
return decode(samba.listdir(path))
|
||||
else:
|
||||
return decode(os.listdir(path))
|
||||
except:
|
||||
logger.error("ERROR al leer el directorio: %s" % path)
|
||||
logger.error(traceback.format_exc())
|
||||
if not silent:
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
@@ -510,15 +743,17 @@ def join(*paths):
|
||||
|
||||
for path in paths:
|
||||
if path:
|
||||
if xbmc_vfs:
|
||||
path = encode(path)
|
||||
list_path += path.replace("\\", "/").strip("/").split("/")
|
||||
|
||||
if list_path[0].lower() == "smb:":
|
||||
return "/".join(list_path)
|
||||
if scrapertools.find_single_match(paths[0], '(^\w+:\/\/)'):
|
||||
return str("/".join(list_path))
|
||||
else:
|
||||
return os.sep.join(list_path)
|
||||
return str(os.sep.join(list_path))
|
||||
|
||||
|
||||
def split(path):
|
||||
def split(path, vfs=True):
|
||||
"""
|
||||
Devuelve una tupla formada por el directorio y el nombre del fichero de una ruta
|
||||
@param path: ruta
|
||||
@@ -526,15 +761,16 @@ def split(path):
|
||||
@return: (dirname, basename)
|
||||
@rtype: tuple
|
||||
"""
|
||||
if path.lower().startswith("smb://"):
|
||||
if scrapertools.find_single_match(path, '(^\w+:\/\/)'):
|
||||
protocol = scrapertools.find_single_match(path, '(^\w+:\/\/)')
|
||||
if '/' not in path[6:]:
|
||||
path = path.replace("smb://", "smb:///", 1)
|
||||
path = path.replace(protocol, protocol + "/", 1)
|
||||
return path.rsplit('/', 1)
|
||||
else:
|
||||
return os.path.split(path)
|
||||
|
||||
|
||||
def basename(path):
|
||||
def basename(path, vfs=True):
|
||||
"""
|
||||
Devuelve el nombre del fichero de una ruta
|
||||
@param path: ruta
|
||||
@@ -545,7 +781,7 @@ def basename(path):
|
||||
return split(path)[1]
|
||||
|
||||
|
||||
def dirname(path):
|
||||
def dirname(path, vfs=True):
|
||||
"""
|
||||
Devuelve el directorio de una ruta
|
||||
@param path: ruta
|
||||
@@ -588,12 +824,13 @@ def remove_smb_credential(path):
|
||||
"""
|
||||
logger.info()
|
||||
|
||||
if not path.startswith("smb://"):
|
||||
if not scrapertools.find_single_match(path, '(^\w+:\/\/)'):
|
||||
return path
|
||||
|
||||
path_without_credentials = scrapertools.find_single_match(path, '^smb:\/\/(?:[^;\n]+;)?(?:[^:@\n]+[:|@])?(?:[^@\n]+@)?(.*?$)')
|
||||
|
||||
protocol = scrapertools.find_single_match(path, '(^\w+:\/\/)')
|
||||
path_without_credentials = scrapertools.find_single_match(path, '^\w+:\/\/(?:[^;\n]+;)?(?:[^:@\n]+[:|@])?(?:[^@\n]+@)?(.*?$)')
|
||||
|
||||
if path_without_credentials:
|
||||
return ('smb://' + path_without_credentials)
|
||||
return (protocol + path_without_credentials)
|
||||
else:
|
||||
return path
|
||||
|
||||
Reference in New Issue
Block a user