dialogs.c

来自「elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, el」· C语言 代码 · 共 826 行 · 第 1/2 页

C
826
字号
/* BitTorrent specific dialogs */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "elinks.h"#include "dialogs/document.h"#include "dialogs/download.h"#include "dialogs/progress.h"#include "intl/gettext/libintl.h"#include "mime/mime.h"#include "network/connection.h"#include "network/state.h"#include "protocol/bittorrent/bencoding.h"#include "protocol/bittorrent/bittorrent.h"#include "protocol/bittorrent/common.h"#include "protocol/bittorrent/piececache.h"#include "protocol/uri.h"#include "session/download.h"#include "session/session.h"#include "terminal/draw.h"#include "util/conv.h"#include "util/string.h"struct bittorrent_download_info {	struct list_head labels;	/* -> struct string_list_item */	unsigned char *name;	int *selection;	size_t size;};static voiddone_bittorrent_download_info(struct bittorrent_download_info *info){	free_string_list(&info->labels);	mem_free_if(info->selection);	mem_free_if(info->name);	mem_free(info);}static struct bittorrent_download_info *init_bittorrent_download_info(struct bittorrent_meta *meta){	struct bittorrent_download_info *info;	struct bittorrent_file *file;	size_t max_label = 0;	info = mem_calloc(1, sizeof(*info));	if (!info) return NULL;	init_list(info->labels);	info->name = stracpy(meta->name);	if (!info->name) {		mem_free(info);		return NULL;	}	foreach (file, meta->files) {		struct string string;		int spaces;		if (!init_string(&string))			break;		info->size++;		add_xnum_to_string(&string, file->length);		/*   40 K   file1		 * 2300 MiB file2 */		spaces = string.length - strcspn(string.source, " ") - 1;		add_xchar_to_string(&string, ' ', int_max(4 - spaces, 1));		add_to_string_list(&info->labels, string.source, string.length);		if (string.length > max_label)			max_label = string.length;		done_string(&string);	}	info->selection = mem_calloc(info->size, sizeof(*info->selection));	if (!info->selection || info->size != list_size(&meta->files)) {		done_bittorrent_download_info(info);		return NULL;	}	info->size = 0;	foreach (file, meta->files) {		struct string_list_item *item;		size_t pos = 0;		foreach (item, info->labels)			if (pos++ == info->size)				break;		info->selection[info->size++] = 1;		pos = max_label - item->string.length;		add_to_string(&item->string, file->name);		for (; pos > 0; pos--) {			insert_in_string(&item->string.source, 0, " ", 1);		}	}	return info;}/* Add information from the meta file struct to a string. */static voidadd_bittorrent_meta_to_string(struct string *msg, struct bittorrent_meta *meta,			      struct terminal *term, int add_files){	if (meta->malicious_paths) {		add_format_to_string(msg, "%s\n\n",			_("Warning: potential malicious path detected", term));	}	add_format_to_string(msg, "\n%s: ",		_("Size", term));	add_xnum_to_string(msg,		(off_t) (meta->pieces - 1) * meta->piece_length		+ meta->last_piece_length);	if (meta->last_piece_length == meta->piece_length) {		add_format_to_string(msg, " (%ld * %ld)",			meta->pieces, meta->piece_length);	} else {		add_format_to_string(msg, " (%ld * %ld + %ld)",			meta->pieces - 1, meta->piece_length,			meta->last_piece_length);	}	add_format_to_string(msg, "\n%s: %s",		_("Info hash", term),		get_hexed_bittorrent_id(meta->info_hash));	add_format_to_string(msg, "\n%s: %s",		_("Announce URI", term),		struri(meta->tracker_uris.uris[0]));#ifdef HAVE_STRFTIME	if (meta->creation_date) {		add_format_to_string(msg, "\n%s: ",			_("Creation date", term));		add_date_to_string(msg,			get_opt_str("ui.date_format"),			&meta->creation_date);	}#endif	if (meta->type == BITTORRENT_MULTI_FILE) {		add_format_to_string(msg, "\n%s: %s",			_("Directory", term), meta->name);	}	if (add_files) {		struct bittorrent_download_info *info;		struct string_list_item *item;		info = init_bittorrent_download_info(meta);		if (info) {			add_format_to_string(msg, "\n%s:",				_("Files", term));			foreach (item, info->labels) {				add_format_to_string(msg, "\n  %s",					item->string.source);			}			done_bittorrent_download_info(info);		}	}	if (meta->comment && *meta->comment) {		add_format_to_string(msg, "\n%s:\n %s",		_("Comment", term), meta->comment);	}}/* ************************************************************************** *//* Download dialog button hooks and helpers: *//* ************************************************************************** */voidset_bittorrent_files_for_deletion(struct download *download){	struct bittorrent_connection *bittorrent;	if (!download->conn || !download->conn->info)		return;	bittorrent = download->conn->info;	bittorrent->cache->delete_files = 1;}voidset_bittorrent_notify_on_completion(struct download *download, struct terminal *term){	struct bittorrent_connection *bittorrent;	if (!download->conn || !download->conn->info)		return;	bittorrent = download->conn->info;	bittorrent->cache->notify_complete = 1;	bittorrent->term = term;}voidnotify_bittorrent_download_complete(struct bittorrent_connection *bittorrent){	struct connection *conn = bittorrent->conn;	unsigned char *url = get_uri_string(conn->uri, URI_PUBLIC);	if (!url) return;	assert(bittorrent->term);	info_box(bittorrent->term, MSGBOX_FREE_TEXT,		N_("Download"), ALIGN_CENTER,		msg_text(bittorrent->term, N_("Download complete:\n%s"), url));	mem_free(url);}/* Handler for the Info-button available in the download dialog. */widget_handler_status_Tdlg_show_bittorrent_info(struct dialog_data *dlg_data, struct widget_data *widget_data){	struct file_download *file_download = dlg_data->dlg->udata;	struct download *download = &file_download->download;	struct string msg;	if (download->conn	    && download->conn->info	    && init_string(&msg)) {		struct terminal *term = file_download->term;		struct bittorrent_connection *bittorrent;		enum msgbox_flags flags = MSGBOX_FREE_TEXT;		bittorrent = download->conn->info;		add_bittorrent_meta_to_string(&msg, &bittorrent->meta, term, 1);		if (list_size(&bittorrent->meta.files) > 1)			flags |= MSGBOX_SCROLLABLE;		info_box(term, flags,			 N_("Download info"), ALIGN_LEFT, msg.source);	}	return EVENT_PROCESSED;}/* ************************************************************************** *//* Download status message creation: *//* ************************************************************************** *//* Compose and return the status message about current download speed and * BitTorrent swarm info. It is called fairly often so most values used in here * should be easily accessible. */unsigned char *get_bittorrent_message(struct download *download, struct terminal *term,		       int wide, int full, unsigned char *separator){	/* Cooresponds to the connection mode enum. */	static unsigned char *modes_text[] = {		N_("downloading (random)"),		N_("downloading (rarest first)"),		N_("downloading (end game)"),		N_("seeding"),	};	struct bittorrent_connection *bittorrent;	struct bittorrent_peer_connection *peer;	struct string string;	unsigned char *msg;	uint32_t value;	if (!download->conn	    || !download->conn->info	    || !init_string(&string))		return NULL;	/* Get the download speed information message. */	msg = get_progress_msg(download->progress, term, wide, full, separator);	if (!msg) {		done_string(&string);		return NULL;	}	bittorrent = download->conn->info;	add_to_string(&string, msg);	mem_free(msg);	/* Status: */	add_format_to_string(&string, "\n\n%s: %s",		_("Status", term), _(modes_text[bittorrent->mode], term));	if (bittorrent->cache->partial)		add_format_to_string(&string, " (%s)",			_("partial", term));	/* Peers: */	add_format_to_string(&string, "\n%s: ", _("Peers", term));	value = list_size(&bittorrent->peers);	add_format_to_string(&string,		n_("%u connection", "%u connections", value, term), value);	add_to_string(&string, ", ");	value = 0;	foreach (peer, bittorrent->peers)		if (peer->remote.seeder)			value++;	add_format_to_string(&string,		n_("%u seeder", "%u seeders", value, term), value);	add_to_string(&string, ", ");	value = list_size(&bittorrent->peer_pool);	add_format_to_string(&string,		n_("%u available", "%u available", value, term), value);	/* Swarm info: */	if (bittorrent->complete > 0 || bittorrent->incomplete > 0) {		add_format_to_string(&string, "\n%s: ", _("Swarm info", term));		if (bittorrent->complete > 0) {			value = bittorrent->complete;			add_format_to_string(&string,				n_("%u seeder", "%u seeders", value, term), value);		}		if (bittorrent->incomplete > 0) {			if (bittorrent->complete > 0)				add_to_string(&string, ", ");			value = bittorrent->incomplete;			add_format_to_string(&string,				n_("%u downloader", "%u downloaders", value, term), value);		}	}	/* Upload: */	add_format_to_string(&string, "\n%s: ", _("Upload", term));	add_xnum_to_string(&string, bittorrent->uploaded);	add_to_string(&string, ", ");	add_xnum_to_string(&string, bittorrent->upload_progress.current_speed);	add_to_string(&string, "/s, ");	add_xnum_to_string(&string, bittorrent->upload_progress.average_speed);	add_format_to_string(&string, "/s %s", _("average", term));	if (bittorrent->uploaded < bittorrent->downloaded) {		struct progress *progress = &bittorrent->upload_progress;		add_format_to_string(&string, ", %s ", _("1:1 in", term));		add_timeval_to_string(&string, &progress->estimated_time);	}	/* Sharing: */	add_format_to_string(&string, "\n%s: ", _("Sharing", term));	if (bittorrent->downloaded) {		add_format_to_string(&string, "%.3f", bittorrent->sharing_rate);	} else {		/* Idea taken from btdownloadcurses .. 'oo' means infinite. */		add_to_string(&string, "oo");	}	add_to_string(&string, " (");	add_xnum_to_string(&string, bittorrent->uploaded);	add_format_to_string(&string, " %s / ", _("uploaded", term));	add_xnum_to_string(&string, bittorrent->downloaded);	add_format_to_string(&string, " %s)", _("downloaded", term));	/* Pieces: */	add_format_to_string(&string, "\n%s: ", _("Pieces", term));	value = bittorrent->cache->completed_pieces;	add_format_to_string(&string,		n_("%u completed", "%u completed", value, term), value);	value = bittorrent->cache->loading_pieces;	if (value) {		add_to_string(&string, ", ");		add_format_to_string(&string,			n_("%u in progress", "%u in progress", value, term), value);	}	if (bittorrent->cache->partial)		value = bittorrent->cache->partial_pieces;	else		value = bittorrent->meta.pieces;	value -= bittorrent->cache->completed_pieces;	if (value) {		add_to_string(&string, ", ");		add_format_to_string(&string,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?