mirror of
https://github.com/transmission/transmission.git
synced 2026-02-15 07:26:49 +00:00
(trunk, libT) #4682 'Add return id from duplicate torrent torrent-add rpc' -- added.
This commit is contained in:
@@ -222,7 +222,6 @@ getConfigDir (int argc, const char ** argv)
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{
|
||||
int error;
|
||||
tr_session * h;
|
||||
tr_ctor * ctor;
|
||||
tr_torrent * tor = NULL;
|
||||
@@ -310,7 +309,7 @@ main (int argc, char ** argv)
|
||||
|
||||
tr_free (fileContents);
|
||||
|
||||
tor = tr_torrentNew (ctor, &error);
|
||||
tor = tr_torrentNew (ctor, NULL, NULL);
|
||||
tr_ctorFree (ctor);
|
||||
if (!tor)
|
||||
{
|
||||
|
||||
@@ -263,7 +263,7 @@ onFileAdded (tr_session * session, const char * dir, const char * file)
|
||||
|
||||
if (!err)
|
||||
{
|
||||
tr_torrentNew (ctor, &err);
|
||||
tr_torrentNew (ctor, &err, NULL);
|
||||
|
||||
if (err == TR_PARSE_ERR)
|
||||
tr_logAddError ("Error parsing .torrent file \"%s\"", file);
|
||||
|
||||
@@ -382,10 +382,13 @@
|
||||
Set multiple cookies like this: "name1=content1; name2=content2;" etc.
|
||||
<http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTCOOKIE>
|
||||
|
||||
Response arguments: on success, a "torrent-added" object in the
|
||||
Response arguments: On success, a "torrent-added" object in the
|
||||
form of one of 3.3's tr_info objects with the
|
||||
fields for id, name, and hashString.
|
||||
|
||||
On failure due to a duplicate torrent existing,
|
||||
a "torrent-duplicate" object in the same form.
|
||||
|
||||
3.5. Removing a Torrent
|
||||
|
||||
Method name: "torrent-remove"
|
||||
@@ -761,6 +764,7 @@
|
||||
15 | 2.80 | yes | torrent-get | new arg "etaIdle"
|
||||
| | yes | torrent-rename-path | new method
|
||||
| | yes | free-space | new method
|
||||
| | yes | torrent-add | new return return arg "torrent-duplicate"
|
||||
|
||||
5.1. Upcoming Breakage
|
||||
|
||||
|
||||
@@ -186,6 +186,7 @@ sourceChanged (GtkFileChooserButton * b, gpointer gdata)
|
||||
{
|
||||
int err = 0;
|
||||
int new_file = 0;
|
||||
int duplicate_id = 0;
|
||||
tr_torrent * torrent;
|
||||
|
||||
if (filename && (!o->filename || !tr_is_same_file (filename, o->filename)))
|
||||
@@ -200,14 +201,21 @@ sourceChanged (GtkFileChooserButton * b, gpointer gdata)
|
||||
tr_ctorSetPaused (o->ctor, TR_FORCE, TRUE);
|
||||
tr_ctorSetDeleteSource (o->ctor, FALSE);
|
||||
|
||||
if ((torrent = tr_torrentNew (o->ctor, &err)))
|
||||
if ((torrent = tr_torrentNew (o->ctor, &err, &duplicate_id)))
|
||||
{
|
||||
removeOldTorrent (o);
|
||||
o->tor = torrent;
|
||||
}
|
||||
else if (new_file)
|
||||
{
|
||||
gtr_add_torrent_error_dialog (GTK_WIDGET (b), err, o->filename);
|
||||
tr_torrent * tor;
|
||||
|
||||
if (duplicate_id)
|
||||
tor = gtr_core_find_torrent (o->core, duplicate_id);
|
||||
else
|
||||
tor = NULL;
|
||||
|
||||
gtr_add_torrent_error_dialog (GTK_WIDGET (b), err, tor, o->filename);
|
||||
}
|
||||
|
||||
updateTorrent (o);
|
||||
|
||||
@@ -1102,7 +1102,6 @@ gtr_core_add_torrent (TrCore * core, tr_torrent * tor, gboolean do_notify)
|
||||
static tr_torrent *
|
||||
core_create_new_torrent (TrCore * core, tr_ctor * ctor)
|
||||
{
|
||||
int errcode = 0;
|
||||
tr_torrent * tor;
|
||||
bool do_trash = false;
|
||||
tr_session * session = gtr_core_session (core);
|
||||
@@ -1111,7 +1110,7 @@ core_create_new_torrent (TrCore * core, tr_ctor * ctor)
|
||||
* doesn't have any concept of the glib trash API */
|
||||
tr_ctorGetDeleteSource (ctor, &do_trash);
|
||||
tr_ctorSetDeleteSource (ctor, FALSE);
|
||||
tor = tr_torrentNew (ctor, &errcode);
|
||||
tor = tr_torrentNew (ctor, NULL, NULL);
|
||||
|
||||
if (tor && do_trash)
|
||||
{
|
||||
@@ -1127,7 +1126,7 @@ core_create_new_torrent (TrCore * core, tr_ctor * ctor)
|
||||
}
|
||||
}
|
||||
|
||||
return tor;
|
||||
return tor;
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
20
gtk/util.c
20
gtk/util.c
@@ -217,21 +217,21 @@ getWindow (GtkWidget * w)
|
||||
}
|
||||
|
||||
void
|
||||
gtr_add_torrent_error_dialog (GtkWidget * child, int err, const char * file)
|
||||
gtr_add_torrent_error_dialog (GtkWidget * child,
|
||||
int err,
|
||||
tr_torrent * duplicate_torrent,
|
||||
const char * filename)
|
||||
{
|
||||
char * secondary;
|
||||
const char * fmt;
|
||||
GtkWidget * w;
|
||||
GtkWindow * win = getWindow (child);
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case TR_PARSE_ERR: fmt = _("The torrent file \"%s\" contains invalid data."); break;
|
||||
case TR_PARSE_DUPLICATE: fmt = _("The torrent file \"%s\" is already in use."); break;
|
||||
default: fmt = _("The torrent file \"%s\" encountered an unknown error."); break;
|
||||
}
|
||||
|
||||
secondary = g_strdup_printf (fmt, file);
|
||||
if (err == TR_PARSE_ERR)
|
||||
secondary = g_strdup_printf (_("The torrent file \"%s\" contains invalid data."), filename);
|
||||
else if (err == TR_PARSE_DUPLICATE)
|
||||
secondary = g_strdup_printf (_("The torrent file \"%s\" is already in use by \"%s.\""), filename, tr_torrentName (duplicate_torrent));
|
||||
else
|
||||
secondary = g_strdup_printf (_("The torrent file \"%s\" encountered an unknown error."), filename);
|
||||
|
||||
w = gtk_message_dialog_new (win,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
|
||||
@@ -125,6 +125,7 @@ void gtr_http_failure_dialog (GtkWidget * parent, const char * url, long respons
|
||||
|
||||
void gtr_add_torrent_error_dialog (GtkWidget * window_or_child,
|
||||
int err,
|
||||
tr_torrent * duplicate_torrent,
|
||||
const char * filename);
|
||||
|
||||
/* pop up the context menu if a user right-clicks.
|
||||
|
||||
@@ -327,7 +327,7 @@ libttest_zero_torrent_init (tr_session * session)
|
||||
|
||||
/* create the torrent */
|
||||
err = 0;
|
||||
tor = tr_torrentNew (ctor, &err);
|
||||
tor = tr_torrentNew (ctor, &err, NULL);
|
||||
assert (!err);
|
||||
|
||||
/* cleanup */
|
||||
|
||||
@@ -344,6 +344,7 @@ static const struct tr_key_struct my_static[] =
|
||||
{ "torrent-complete-notification-enabled", 37 },
|
||||
{ "torrent-complete-sound-command", 30 },
|
||||
{ "torrent-complete-sound-enabled", 30 },
|
||||
{ "torrent-duplicate", 17 },
|
||||
{ "torrent-get", 11 },
|
||||
{ "torrent-set", 11 },
|
||||
{ "torrent-set-location", 20 },
|
||||
|
||||
@@ -354,6 +354,7 @@ enum
|
||||
TR_KEY_torrent_complete_notification_enabled,
|
||||
TR_KEY_torrent_complete_sound_command,
|
||||
TR_KEY_torrent_complete_sound_enabled,
|
||||
TR_KEY_torrent_duplicate,
|
||||
TR_KEY_torrent_get,
|
||||
TR_KEY_torrent_set,
|
||||
TR_KEY_torrent_set_location,
|
||||
|
||||
@@ -133,7 +133,7 @@ create_torrent_from_base64_metainfo (tr_ctor * ctor, const char * metainfo_base6
|
||||
|
||||
/* create the torrent */
|
||||
err = 0;
|
||||
tor = tr_torrentNew (ctor, &err);
|
||||
tor = tr_torrentNew (ctor, &err, NULL);
|
||||
assert (!err);
|
||||
|
||||
/* cleanup */
|
||||
|
||||
@@ -1515,33 +1515,46 @@ blocklistUpdate (tr_session * session,
|
||||
static void
|
||||
addTorrentImpl (struct tr_rpc_idle_data * data, tr_ctor * ctor)
|
||||
{
|
||||
int err = 0;
|
||||
const char * result = NULL;
|
||||
tr_torrent * tor = tr_torrentNew (ctor, &err);
|
||||
int err;
|
||||
int duplicate_id;
|
||||
const char * result;
|
||||
tr_torrent * tor;
|
||||
tr_quark key;
|
||||
|
||||
tr_ctorFree (ctor);
|
||||
err = 0;
|
||||
duplicate_id = 0;
|
||||
tor = tr_torrentNew (ctor, &err, &duplicate_id);
|
||||
tr_ctorFree (ctor);
|
||||
|
||||
if (tor)
|
||||
if (!err)
|
||||
{
|
||||
tr_variant fields;
|
||||
tr_variantInitList (&fields, 3);
|
||||
tr_variantListAddStr (&fields, "id");
|
||||
tr_variantListAddStr (&fields, "name");
|
||||
tr_variantListAddStr (&fields, "hashString");
|
||||
addInfo (tor, tr_variantDictAdd (data->args_out, TR_KEY_torrent_added), &fields);
|
||||
notify (data->session, TR_RPC_TORRENT_ADDED, tor);
|
||||
tr_variantFree (&fields);
|
||||
key = TR_KEY_torrent_added;
|
||||
result = NULL;
|
||||
}
|
||||
else if (err == TR_PARSE_DUPLICATE)
|
||||
else if (err == TR_PARSE_ERR)
|
||||
{
|
||||
result = "duplicate torrent";
|
||||
result = "invalid or corrupt torrent file";
|
||||
}
|
||||
else if (err == TR_PARSE_ERR)
|
||||
else if (err == TR_PARSE_DUPLICATE)
|
||||
{
|
||||
result = "invalid or corrupt torrent file";
|
||||
tor = tr_torrentFindFromId (data->session, duplicate_id);
|
||||
key = TR_KEY_torrent_duplicate;
|
||||
result = "duplicate torrent";
|
||||
}
|
||||
|
||||
tr_idle_function_done (data, result);
|
||||
if (tor != NULL)
|
||||
{
|
||||
tr_variant fields;
|
||||
tr_variantInitList (&fields, 3);
|
||||
tr_variantListAddStr (&fields, "id");
|
||||
tr_variantListAddStr (&fields, "name");
|
||||
tr_variantListAddStr (&fields, "hashString");
|
||||
addInfo (tor, tr_variantDictAdd (data->args_out, key), &fields);
|
||||
notify (data->session, TR_RPC_TORRENT_ADDED, tor);
|
||||
tr_variantFree (&fields);
|
||||
}
|
||||
|
||||
tr_idle_function_done (data, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1937,7 +1937,7 @@ sessionLoadTorrents (void * vdata)
|
||||
tr_torrent * tor;
|
||||
char * path = tr_buildPath (dirname, d->d_name, NULL);
|
||||
tr_ctorSetMetainfoFromFile (data->ctor, path);
|
||||
if ((tor = tr_torrentNew (data->ctor, NULL)))
|
||||
if ((tor = tr_torrentNew (data->ctor, NULL, NULL)))
|
||||
{
|
||||
tr_list_prepend (&list, tor);
|
||||
++n;
|
||||
|
||||
@@ -971,15 +971,18 @@ torrentInit (tr_torrent * tor, const tr_ctor * ctor)
|
||||
}
|
||||
|
||||
static tr_parse_result
|
||||
torrentParseImpl (const tr_ctor * ctor, tr_info * setmeInfo,
|
||||
bool * setmeHasInfo, int * dictLength)
|
||||
torrentParseImpl (const tr_ctor * ctor,
|
||||
tr_info * setmeInfo,
|
||||
bool * setmeHasInfo,
|
||||
int * dictLength,
|
||||
int * setme_duplicate_id)
|
||||
{
|
||||
int doFree;
|
||||
bool didParse;
|
||||
bool hasInfo = false;
|
||||
tr_info tmp;
|
||||
bool doFree;
|
||||
bool didParse;
|
||||
bool hasInfo = false;
|
||||
tr_info tmp;
|
||||
const tr_variant * metainfo;
|
||||
tr_session * session = tr_ctorGetSession (ctor);
|
||||
tr_session * session = tr_ctorGetSession (ctor);
|
||||
tr_parse_result result = TR_PARSE_OK;
|
||||
|
||||
if (setmeInfo == NULL)
|
||||
@@ -999,8 +1002,18 @@ torrentParseImpl (const tr_ctor * ctor, tr_info * setmeInfo,
|
||||
if (didParse && hasInfo && !tr_getBlockSize (setmeInfo->pieceSize))
|
||||
result = TR_PARSE_ERR;
|
||||
|
||||
if (didParse && session && tr_torrentExists (session, setmeInfo->hash))
|
||||
result = TR_PARSE_DUPLICATE;
|
||||
if (didParse && session && (result == TR_PARSE_OK))
|
||||
{
|
||||
const tr_torrent * const tor = tr_torrentFindFromHash (session, setmeInfo->hash);
|
||||
|
||||
if (tor != NULL)
|
||||
{
|
||||
result = TR_PARSE_DUPLICATE;
|
||||
|
||||
if (setme_duplicate_id != NULL)
|
||||
*setme_duplicate_id = tr_torrentId (tor);
|
||||
}
|
||||
}
|
||||
|
||||
if (doFree)
|
||||
tr_metainfoFree (setmeInfo);
|
||||
@@ -1014,40 +1027,42 @@ torrentParseImpl (const tr_ctor * ctor, tr_info * setmeInfo,
|
||||
tr_parse_result
|
||||
tr_torrentParse (const tr_ctor * ctor, tr_info * setmeInfo)
|
||||
{
|
||||
return torrentParseImpl (ctor, setmeInfo, NULL, NULL);
|
||||
return torrentParseImpl (ctor, setmeInfo, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
tr_torrent *
|
||||
tr_torrentNew (const tr_ctor * ctor, int * setmeError)
|
||||
tr_torrentNew (const tr_ctor * ctor, int * setme_error, int * setme_duplicate_id)
|
||||
{
|
||||
int len;
|
||||
bool hasInfo;
|
||||
tr_info tmpInfo;
|
||||
tr_parse_result r;
|
||||
tr_torrent * tor = NULL;
|
||||
int len;
|
||||
bool hasInfo;
|
||||
tr_info tmpInfo;
|
||||
tr_parse_result r;
|
||||
tr_torrent * tor = NULL;
|
||||
|
||||
assert (ctor != NULL);
|
||||
assert (tr_isSession (tr_ctorGetSession (ctor)));
|
||||
assert (ctor != NULL);
|
||||
assert (tr_isSession (tr_ctorGetSession (ctor)));
|
||||
|
||||
r = torrentParseImpl (ctor, &tmpInfo, &hasInfo, &len);
|
||||
if (r == TR_PARSE_OK)
|
||||
r = torrentParseImpl (ctor, &tmpInfo, &hasInfo, &len, setme_duplicate_id);
|
||||
if (r == TR_PARSE_OK)
|
||||
{
|
||||
tor = tr_new0 (tr_torrent, 1);
|
||||
tor->info = tmpInfo;
|
||||
if (hasInfo)
|
||||
tor->infoDictLength = len;
|
||||
torrentInit (tor, ctor);
|
||||
tor = tr_new0 (tr_torrent, 1);
|
||||
tor->info = tmpInfo;
|
||||
|
||||
if (hasInfo)
|
||||
tor->infoDictLength = len;
|
||||
|
||||
torrentInit (tor, ctor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r == TR_PARSE_DUPLICATE)
|
||||
tr_metainfoFree (&tmpInfo);
|
||||
if (r == TR_PARSE_DUPLICATE)
|
||||
tr_metainfoFree (&tmpInfo);
|
||||
|
||||
if (setmeError)
|
||||
*setmeError = r;
|
||||
if (setme_error != NULL)
|
||||
*setme_error = r;
|
||||
}
|
||||
|
||||
return tor;
|
||||
return tor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1061,12 +1061,21 @@ tr_parse_result tr_torrentParse (const tr_ctor * ctor,
|
||||
void tr_metainfoFree (tr_info * inf);
|
||||
|
||||
|
||||
/** Instantiate a single torrent.
|
||||
@return 0 on success,
|
||||
TR_EINVALID if the torrent couldn't be parsed, or
|
||||
TR_EDUPLICATE if there's already a matching torrent object. */
|
||||
/**
|
||||
* Instantiate a single torrent.
|
||||
*
|
||||
* Returns a pointer to the torrent on success, or NULL on failure.
|
||||
*
|
||||
* @param setme_error: TR_PARSE_ERR if the parsing failed;
|
||||
* TR_PARSE_OK if parsing succeeded and it's not a duplicate;
|
||||
* TR_PARSE_DUPLICATE if parsing succeeded but it's a duplicate.
|
||||
*
|
||||
* @param setme_duplicate_id: when setmeError is TR_PARSE_DUPLICATE,
|
||||
* this field is set to the duplicate torrent's id.
|
||||
*/
|
||||
tr_torrent * tr_torrentNew (const tr_ctor * ctor,
|
||||
int * setmeError);
|
||||
int * setme_error,
|
||||
int * setme_duplicate_id);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -1666,7 +1666,7 @@ int trashDataFile(const char * filename)
|
||||
result = tr_ctorSetMetainfoFromHash(ctor, [hashString UTF8String]);
|
||||
|
||||
if (result == TR_PARSE_OK)
|
||||
fHandle = tr_torrentNew(ctor, NULL);
|
||||
fHandle = tr_torrentNew(ctor, NULL, NULL);
|
||||
|
||||
tr_ctorFree(ctor);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user