Exemple #1
0
    def verify_bt(f, t):
        from lixian_progress import SimpleProgressBar

        bar = SimpleProgressBar()
        result = lixian_hash_bt.verify_bt_file(t, f, progress_callback=bar.update)
        bar.done()
        return result
Exemple #2
0
 def verify_bt(f, t):
     from lixian_progress import SimpleProgressBar
     bar = SimpleProgressBar()
     result = lixian_hash_bt.verify_bt_file(t,
                                            f,
                                            progress_callback=bar.update)
     bar.done()
     return result
Exemple #3
0
def download_single_task(client, download, task, options):
	output = options.get('output')
	output = output and os.path.expanduser(output)
	output_dir = options.get('output_dir')
	output_dir = output_dir and os.path.expanduser(output_dir)
	delete = options.get('delete')
	resuming = options.get('resuming')
	overwrite = options.get('overwrite')
	mini_hash = options.get('mini_hash')
	no_hash = options.get('no_hash')
	no_bt_dir = options.get('no_bt_dir')
	save_torrent_file = options.get('save_torrent_file')

	assert client.get_gdriveid()
	if task['status_text'] != 'completed':
		if 'files' not in task:
			with colors(options.get('colors')).yellow():
				print 'skip task %s as the status is %s' % (task['name'].encode(default_encoding), task['status_text'])
			return
	def download1(client, url, path, size):
		if not os.path.exists(path):
			download(client, url, path)
		elif not resuming:
			if overwrite:
				download(client, url, path)
			else:
				raise Exception('%s already exists. Please try --continue or --overwrite' % path)
		else:
			assert os.path.getsize(path) <= size, 'existing file bigger than expected, unsafe to continue nor overwrite'
			if os.path.getsize(path) < size:
				download(client, url, path, resuming)
			elif os.path.getsize(path) == size:
				pass
			else:
				raise NotImplementedError()
	def download2(client, url, path, task):
		size = task['size']
		if mini_hash and resuming and verify_mini_hash(path, task):
			return
		download1(client, url, path, size)
		verify = verify_basic_hash if no_hash else verify_hash
		if not verify(path, task):
			with colors(options.get('colors')).yellow():
				print 'hash error, redownloading...'
			os.remove(path)
			download1(client, url, path, size)
			if not verify(path, task):
				raise Exception('hash check failed')
	download_url = str(task['xunlei_url'])
	if output:
		output_path = output
		output_dir = os.path.dirname(output)
		output_name = os.path.basename(output)
	else:
		output_name = escape_filename(task['name']).encode(default_encoding)
		output_dir = output_dir or '.'
		output_path = os.path.join(output_dir, output_name)
	referer = str(client.get_referer())
	gdriveid = str(client.get_gdriveid())

	if task['type'] == 'bt':
		files, skipped, single_file = lixian_query.expand_bt_sub_tasks(task)
		if single_file:
			dirname = output_dir
		else:
			if no_bt_dir:
				output_path = os.path.dirname(output_path)
			dirname = output_path
		assert dirname # dirname must be non-empty, otherwise dirname + os.path.sep + ... might be dangerous
		if dirname and not os.path.exists(dirname):
			os.makedirs(dirname)
		for t in skipped:
			with colors(options.get('colors')).yellow():
				print 'skip task %s/%s (%s) as the status is %s' % (t['id'], t['index'], t['name'].encode(default_encoding), t['status_text'])
		if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
			print task['name'].encode(default_encoding), 'is already done'
			if delete and 'files' not in task:
				client.delete_task(task)
			return
		if not single_file:
			with colors(options.get('colors')).green():
				print output_name + '/'
		for f in files:
			name = f['name']
			if f['status_text'] != 'completed':
				print 'Skipped %s file %s ...' % (f['status_text'], name.encode(default_encoding))
				continue
			if not single_file:
				print name.encode(default_encoding), '...'
			else:
				with colors(options.get('colors')).green():
					print name.encode(default_encoding), '...'
			# XXX: if file name is escaped, hashing bt won't get correct file
			splitted_path = map(escape_filename, name.split('\\'))
			name = os.path.join(*splitted_path).encode(default_encoding)
			path = dirname + os.path.sep + name # fix issue #82
			if splitted_path[:-1]:
				subdir = os.path.join(*splitted_path[:-1]).encode(default_encoding)
				subdir = dirname + os.path.sep + subdir # fix issue #82
				if not os.path.exists(subdir):
					os.makedirs(subdir)
			download_url = str(f['xunlei_url'])
			download2(client, download_url, path, f)
		if save_torrent_file:
			info_hash = str(task['bt_hash'])
			if single_file:
				torrent = os.path.join(dirname, escape_filename(task['name']).encode(default_encoding) + '.torrent')
			else:
				torrent = os.path.join(dirname, info_hash + '.torrent')
			if os.path.exists(torrent):
				pass
			else:
				content = client.get_torrent_file_by_info_hash(info_hash)
				with open(torrent, 'wb') as ouput_stream:
					ouput_stream.write(content)
		if not no_hash:
			torrent_file = client.get_torrent_file(task)
			print 'Hashing bt ...'
			from lixian_progress import SimpleProgressBar
			bar = SimpleProgressBar()
			file_set = [f['name'].encode('utf-8').split('\\') for f in files] if 'files' in task else None
			verified = lixian_hash_bt.verify_bt(output_path, lixian_hash_bt.bdecode(torrent_file)['info'], file_set=file_set, progress_callback=bar.update)
			bar.done()
			if not verified:
				# note that we don't delete bt download folder if hash failed
				raise Exception('bt hash check failed')
	else:
		if output_dir and not os.path.exists(output_dir):
			os.makedirs(output_dir)

		with colors(options.get('colors')).green():
			print output_name, '...'
		download2(client, download_url, output_path, task)

	if delete and 'files' not in task:
		client.delete_task(task)
Exemple #4
0
def download_single_task(client, download, task, options):
	output = options.get('output')
	output_dir = options.get('output_dir')
	delete = options.get('delete')
	resuming = options.get('resuming')
	overwrite = options.get('overwrite')
	mini_hash = options.get('mini_hash')
	no_hash = options.get('no_hash')

	assert client.get_gdriveid()
	if task['status_text'] != 'completed':
		if 'files' not in task:
			print 'skip task %s as the status is %s' % (task['name'].encode(default_encoding), task['status_text'])
			return
	def download1(client, url, path, size):
		if not os.path.exists(path):
			download(client, url, path)
		elif not resuming:
			if overwrite:
				download(client, url, path)
			else:
				raise Exception('%s already exists. Please try --continue or --overwrite' % path)
		else:
			assert os.path.getsize(path) <= size, 'existing file bigger than expected, unsafe to continue nor overwrite'
			if os.path.getsize(path) < size:
				download(client, url, path, resuming)
			elif os.path.getsize(path) == size:
				pass
			else:
				raise NotImplementedError()
	def download2(client, url, path, task):
		size = task['size']
		if mini_hash and resuming and verify_mini_hash(path, task):
			return
		download1(client, url, path, size)
		verify = verify_basic_hash if no_hash else verify_hash
		if not verify(path, task):
			print 'hash error, redownloading...'
			os.remove(path)
			download1(client, url, path, size)
			if not verify(path, task):
				raise Exception('hash check failed')
	download_url = str(task['xunlei_url'])
	if output:
		filename = output
	else:
		filename = escape_filename(task['name']).encode(default_encoding)
		if output_dir:
			filename = os.path.join(output_dir, filename)
	referer = str(client.get_referer())
	gdriveid = str(client.get_gdriveid())

	if task['type'] == 'bt':
		files = client.list_bt(task)
		if len(files) == 1 and files[0]['name'] == task['name']:
			dirname = os.path.dirname(filename)
		else:
			dirname = filename
		if dirname and not os.path.exists(dirname):
			os.makedirs(dirname)
		if 'files' in task:
			ordered_files = []
			indexed_files = dict((f['index'], f) for f in files)
			for index in task['files']:
				t = indexed_files[int(index)]
				if t not in ordered_files:
					if t['status_text'] != 'completed':
						print 'skip task %s/%s (%s) as the status is %s' % (t['id'], index, t['name'].encode(default_encoding), t['status_text'])
					else:
						ordered_files.append(t)
			files = ordered_files
		if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
			print task['name'].encode(default_encoding), 'is already done'
			if delete and 'files' not in task:
				client.delete_task(task)
			return
		for f in files:
			name = f['name']
			print 'Downloading', name.encode(default_encoding), '...'
			# XXX: if file name is escaped, hashing bt won't get correct file
			path = os.path.join(dirname, *[p.encode(default_encoding) for p in map(escape_filename, name.split('\\'))])
			subdir = os.path.dirname(path)
			if subdir and not os.path.exists(subdir):
				os.makedirs(subdir)
			download_url = str(f['xunlei_url'])
			download2(client, download_url, path, f)
		if not no_hash:
			torrent_file = client.get_torrent_file(task)
			print 'Hashing bt ...'
			from lixian_progress import SimpleProgressBar
			bar = SimpleProgressBar()
			file_set = [f['name'].encode('utf-8').split('\\') for f in files] if 'files' in task else None
			verified = lixian_hash_bt.verify_bt(filename, lixian_hash_bt.bdecode(torrent_file)['info'], file_set=file_set, progress_callback=bar.update)
			bar.done()
			if not verified:
				# note that we don't delete bt download folder if hash failed
				raise Exception('bt hash check failed')
	else:
		dirname = os.path.dirname(filename)
		if dirname and not os.path.exists(dirname):
			os.makedirs(dirname)
		print 'Downloading', os.path.basename(filename), '...'
		download2(client, download_url, filename, task)

	if delete and 'files' not in task:
		client.delete_task(task)
Exemple #5
0
def download_single_task(client, download, task, options):
    output = options.get('output')
    output = output and os.path.expanduser(output)
    output_dir = options.get('output_dir')
    output_dir = output_dir and os.path.expanduser(output_dir)
    delete = options.get('delete')
    resuming = options.get('resuming')
    overwrite = options.get('overwrite')
    mini_hash = options.get('mini_hash')
    no_hash = options.get('no_hash')
    no_bt_dir = options.get('no_bt_dir')
    save_torrent_file = options.get('save_torrent_file')

    assert client.get_gdriveid()
    if task['status_text'] != 'completed':
        if 'files' not in task:
            with colors(options.get('colors')).yellow():
                print 'skip task %s as the status is %s' % (
                    task['name'].encode(default_encoding), task['status_text'])
            return

    def download1(client, url, path, size):
        if not os.path.exists(path):
            download(client, url, path)
        elif not resuming:
            if overwrite:
                download(client, url, path)
            else:
                raise Exception(
                    '%s already exists. Please try --continue or --overwrite' %
                    path)
        else:
            assert os.path.getsize(
                path
            ) <= size, 'existing file bigger than expected, unsafe to continue nor overwrite'
            if os.path.getsize(path) < size:
                download(client, url, path, resuming)
            elif os.path.getsize(path) == size:
                pass
            else:
                raise NotImplementedError()

    def download2(client, url, path, task):
        size = task['size']
        if mini_hash and resuming and verify_mini_hash(path, task):
            return
        download1(client, url, path, size)
        verify = verify_basic_hash if no_hash else verify_hash
        if not verify(path, task):
            with colors(options.get('colors')).yellow():
                print 'hash error, redownloading...'
            os.remove(path)
            download1(client, url, path, size)
            if not verify(path, task):
                raise Exception('hash check failed')

    download_url = str(task['xunlei_url'])
    if output:
        output_path = output
        output_dir = os.path.dirname(output)
        output_name = os.path.basename(output)
    else:
        output_name = escape_filename(task['name']).encode(default_encoding)
        output_dir = output_dir or '.'
        output_path = os.path.join(output_dir, output_name)
    referer = str(client.get_referer())
    gdriveid = str(client.get_gdriveid())

    if task['type'] == 'bt':
        files, skipped, single_file = lixian_query.expand_bt_sub_tasks(task)
        if single_file:
            dirname = output_dir
        else:
            if no_bt_dir:
                output_path = os.path.dirname(output_path)
            dirname = output_path
        assert dirname  # dirname must be non-empty, otherwise dirname + os.path.sep + ... might be dangerous
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        for t in skipped:
            with colors(options.get('colors')).yellow():
                print 'skip task %s/%s (%s) as the status is %s' % (
                    str(t['id']), t['index'],
                    t['name'].encode(default_encoding), t['status_text'])
        if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
            print task['name'].encode(default_encoding), 'is already done'
            if delete and 'files' not in task:
                client.delete_task(task)
            return
        if not single_file:
            with colors(options.get('colors')).green():
                print output_name + '/'
        for f in files:
            name = f['name']
            if f['status_text'] != 'completed':
                print 'Skipped %s file %s ...' % (
                    f['status_text'], name.encode(default_encoding))
                continue
            if not single_file:
                print name.encode(default_encoding), '...'
            else:
                with colors(options.get('colors')).green():
                    print name.encode(default_encoding), '...'
            # XXX: if file name is escaped, hashing bt won't get correct file
            splitted_path = map(escape_filename, name.split('\\'))
            name = os.path.join(*splitted_path).encode(default_encoding)
            path = dirname + os.path.sep + name  # fix issue #82
            if splitted_path[:-1]:
                subdir = os.path.join(
                    *splitted_path[:-1]).encode(default_encoding)
                subdir = dirname + os.path.sep + subdir  # fix issue #82
                if not os.path.exists(subdir):
                    os.makedirs(subdir)
            download_url = str(f['xunlei_url'])
            download2(client, download_url, path, f)
        if save_torrent_file:
            info_hash = str(task['bt_hash'])
            if single_file:
                torrent = os.path.join(
                    dirname,
                    escape_filename(task['name']).encode(default_encoding) +
                    '.torrent')
            else:
                torrent = os.path.join(dirname, info_hash + '.torrent')
            if os.path.exists(torrent):
                pass
            else:
                content = client.get_torrent_file_by_info_hash(info_hash)
                with open(torrent, 'wb') as ouput_stream:
                    ouput_stream.write(content)
        if not no_hash:
            torrent_file = client.get_torrent_file(task)
            print 'Hashing bt ...'
            from lixian_progress import SimpleProgressBar
            bar = SimpleProgressBar()
            file_set = [f['name'].encode('utf-8').split('\\')
                        for f in files] if 'files' in task else None
            verified = lixian_hash_bt.verify_bt(
                output_path,
                lixian_hash_bt.bdecode(torrent_file)['info'],
                file_set=file_set,
                progress_callback=bar.update)
            bar.done()
            if not verified:
                # note that we don't delete bt download folder if hash failed
                raise Exception('bt hash check failed')
    else:
        if output_dir and not os.path.exists(output_dir):
            os.makedirs(output_dir)

        with colors(options.get('colors')).green():
            print output_name, '...'
        download2(client, download_url, output_path, task)

    if delete and 'files' not in task:
        client.delete_task(task)
Exemple #6
0
def download_single_task(client, task, options):
	output = options.get('output')
	output = output and os.path.expanduser(output)
	output_dir = options.get('output_dir')
	output_dir = output_dir and os.path.expanduser(output_dir)
	delete = options.get('delete')
	resuming = options.get('resuming')
	overwrite = options.get('overwrite')
	mini_hash = options.get('mini_hash')
	no_hash = options.get('no_hash')
	no_bt_dir = options.get('no_bt_dir')
	save_torrent_file = options.get('save_torrent_file')

	assert client.get_gdriveid()
	if task['status_text'] != 'completed':
		if 'files' not in task:
			with colors(options.get('colors')).yellow():
				print 'skip task %s as the status is %s' % (task['name'].encode(default_encoding), task['status_text'])
			return

	if output:
		output_path = output
		output_dir = os.path.dirname(output)
		output_name = os.path.basename(output)
	else:
		output_name = safe_encode_native_path(escape_filename(task['name']))
		output_dir = output_dir or '.'
		output_path = os.path.join(output_dir, output_name)

	if task['type'] == 'bt':
		files, skipped, single_file = lixian_query.expand_bt_sub_tasks(task)
		if single_file:
			dirname = output_dir
		else:
			if no_bt_dir:
				output_path = os.path.dirname(output_path)
			dirname = output_path
		assert dirname # dirname must be non-empty, otherwise dirname + os.path.sep + ... might be dangerous
		ensure_dir_exists(dirname)
		for t in skipped:
			with colors(options.get('colors')).yellow():
				print 'skip task %s/%s (%s) as the status is %s' % (str(t['id']), t['index'], t['name'].encode(default_encoding), t['status_text'])
		if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
			print task['name'].encode(default_encoding), 'is already done'
			if delete and 'files' not in task:
				client.delete_task(task)
			return
		if not single_file:
			with colors(options.get('colors')).green():
				print output_name + '/'
		for f in files:
			name = f['name']
			if f['status_text'] != 'completed':
				print 'Skipped %s file %s ...' % (f['status_text'], name.encode(default_encoding))
				continue
			if not single_file:
				print name.encode(default_encoding), '...'
			else:
				with colors(options.get('colors')).green():
					print name.encode(default_encoding), '...'
			# XXX: if file name is escaped, hashing bt won't get correct file
			splitted_path = map(escape_filename, name.split('\\'))
			name = safe_encode_native_path(os.path.join(*splitted_path))
			path = dirname + os.path.sep + name # fix issue #82
			if splitted_path[:-1]:
				subdir = safe_encode_native_path(os.path.join(*splitted_path[:-1]))
				subdir = dirname + os.path.sep + subdir # fix issue #82
				ensure_dir_exists(subdir)
			download_file(client, path, f, options)
		if save_torrent_file:
			info_hash = str(task['bt_hash'])
			if single_file:
				torrent = os.path.join(dirname, escape_filename(task['name']).encode(default_encoding) + '.torrent')
			else:
				torrent = os.path.join(dirname, info_hash + '.torrent')
			if os.path.exists(torrent):
				pass
			else:
				content = client.get_torrent_file_by_info_hash(info_hash)
				with open(torrent, 'wb') as ouput_stream:
					ouput_stream.write(content)
		if not no_hash:
			torrent_file = client.get_torrent_file(task)
			print 'Hashing bt ...'
			from lixian_progress import SimpleProgressBar
			bar = SimpleProgressBar()
			file_set = [f['name'].encode('utf-8').split('\\') for f in files] if 'files' in task else None
			verified = lixian_hash_bt.verify_bt(output_path, lixian_hash_bt.bdecode(torrent_file)['info'], file_set=file_set, progress_callback=bar.update)
			bar.done()
			if not verified:
				# note that we don't delete bt download folder if hash failed
				raise Exception('bt hash check failed')
	else:
		ensure_dir_exists(output_dir)

		with colors(options.get('colors')).green():
			print output_name, '...'
		download_file(client, output_path, task, options)

	if delete and 'files' not in task:
		client.delete_task(task)
Exemple #7
0
def download_single_task(client, download, task, options):
    output = options.get("output")
    output_dir = options.get("output_dir")
    delete = options.get("delete")
    resuming = options.get("resuming")
    overwrite = options.get("overwrite")
    mini_hash = options.get("mini_hash")
    no_hash = options.get("no_hash")

    assert client.get_gdriveid()
    if task["status_text"] != "completed":
        if "files" not in task:
            print "skip task %s as the status is %s" % (task["name"].encode(default_encoding), task["status_text"])
            return

    def download1(client, url, path, size):
        if not os.path.exists(path):
            download(client, url, path)
        elif not resuming:
            if overwrite:
                download(client, url, path)
            else:
                raise Exception("%s already exists. Please try --continue or --overwrite" % path)
        else:
            assert os.path.getsize(path) <= size, "existing file bigger than expected, unsafe to continue nor overwrite"
            if os.path.getsize(path) < size:
                download(client, url, path, resuming)
            elif os.path.getsize(path) == size:
                pass
            else:
                raise NotImplementedError()

    def download2(client, url, path, task):
        size = task["size"]
        if mini_hash and resuming and verify_mini_hash(path, task):
            return
        download1(client, url, path, size)
        verify = verify_basic_hash if no_hash else verify_hash
        if not verify(path, task):
            print "hash error, redownloading..."
            os.remove(path)
            download1(client, url, path, size)
            if not verify(path, task):
                raise Exception("hash check failed")

    download_url = str(task["xunlei_url"])
    if output:
        output_path = output
        output_dir = os.path.dirname(output)
        output_name = os.path.basename(output)
    else:
        output_name = escape_filename(task["name"]).encode(default_encoding)
        output_dir = output_dir or "."
        output_path = os.path.join(output_dir, output_name)
    referer = str(client.get_referer())
    gdriveid = str(client.get_gdriveid())

    if task["type"] == "bt":
        files, skipped, single_file = expand_bt_sub_tasks(client, task)
        if single_file:
            dirname = output_dir
        else:
            dirname = output_path
        assert dirname  # dirname must be non-empty, otherwise dirname + os.path.sep + ... might be dangerous
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
            for t in skipped:
                print "skip task %s/%s (%s) as the status is %s" % (
                    t["id"],
                    t["index"],
                    t["name"].encode(default_encoding),
                    t["status_text"],
                )
        if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
            print task["name"].encode(default_encoding), "is already done"
            if delete and "files" not in task:
                client.delete_task(task)
            return
        for f in files:
            name = f["name"]
            if f["status_text"] != "completed":
                print "Skipped %s file %s ..." % (f["status_text"], name.encode(default_encoding))
                continue
            print "Downloading", name.encode(default_encoding), "..."
            # XXX: if file name is escaped, hashing bt won't get correct file
            splitted_path = map(escape_filename, name.split("\\"))
            name = os.path.join(*splitted_path).encode(default_encoding)
            path = dirname + os.path.sep + name  # fix issue #82
            if splitted_path[:-1]:
                subdir = os.path.join(*splitted_path[:-1]).encode(default_encoding)
                subdir = dirname + os.path.sep + subdir  # fix issue #82
                if not os.path.exists(subdir):
                    os.makedirs(subdir)
            download_url = str(f["xunlei_url"])
            download2(client, download_url, path, f)
        if not no_hash:
            torrent_file = client.get_torrent_file(task)
            print "Hashing bt ..."
            from lixian_progress import SimpleProgressBar

            bar = SimpleProgressBar()
            file_set = [f["name"].encode("utf-8").split("\\") for f in files] if "files" in task else None
            verified = lixian_hash_bt.verify_bt(
                output_path,
                lixian_hash_bt.bdecode(torrent_file)["info"],
                file_set=file_set,
                progress_callback=bar.update,
            )
            bar.done()
            if not verified:
                # note that we don't delete bt download folder if hash failed
                raise Exception("bt hash check failed")
    else:
        if output_dir and not os.path.exists(output_dir):
            os.makedirs(output_dir)
        print "Downloading", output_name, "..."
        download2(client, download_url, output_path, task)

    if delete and "files" not in task:
        client.delete_task(task)
Exemple #8
0
def download_single_task(client, task, options):
    output = options.get("output")
    output = output and os.path.expanduser(output)
    output_dir = options.get("output_dir")
    output_dir = output_dir and os.path.expanduser(output_dir)
    delete = options.get("delete")
    resuming = options.get("resuming")
    overwrite = options.get("overwrite")
    mini_hash = options.get("mini_hash")
    no_hash = options.get("no_hash")
    no_bt_dir = options.get("no_bt_dir")
    save_torrent_file = options.get("save_torrent_file")

    assert client.get_gdriveid()
    if task["status_text"] != "completed":
        if "files" not in task:
            with colors(options.get("colors")).yellow():
                print "skip task %s as the status is %s" % (task["name"].encode(default_encoding), task["status_text"])
            return

    if output:
        output_path = output
        output_dir = os.path.dirname(output)
        output_name = os.path.basename(output)
    else:
        output_name = escape_filename(task["name"]).encode(default_encoding)
        output_dir = output_dir or "."
        output_path = os.path.join(output_dir, output_name)

    if task["type"] == "bt":
        files, skipped, single_file = lixian_query.expand_bt_sub_tasks(task)
        if single_file:
            dirname = output_dir
        else:
            if no_bt_dir:
                output_path = os.path.dirname(output_path)
            dirname = output_path
        assert dirname  # dirname must be non-empty, otherwise dirname + os.path.sep + ... might be dangerous
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        for t in skipped:
            with colors(options.get("colors")).yellow():
                print "skip task %s/%s (%s) as the status is %s" % (
                    str(t["id"]),
                    t["index"],
                    t["name"].encode(default_encoding),
                    t["status_text"],
                )
        if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
            print task["name"].encode(default_encoding), "is already done"
            if delete and "files" not in task:
                client.delete_task(task)
            return
        if not single_file:
            with colors(options.get("colors")).green():
                print output_name + "/"
        for f in files:
            name = f["name"]
            if f["status_text"] != "completed":
                print "Skipped %s file %s ..." % (f["status_text"], name.encode(default_encoding))
                continue
            if not single_file:
                print name.encode(default_encoding), "..."
            else:
                with colors(options.get("colors")).green():
                    print name.encode(default_encoding), "..."
                    # XXX: if file name is escaped, hashing bt won't get correct file
            splitted_path = map(escape_filename, name.split("\\"))
            name = os.path.join(*splitted_path).encode(default_encoding)
            path = dirname + os.path.sep + name  # fix issue #82
            if splitted_path[:-1]:
                subdir = os.path.join(*splitted_path[:-1]).encode(default_encoding)
                subdir = dirname + os.path.sep + subdir  # fix issue #82
                if not os.path.exists(subdir):
                    os.makedirs(subdir)
            download_file(client, path, f, options)
        if save_torrent_file:
            info_hash = str(task["bt_hash"])
            if single_file:
                torrent = os.path.join(dirname, escape_filename(task["name"]).encode(default_encoding) + ".torrent")
            else:
                torrent = os.path.join(dirname, info_hash + ".torrent")
            if os.path.exists(torrent):
                pass
            else:
                content = client.get_torrent_file_by_info_hash(info_hash)
                with open(torrent, "wb") as ouput_stream:
                    ouput_stream.write(content)
        if not no_hash:
            torrent_file = client.get_torrent_file(task)
            print "Hashing bt ..."
            from lixian_progress import SimpleProgressBar

            bar = SimpleProgressBar()
            file_set = [f["name"].encode("utf-8").split("\\") for f in files] if "files" in task else None
            verified = lixian_hash_bt.verify_bt(
                output_path,
                lixian_hash_bt.bdecode(torrent_file)["info"],
                file_set=file_set,
                progress_callback=bar.update,
            )
            bar.done()
            if not verified:
                # note that we don't delete bt download folder if hash failed
                raise Exception("bt hash check failed")
    else:
        if output_dir and not os.path.exists(output_dir):
            os.makedirs(output_dir)

        with colors(options.get("colors")).green():
            print output_name, "..."
        download_file(client, output_path, task, options)

    if delete and "files" not in task:
        client.delete_task(task)
def download_single_task(client, download, task, options):
    output = options.get('output')
    output_dir = options.get('output_dir')
    delete = options.get('delete')
    resuming = options.get('resuming')
    overwrite = options.get('overwrite')
    mini_hash = options.get('mini_hash')
    no_hash = options.get('no_hash')

    assert client.get_gdriveid()
    if task['status_text'] != 'completed':
        print 'skip task %s as the status is %s' % (
            task['name'].encode(default_encoding), task['status_text'])
        return

    def download1(client, url, path, size):
        if not os.path.exists(path):
            download(client, url, path)
        elif not resuming:
            if overwrite:
                download(client, url, path)
            else:
                raise Exception(
                    '%s already exists. Please try --continue or --overwrite' %
                    path)
        else:
            assert os.path.getsize(
                path
            ) <= size, 'existing file bigger than expected, unsafe to continue nor overwrite'
            if os.path.getsize(path) < size:
                download(client, url, path, resuming)
            elif os.path.getsize(path) == size:
                pass
            else:
                raise NotImplementedError()

    def download2(client, url, path, task):
        size = task['size']
        if mini_hash and resuming and verify_mini_hash(path, task):
            return
        download1(client, url, path, size)
        verify = verify_basic_hash if no_hash else verify_hash
        if not verify(path, task):
            print 'hash error, redownloading...'
            os.remove(path)
            download1(client, url, path, size)
            if not verify(path, task):
                raise Exception('hash check failed')

    download_url = str(task['xunlei_url'])
    if output:
        filename = output
    else:
        filename = escape_filename(task['name']).encode(default_encoding)
        if output_dir:
            filename = os.path.join(output_dir, filename)
    referer = str(client.get_referer())
    gdriveid = str(client.get_gdriveid())

    if task['type'] == 'bt':
        files = client.list_bt(task)
        if len(files) == 1 and files[0]['name'] == task['name']:
            dirname = os.path.dirname(filename)
        else:
            dirname = filename
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        if 'files' in task:
            ordered_files = []
            indexed_files = dict((f['index'], f) for f in files)
            for index in task['files']:
                t = indexed_files[int(index)]
                if t not in ordered_files:
                    ordered_files.append(t)
            files = ordered_files
        if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
            print task['name'].encode(default_encoding), 'is already done'
            if delete and 'files' not in task:
                client.delete_task(task)
            return
        for f in files:
            name = f['name'].encode(default_encoding)
            print 'Downloading', name, '...'
            path = os.path.join(dirname, *name.split('\\'))
            subdir = os.path.dirname(path)
            if subdir and not os.path.exists(subdir):
                os.makedirs(subdir)
            download_url = str(f['xunlei_url'])
            download2(client, download_url, path, f)
        if not no_hash:
            torrent_file = client.get_torrent_file(task)
            print 'Hashing bt ...'
            from lixian_progress import SimpleProgressBar
            bar = SimpleProgressBar()
            file_set = [f['name'].encode('utf-8').split('\\')
                        for f in files] if 'files' in task else None
            verified = lixian_hash_bt.verify_bt(
                filename,
                lixian_hash_bt.bdecode(torrent_file)['info'],
                file_set=file_set,
                progress_callback=bar.update)
            bar.done()
            if not verified:
                # note that we don't delete bt download folder if hash failed
                raise Exception('bt hash check failed')
    else:
        dirname = os.path.dirname(filename)
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        print 'Downloading', os.path.basename(filename), '...'
        download2(client, download_url, filename, task)

    if delete and 'files' not in task:
        client.delete_task(task)
Exemple #10
0
def download_single_task(client, download, task, options):
    output = options.get("output")
    output_dir = options.get("output_dir")
    delete = options.get("delete")
    resuming = options.get("resuming")
    overwrite = options.get("overwrite")
    mini_hash = options.get("mini_hash")
    no_hash = options.get("no_hash")

    assert client.get_gdriveid()
    if task["status_text"] != "completed":
        if "files" not in task:
            print "skip task %s as the status is %s" % (task["name"].encode(default_encoding), task["status_text"])
            return

    def download1(client, url, path, size):
        if not os.path.exists(path):
            download(client, url, path)
        elif not resuming:
            if overwrite:
                download(client, url, path)
            else:
                raise Exception("%s already exists. Please try --continue or --overwrite" % path)
        else:
            assert os.path.getsize(path) <= size, "existing file bigger than expected, unsafe to continue nor overwrite"
            if os.path.getsize(path) < size:
                download(client, url, path, resuming)
            elif os.path.getsize(path) == size:
                pass
            else:
                raise NotImplementedError()

    def download2(client, url, path, task):
        size = task["size"]
        if mini_hash and resuming and verify_mini_hash(path, task):
            return
        download1(client, url, path, size)
        verify = verify_basic_hash if no_hash else verify_hash
        if not verify(path, task):
            print "hash error, redownloading..."
            os.remove(path)
            download1(client, url, path, size)
            if not verify(path, task):
                raise Exception("hash check failed")

    download_url = str(task["xunlei_url"])
    if output:
        filename = output
    else:
        filename = escape_filename(task["name"]).encode(default_encoding)
        if output_dir:
            filename = os.path.join(output_dir, filename)
    referer = str(client.get_referer())
    gdriveid = str(client.get_gdriveid())

    if task["type"] == "bt":
        files = client.list_bt(task)
        if len(files) == 1 and files[0]["name"] == task["name"]:
            dirname = os.path.dirname(filename)
        else:
            dirname = filename
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        if "files" in task:
            ordered_files = []
            indexed_files = dict((f["index"], f) for f in files)
            for index in task["files"]:
                t = indexed_files[int(index)]
                if t not in ordered_files:
                    if t["status_text"] != "completed":
                        print "skip task %s/%s (%s) as the status is %s" % (
                            t["id"],
                            index,
                            t["name"].encode(default_encoding),
                            t["status_text"],
                        )
                    else:
                        ordered_files.append(t)
            files = ordered_files
        if mini_hash and resuming and verify_mini_bt_hash(dirname, files):
            print task["name"].encode(default_encoding), "is already done"
            if delete and "files" not in task:
                client.delete_task(task)
            return
        for f in files:
            name = f["name"]
            print "Downloading", name.encode(default_encoding), "..."
            # XXX: if file name is escaped, hashing bt won't get correct file
            path = os.path.join(dirname, *[p.encode(default_encoding) for p in map(escape_filename, name.split("\\"))])
            subdir = os.path.dirname(path)
            if subdir and not os.path.exists(subdir):
                os.makedirs(subdir)
            download_url = str(f["xunlei_url"])
            download2(client, download_url, path, f)
        if not no_hash:
            torrent_file = client.get_torrent_file(task)
            print "Hashing bt ..."
            from lixian_progress import SimpleProgressBar

            bar = SimpleProgressBar()
            file_set = [f["name"].encode("utf-8").split("\\") for f in files] if "files" in task else None
            verified = lixian_hash_bt.verify_bt(
                filename, lixian_hash_bt.bdecode(torrent_file)["info"], file_set=file_set, progress_callback=bar.update
            )
            bar.done()
            if not verified:
                # note that we don't delete bt download folder if hash failed
                raise Exception("bt hash check failed")
    else:
        dirname = os.path.dirname(filename)
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        print "Downloading", os.path.basename(filename), "..."
        download2(client, download_url, filename, task)

    if delete and "files" not in task:
        client.delete_task(task)