def download_video(video_url):
    """Callback function of the 'Download' context menu

    Args:
        video_url (str): URL of the video to download
    """

    #  print('URL Video to download ' + video_url)

    #  Now that we have video URL we can try to download this one
    YDStreamUtils = __import__('YDStreamUtils')
    YDStreamExtractor = __import__('YDStreamExtractor')

    vid = YDStreamExtractor.getVideoInfo(
        video_url,
        quality=get_quality_YTDL(download_mode=True),
        resolve_redirects=True)

    if vid is None:
        Script.log(
            'YDStreamExtractor.getVideoInfo() failed for video URL: %s' %
            video_url)
        return False

    path = Script.setting.get_string('dl_folder')
    download_ok = False
    with YDStreamUtils.DownloadProgress() as prog:
        try:
            YDStreamExtractor.setOutputCallback(prog)
            result = YDStreamExtractor.handleDownload(
                vid, bg=Script.setting.get_boolean('dl_background'), path=path)
            if result:
                if result.status == 'canceled':
                    error_message = result.message
                    Script.log('Download failed: %s' % error_message)
                else:
                    full_path_to_file = result.filepath
                    Script.log('Download success: %s' % full_path_to_file)
                    download_ok = True

        finally:
            YDStreamExtractor.setOutputCallback(None)

    if path != '' and \
            Script.setting.get_boolean('dl_item_filename') and \
            download_ok:

        try:
            filename = os.path.basename(full_path_to_file)
            _, file_extension = os.path.splitext(full_path_to_file)
            current_filepath = os.path.join(path, filename)
            video_name = get_selected_item_label()
            final_filepath = os.path.join(path, video_name + file_extension)
            xbmcvfs.rename(current_filepath, final_filepath)
        except Exception:
            Script.log('Failed to rename video file')

    return False
Пример #2
0
    def rename(path, newpath):
        log("FileAccess: rename " + path + " to " + newpath)

        try:
            if xbmcvfs.rename(path, newpath):
                return True
        except Exception as e: 
            log("FileAccess: rename, Failed! %s"%(e), xbmc.LOGERROR)

        if path[0:6].lower() == 'smb://' or newpath[0:6].lower() == 'smb://':
            if os.name.lower() == 'nt':
                log("FileAccess: Modifying name")
                if path[0:6].lower() == 'smb://':
                    path = '\\\\' + path[6:]

                if newpath[0:6].lower() == 'smb://':
                    newpath = '\\\\' + newpath[6:]

        try:
            log("FileAccess: os.rename")
            os.rename(xbmcvfs.translatePath(path), xbmcvfs.translatePath(newpath))
            return True
        except Exception as e: 
            log("FileAccess: rename, Failed! %s"%(e), xbmc.LOGERROR)

        try:
            log("FileAccess: shutil.move")
            shutil.move(xbmcvfs.translatePath(path), xbmcvfs.translatePath(newpath))
            return True
        except Exception as e: 
            log("FileAccess: rename, Failed! %s"%(e), xbmc.LOGERROR)

        log("FileAccess: OSError")
        raise OSError()
Пример #3
0
def downloadVideo(title, vid):
    global downloadDir
    if not downloadDir:
        xbmcgui.Dialog().notification('Download:', translation(30110), _icon,
                                      5000, False)
        return
    url, hstr = getStreamUrl(vid).split('|')
    if six.PY2:
        vidfile = xbmc.makeLegalFilename(
            (downloadDir + title.decode('utf-8') + '.mp4').encode('utf-8'))
    else:
        vidfile = xbmcvfs.makeLegalFilename(downloadDir + title + '.mp4')
    if not xbmcvfs.exists(vidfile):
        tmp_file = tempfile.mktemp(dir=downloadDir, suffix='.mp4')
        if six.PY2:
            tmp_file = xbmc.makeLegalFilename(tmp_file)
        else:
            tmp_file = xbmcvfs.makeLegalFilename(tmp_file)
        pDialog.create('Dailymotion',
                       '{0}[CR]{1}'.format(translation(30044), title))
        dfile = requests.get(url,
                             headers=dict(urllib_parse.parse_qsl(hstr)),
                             stream=True)
        totalsize = float(dfile.headers['content-length'])
        handle = open(tmp_file, "wb")
        chunks = 0
        for chunk in dfile.iter_content(chunk_size=2097152):
            if chunk:  # filter out keep-alive new chunks
                handle.write(chunk)
                chunks += 1
                percent = int(float(chunks * 209715200) / totalsize)
                pDialog.update(percent)
                if pDialog.iscanceled():
                    handle.close()
                    xbmcvfs.delete(tmp_file)
                    break
        handle.close()
        try:
            xbmcvfs.rename(tmp_file, vidfile)
            return vidfile
        except:
            return tmp_file
    else:
        xbmcgui.Dialog().notification('Download:', translation(30109), _icon,
                                      5000, False)
Пример #4
0
def downloadVideo(url, name):

    def _pbhook(downloaded, filesize, url=None, dp=None, name=''):
        try:
            percent = min(int((downloaded * 100) / filesize), 100)
            currently_downloaded = float(downloaded) / (1024 * 1024)
            kbps_speed = int(downloaded / (time.perf_counter() if PY3 else time.clock() - start))
            if kbps_speed > 0:
                eta = (filesize - downloaded) / kbps_speed
            else:
                eta = 0
            kbps_speed = kbps_speed / 1024
            total = float(filesize) / (1024 * 1024)
            mbs = '%.02f MB of %.02f MB' % (currently_downloaded, total)
            e = 'Speed: %.02f Kb/s ' % kbps_speed
            e += 'ETA: %02d:%02d' % divmod(eta, 60)
            dp.update(percent, '{0}[CR]{1}[CR]{2}'.format(name[:50], mbs, e))
        except:
            percent = 100
            dp.update(percent)
        if dp.iscanceled():
            dp.close()
            raise StopDownloading('Stopped Downloading')

    def getResponse(url, headers2, size):
        try:
            if size > 0:
                size = int(size)
                headers2['Range'] = 'bytes=%d-' % size

            req = Request(url, headers=headers2)

            resp = urlopen(req, timeout=30)
            return resp
        except:
            return None

    def doDownload(url, dest, dp, name):
        headers = {}
        if '|' in url:
            url, uheaders = url.split('|')
            headers = dict(urllib_parse.parse_qsl(uheaders))

        if 'User-Agent' not in list(headers.keys()):
            headers.update({'User-Agent': USER_AGENT})

        resp = getResponse(url, headers, 0)

        if not resp:
            dialog.ok("Cumination", '{0}[CR]{1}'.format(i18n('dnld_fail'), i18n('no_resp')))
            return False
        try:
            content = int(resp.headers['Content-Length'])
        except:
            content = 0
        try:
            resumable = 'bytes' in resp.headers['Accept-Ranges'].lower()
        except:
            resumable = False
        if resumable:
            six.print_("Download is resumable")

        if content < 1:
            dialog.ok("Cumination", '{0}[CR]{1}'.format(i18n('unkn_size'), i18n('no_dnld')))
            return False

        size = 8192
        mb = content / (1024 * 1024)

        if content < size:
            size = content

        total = 0
        errors = 0
        count = 0
        resume = 0
        sleep = 0

        six.print_('{0} : {1}MB {2} '.format(i18n('file_size'), mb, dest))
        f = xbmcvfs.File(dest, 'w')

        chunk = None
        chunks = []

        while True:
            downloaded = total
            for c in chunks:
                downloaded += len(c)
            percent = min(100 * downloaded / content, 100)

            _pbhook(downloaded, content, url, dp, name)

            chunk = None
            error = False

            try:
                chunk = resp.read(size)
                if not chunk:
                    if percent < 99:
                        error = True
                    else:
                        while len(chunks) > 0:
                            c = chunks.pop(0)
                            f.write(c)
                            del c
                        f.close()
                        return True

            except Exception as e:
                six.print_(str(e))
                error = True
                sleep = 10
                errno = 0

                if hasattr(e, 'errno'):
                    errno = e.errno

                if errno == 10035:  # 'A non-blocking socket operation could not be completed immediately'
                    pass

                if errno == 10054:  # 'An existing connection was forcibly closed by the remote host'
                    errors = 10  # force resume
                    sleep = 30

                if errno == 11001:  # 'getaddrinfo failed'
                    errors = 10  # force resume
                    sleep = 30

            if chunk:
                errors = 0
                chunks.append(chunk)
                if len(chunks) > 5:
                    c = chunks.pop(0)
                    f.write(c)
                    total += len(c)
                    del c

            if error:
                errors += 1
                count += 1
                xbmc.sleep(sleep * 1000)

            if (resumable and errors > 0) or errors >= 10:
                if (not resumable and resume >= 50) or resume >= 500:
                    # Give up!
                    return False

                resume += 1
                errors = 0
                if resumable:
                    chunks = []
                    # create new response
                    resp = getResponse(url, headers, total)
                else:
                    # use existing response
                    pass

    def clean_filename(s):
        if not s:
            return ''
        badchars = '\\/:*?\"<>|\''
        for c in badchars:
            s = s.replace(c, '')
        return s.strip()

    download_path = addon.getSetting('download_path')
    if download_path == '':
        try:
            download_path = dialog.browse(0, i18n('dnld_path'), "", "", False, False)
            addon.setSetting(id='download_path', value=download_path)
            if not xbmcvfs.exists(download_path):
                xbmcvfs.mkdir(download_path)
        except:
            pass
    if download_path != '':
        dp = xbmcgui.DialogProgress()
        name = re.sub(r'\[COLOR.+?\/COLOR\]', '', name).strip()
        dp.create(i18n('cum_dnld'), name[:50])
        tmp_file = tempfile.mktemp(dir=download_path, suffix=".mp4")
        tmp_file = xbmc.makeLegalFilename(tmp_file) if PY2 else xbmcvfs.makeLegalFilename(tmp_file)
        start = time.perf_counter() if PY3 else time.clock()
        try:
            downloaded = doDownload(url, tmp_file, dp, name)
            if downloaded:
                if PY2:
                    vidfile = xbmc.makeLegalFilename(download_path + clean_filename(name) + ".mp4")
                else:
                    vidfile = xbmcvfs.makeLegalFilename(download_path + clean_filename(name) + ".mp4")
                try:
                    xbmcvfs.rename(tmp_file, vidfile)
                    return vidfile
                except:
                    return tmp_file
            else:
                raise StopDownloading(i18n('stop_dnld'))
        except:
            while xbmcvfs.exists(tmp_file):
                try:
                    xbmcvfs.delete(tmp_file)
                    break
                except:
                    pass