def show_node_speed(node, kb, options):
	node = "%-5s " % node
	speed = '%dKB/s' % kb
	bar = '.' * (kb /100)
	whitespaces = ' ' * (79 - len(node) - len(bar) - len(speed))
	if kb >= 1000:
		with colors(options.colors).green():
			# print node + bar + whitespaces + speed
			with colors(options.colors).bold():
				print node[:-1],
			print bar + whitespaces + speed
	else:
		print node + bar + whitespaces + speed
Exemple #2
0
def output_tasks(tasks, columns, args, top=True):
    from lixian_colors import colors

    for i, t in enumerate(tasks):
        status_colors = {
            "waiting": "yellow",
            "downloading": "magenta",
            "completed": "green",
            "pending": "cyan",
            "failed": "red",
        }
        c = status_colors[t["status_text"]]
        with colors(args.colors).ansi(c)():
            for k in columns:
                if k == "n":
                    if top:
                        print "#%d" % t["#"],
                elif k == "id":
                    print t.get("index", t["id"]),
                elif k == "name":
                    print t["name"].encode(default_encoding),
                elif k == "status":
                    with colors(args.colors).bold():
                        print t["status_text"],
                elif k == "size":
                    if args.format_size:
                        from lixian_util import format_size

                        print format_size(t["size"]),
                    else:
                        print t["size"],
                elif k == "progress":
                    print t["progress"],
                elif k == "speed":
                    print t["speed"],
                elif k == "date":
                    print t["date"],
                elif k == "dcid":
                    print t["dcid"],
                elif k == "gcid":
                    print t["gcid"],
                elif k == "original-url":
                    print t["original_url"],
                elif k == "download-url":
                    print t["xunlei_url"],
                else:
                    raise NotImplementedError(k)
            print
Exemple #3
0
def output_tasks(tasks, columns, args, top=True):
    for i, t in enumerate(tasks):
        status_colors = {
            'waiting': 'yellow',
            'downloading': 'magenta',
            'completed': 'green',
            'pending': 'cyan',
            'failed': 'red',
        }
        c = status_colors[t['status_text']]
        with colors(args.colors).ansi(c)():
            for k in columns:
                if k == 'n':
                    if top:
                        print '#%d' % t['#'],
                elif k == 'id':
                    print t.get('index', t['id']),
                elif k == 'name':
                    print t['name'].encode(default_encoding),
                elif k == 'status':
                    with colors(args.colors).bold():
                        print t['status_text'],
                elif k == 'size':
                    if args.format_size:
                        from lixian_util import format_size
                        print format_size(t['size']),
                    else:
                        print t['size'],
                elif k == 'progress':
                    print t['progress'],
                elif k == 'speed':
                    print t['speed'],
                elif k == 'date':
                    print t['date'],
                elif k == 'dcid':
                    print t['dcid'],
                elif k == 'gcid':
                    print t['gcid'],
                elif k == 'original-url':
                    print t['original_url'],
                elif k == 'download-url':
                    print t['xunlei_url'],
                else:
                    raise NotImplementedError(k)
            print
    return tasks
Exemple #4
0
def output_tasks(tasks, columns, args, top=True):
	for i, t in enumerate(tasks):
		status_colors = {
		'waiting': 'yellow',
		'downloading': 'magenta',
		'completed':'green',
		'pending':'cyan',
		'failed':'red',
		}
		c = status_colors[t['status_text']]
		with colors(args.colors).ansi(c)():
			for k in columns:
				if k == 'n':
					if top:
						print '#%d' % t['#'],
				elif k == 'id':
					print t.get('index', t['id']),
				elif k == 'name':
					print t['name'].encode(default_encoding),
				elif k == 'status':
					with colors(args.colors).bold():
						print t['status_text'],
				elif k == 'size':
					if args.format_size:
						from lixian_util import format_size
						print format_size(t['size']),
					else:
						print t['size'],
				elif k == 'progress':
					print t['progress'],
				elif k == 'speed':
					print t['speed'],
				elif k == 'date':
					print t['date'],
				elif k == 'dcid':
					print t['dcid'],
				elif k == 'gcid':
					print t['gcid'],
				elif k == 'original-url':
					print t['original_url'],
				elif k == 'download-url':
					print t['xunlei_url'],
				else:
					raise NotImplementedError(k)
			print
	return tasks
def test_file(client, url, name, options):
	with colors(options.colors).cyan():
		print name.encode(default_encoding)
	# print 'File:', name.encode(default_encoding)
	# print 'Address:', url
	node_url = lixian_nodes.resolve_node_url(url, client.get_gdriveid(), timeout=3)
	# print 'Node:', node_url
	test_nodes(node_url, client.get_gdriveid(), options)
Exemple #6
0
def download_multiple_tasks(client, tasks, options):
    for task in tasks:
        download_single_task(client, task, options)
    skipped = filter(lambda t: t["status_text"] != "completed", tasks)
    if skipped:
        with colors(options.get("colors")).yellow():
            print "Below tasks were skipped as they were not ready:"
        for task in skipped:
            print task["id"], task["status_text"], task["name"].encode(default_encoding)
Exemple #7
0
def download_multiple_tasks(client, tasks, options):
	for task in tasks:
		download_single_task(client, task, options)
	skipped = filter(lambda t: t['status_text'] != 'completed', tasks)
	if skipped:
		with colors(options.get('colors')).yellow():
			print "Below tasks were skipped as they were not ready:"
		for task in skipped:
			print task['id'], task['status_text'], task['name'].encode(default_encoding)
Exemple #8
0
def download_multiple_tasks(client, download, tasks, options):
	for task in tasks:
		download_single_task(client, download, task, options)
	skipped = filter(lambda t: t['status_text'] != 'completed', tasks)
	if skipped:
		with colors(options.get('colors')).yellow():
			print "Below tasks were skipped as they were not ready:"
		for task in skipped:
			print task['id'], task['status_text'], task['name'].encode(default_encoding)
Exemple #9
0
 def download2(client, url, path, task):
     size = task["size"]
     if mini_hash and resuming and verify_mini_hash(path, task):
         return
     download1_checked(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.rename(path, path + ".error")
         download1_checked(client, url, path, size)
         if not verify(path, task):
             raise Exception("hash check failed")
Exemple #10
0
	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')
Exemple #11
0
 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')
Exemple #12
0
def delete_task(args):
    client = create_client(args)
    to_delete = lixian_query.search_tasks(client, args)
    if not to_delete:
        print "Nothing to delete"
        return
    with colors(args.colors).red.bold():
        print "Below files are going to be deleted:"
        for x in to_delete:
            print x["name"].encode(default_encoding)
    if args.i:
        yes_or_no = raw_input("Are your sure to delete below files from Xunlei cloud? ")
        while yes_or_no.lower() not in ("y", "yes", "n", "no"):
            yes_or_no = raw_input("yes or no? ")
        if yes_or_no.lower() in ("y", "yes"):
            pass
        elif yes_or_no.lower() in ("n", "no"):
            raise RuntimeError("Deletion abort per user request.")
    client.delete_tasks(to_delete)
Exemple #13
0
def delete_task(args):
	client = create_client(args)
	to_delete = lixian_query.search_tasks(client, args)
	if not to_delete:
		print 'Nothing to delete'
		return
	with colors(args.colors).red.bold():
		print "Below files are going to be deleted:"
		for x in to_delete:
			print x['name'].encode(default_encoding)
	if args.i:
		yes_or_no = raw_input('Are your sure to delete below files from Xunlei cloud? ')
		while yes_or_no.lower() not in ('y', 'yes', 'n', 'no'):
			yes_or_no = raw_input('yes or no? ')
		if yes_or_no.lower() in ('y', 'yes'):
			pass
		elif yes_or_no.lower() in ('n', 'no'):
			raise RuntimeError('Deletion abort per user request.')
	client.delete_tasks(to_delete)
Exemple #14
0
def delete_task(args):
    client = XunleiClient(args.username, args.password, args.cookies)
    to_delete = lixian_query.search_tasks(client, args)
    if not to_delete:
        print 'Nothing to delete'
        return
    with colors(args.colors).red.bold():
        print "Below files are going to be deleted:"
        for x in to_delete:
            print x['name'].encode(default_encoding)
    if args.i:
        yes_or_no = raw_input(
            'Are your sure to delete below files from Xunlei cloud? ')
        while yes_or_no.lower() not in ('y', 'yes', 'n', 'no'):
            yes_or_no = raw_input('yes or no? ')
        if yes_or_no.lower() in ('y', 'yes'):
            pass
        elif yes_or_no.lower() in ('n', 'no'):
            raise RuntimeError('Deletion abort per user request.')
    client.delete_tasks(to_delete)
def delete_task(args):
	client = XunleiClient(args.username, args.password, args.cookies)
	if len(args):
		to_delete = search_tasks(client, args)
	elif args.all:
		to_delete = client.read_all_tasks()
	if not to_delete:
		print 'Nothing to delete'
		return
	from lixian_colors import colors
	with colors(args.colors).red.bold():
		print "Below files are going to be deleted:"
		for x in to_delete:
			print x['name'].encode(default_encoding)
	if args.i:
		yes_or_no = raw_input('Are your sure to delete below files from Xunlei cloud? ')
		while yes_or_no.lower() not in ('y', 'yes', 'n', 'no'):
			yes_or_no = raw_input('yes or no? ')
		if yes_or_no.lower() in ('y', 'yes'):
			pass
		elif yes_or_no.lower() in ('n', 'no'):
			raise RuntimeError('Deletion abort per user request.')
	client.delete_tasks(to_delete)
Exemple #16
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)
def show_node_error(node, e, options):
	with colors(options.colors).red():
		print "%-5s %s" % (node, e)
Exemple #18
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)
Exemple #19
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)
	best_speed = 0
	for node in nodes:
		# print 'Node:', node
		url = lixian_nodes.switch_node_in_url(node_url, node)
		try:
			speed = lixian_nodes.get_node_url_speed(url, gdriveid)
			if best_speed < speed:
				best = node
				best_speed = speed
			kb = int(speed/1000)
			# print 'Speed: %dKB/s' % kb, '.' * (kb /100)
			show_node_speed(node, kb, options)
		except Exception, e:
			show_node_error(node, e, options)
	if best:
		with colors(options.colors).green():
			print best,
		print "is the fastest node!"

def show_node_speed(node, kb, options):
	node = "%-5s " % node
	speed = '%dKB/s' % kb
	bar = '.' * (kb /100)
	whitespaces = ' ' * (79 - len(node) - len(bar) - len(speed))
	if kb >= 1000:
		with colors(options.colors).green():
			# print node + bar + whitespaces + speed
			with colors(options.colors).bold():
				print node[:-1],
			print bar + whitespaces + speed
	else:
Exemple #21
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 #22
0
def list_task(args):
    args = parse_login_command_line(args, [], [
        'all', 'completed', 'deleted', 'expired', 'id', 'name', 'status',
        'size', 'dcid', 'gcid', 'original-url', 'download-url', 'speed',
        'progress', 'date', 'n', 'format-size', 'colors'
    ],
                                    default={
                                        'id': get_config('id', True),
                                        'name': True,
                                        'status': True,
                                        'n': get_config('n'),
                                        'size': get_config('size'),
                                        'format-size':
                                        get_config('format-size'),
                                        'colors': get_config('colors', True)
                                    },
                                    help=lixian_help.list)

    status = 'all'
    if args.completed:
        status = 'completed'
    elif args.deleted:
        status = 'deleted'
    elif args.expired:
        status = 'expired'

    parent_ids = [a[:-1] for a in args if re.match(r'^#?\d+/$', a)]
    if parent_ids and not all(re.match(r'^#?\d+/$', a) for a in args):
        raise NotImplementedError("Can't mix 'id/' with others")
    assert len(
        parent_ids) <= 1, "sub-tasks listing only supports single task id"
    ids = [a[:-1] if re.match(r'^#?\d+/$', a) else a for a in args]

    client = XunleiClient(args.username, args.password, args.cookies)
    if parent_ids:
        args[0] = args[0][:-1]
        tasks = search_tasks(client, args, status=status)
        assert len(tasks) == 1
        tasks = client.list_bt(tasks[0])
        #tasks = client.list_bt(client.get_task_by_id(parent_ids[0]))
        tasks.sort(key=lambda x: int(x['index']))
    elif len(ids):
        tasks = search_tasks(client, args, status=status)
    elif status == 'all':
        tasks = client.read_all_tasks()
    elif status == 'completed':
        tasks = client.read_all_completed()
    elif status == 'deleted':
        tasks = client.read_all_deleted()
    elif status == 'expired':
        tasks = client.read_all_expired()
    else:
        raise NotImplementedError(status)
    columns = [
        'n', 'id', 'name', 'status', 'size', 'progress', 'speed', 'date',
        'dcid', 'gcid', 'original-url', 'download-url'
    ]
    columns = filter(lambda k: getattr(args, k), columns)
    from lixian_colors import colors
    for i, t in enumerate(tasks):
        status_colors = {
            'waiting': 'yellow',
            'downloading': 'magenta',
            'completed': 'green',
            'pending': 'cyan',
            'failed': 'red',
        }
        c = status_colors[t['status_text']]
        with colors(args.colors).ansi(c)():
            for k in columns:
                if k == 'n':
                    if not parent_ids:
                        print '#%d' % t['#'],
                elif k == 'id':
                    print t.get('index', t['id']),
                elif k == 'name':
                    print t['name'].encode(default_encoding),
                elif k == 'status':
                    with colors(args.colors).bold():
                        print t['status_text'],
                elif k == 'size':
                    if args.format_size:
                        from lixian_util import format_size
                        print format_size(t['size']),
                    else:
                        print t['size'],
                elif k == 'progress':
                    print t['progress'],
                elif k == 'speed':
                    print t['speed'],
                elif k == 'date':
                    print t['date'],
                elif k == 'dcid':
                    print t['dcid'],
                elif k == 'gcid':
                    print t['gcid'],
                elif k == 'original-url':
                    print t['original_url'],
                elif k == 'download-url':
                    print t['xunlei_url'],
                else:
                    raise NotImplementedError(k)
            print
def list_task(args):
	args = parse_login_command_line(args, [],
	                                ['all', 'completed', 'deleted', 'expired',
	                                 'id', 'name', 'status', 'size', 'dcid', 'gcid', 'original-url', 'download-url', 'speed', 'progress', 'date',
	                                 'n',
	                                 'format-size',
	                                 'colors'
	                                 ],
									default={'id': get_config('id', True), 'name': True, 'status': True, 'n': get_config('n'), 'size': get_config('size'), 'format-size': get_config('format-size'), 'colors': get_config('colors', True)},
									help=lixian_help.list)

	status = 'all'
	if args.completed:
		status = 'completed'
	elif args.deleted:
		status = 'deleted'
	elif args.expired:
		status = 'expired'

	parent_ids = [a[:-1] for a in args if re.match(r'^#?\d+/$', a)]
	if parent_ids and not all(re.match(r'^#?\d+/$', a) for a in args):
		raise NotImplementedError("Can't mix 'id/' with others")
	assert len(parent_ids) <= 1, "sub-tasks listing only supports single task id"
	ids = [a[:-1] if re.match(r'^#?\d+/$', a) else a for a in args]

	client = XunleiClient(args.username, args.password, args.cookies)
	if parent_ids:
		args[0] = args[0][:-1]
		tasks = search_tasks(client, args, status=status)
		assert len(tasks) == 1
		tasks = client.list_bt(tasks[0])
		#tasks = client.list_bt(client.get_task_by_id(parent_ids[0]))
		tasks.sort(key=lambda x: int(x['index']))
	elif len(ids):
		tasks = search_tasks(client, args, status=status)
	elif status == 'all':
		tasks = client.read_all_tasks()
	elif status == 'completed':
		tasks = client.read_all_completed()
	elif status == 'deleted':
		tasks = client.read_all_deleted()
	elif status == 'expired':
		tasks = client.read_all_expired()
	else:
		raise NotImplementedError(status)
	columns = ['n', 'id', 'name', 'status', 'size', 'progress', 'speed', 'date', 'dcid', 'gcid', 'original-url', 'download-url']
	columns = filter(lambda k: getattr(args, k), columns)
	from lixian_colors import colors
	for i, t in enumerate(tasks):
		status_colors = {
				'waiting': 'yellow',
				'downloading': 'magenta',
				'completed':'green',
				'pending':'cyan',
				'failed':'red',
		}
		c = status_colors[t['status_text']]
		with colors(args.colors).ansi(c)():
			for k in columns:
				if k == 'n':
					if not parent_ids:
						print '#%d' % t['#'],
				elif k == 'id':
					print t.get('index', t['id']),
				elif k == 'name':
					print t['name'].encode(default_encoding),
				elif k == 'status':
					with colors(args.colors).bold():
						print t['status_text'],
				elif k == 'size':
					if args.format_size:
						from lixian_util import format_size
						print format_size(t['size']),
					else:
						print t['size'],
				elif k == 'progress':
					print t['progress'],
				elif k == 'speed':
					print t['speed'],
				elif k == 'date':
					print t['date'],
				elif k == 'dcid':
					print t['dcid'],
				elif k == 'gcid':
					print t['gcid'],
				elif k == 'original-url':
					print t['original_url'],
				elif k == 'download-url':
					print t['xunlei_url'],
				else:
					raise NotImplementedError(k)
			print