]> granicus.if.org Git - transmission/commitdiff
(trunk, libT) #4682 'Add return id from duplicate torrent torrent-add rpc' -- added.
authorJordan Lee <jordan@transmissionbt.com>
Wed, 22 May 2013 20:35:38 +0000 (20:35 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Wed, 22 May 2013 20:35:38 +0000 (20:35 +0000)
16 files changed:
cli/cli.c
daemon/daemon.c
extras/rpc-spec.txt
gtk/open-dialog.c
gtk/tr-core.c
gtk/util.c
gtk/util.h
libtransmission/libtransmission-test.c
libtransmission/quark.c
libtransmission/quark.h
libtransmission/rename-test.c
libtransmission/rpcimpl.c
libtransmission/session.c
libtransmission/torrent.c
libtransmission/transmission.h
macosx/Torrent.m

index a1eca56d70eaf5533b759d5654304110d77e1125..ac2cf52417496975bb313892f4a112124b9f6d66 100644 (file)
--- a/cli/cli.c
+++ b/cli/cli.c
@@ -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)
     {
index f0c7ab911a8701daf14e9fa8fb4064da170c6fbb..abdb50ca316d07d2214c712dd3d7c196f2a69534 100644 (file)
@@ -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);
index fed41124a33de8048c9a195da4b831dbc23627f5..2d06c2448d75b3bac90f8620b5a3914effd1d79f 100644 (file)
    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"
    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
 
index 8633a2e6906c21861e75efbbf113170bd26c1c0e..89904ef4fa4c45bb19a874f293847d7c3f79a6ac 100644 (file)
@@ -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);
index 5b1c4e6dc36eb6e9537c2a6a43e6d4c92cd4a2a2..75d196e72d16f49cc1014f9b66410884f8e3b88f 100644 (file)
@@ -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
index a3f0486ab73fc47caa0e32aca6e2b5b244f16a0d..6c89f717e7fdc062bf97939b057e2e20e29514e7 100644 (file)
@@ -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,
index da6d0fe0f6c1b2f35fdc0cfd38999762b07603bf..caaf88845dcc127aa68e4e25d62e010f96241a2d 100644 (file)
@@ -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.
index 7353731e35e7c1a4bd265bdde15a23204b001845..a0cf1f52921c51352271b0ac2bb1620e37c16b27 100644 (file)
@@ -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 */
index dbd7f9de5739334655471834f092f32876ea1de2..66ebdc7b99cd83ba12ffc0210c9ee38f08bab9b8 100644 (file)
@@ -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 },
index 39fcd539310037b5536e17baccd1f8ed4947db94..d84268d10fae96b2a95b5513a7f68020b33b071e 100644 (file)
@@ -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,
index d9599996791eb6f3a24102f60d6ad3fbff14d698..127bafd769fac96b4fa294b2fac8f04ca110882a 100644 (file)
@@ -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 */
index 1b3cc052392c83d6d09b2433d15fcdbdf1b71084..fe79e8c37757bcd6cb979a739ca285b7ed21e918 100644 (file)
@@ -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);
 }
 
 
index d3b50bfa2d1e70be051b920b53800c5731a6a2d8..e3713f3f5dc0193e05476d9a594f20b6888a0b9f 100644 (file)
@@ -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;
index 02f2092f3d5083f10d83e8507dad31709c05e3a2..4a3e94d14309a5070497f74d1cedaff7a6c1762e 100644 (file)
@@ -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)
-{
-    int             doFree;
-    bool            didParse;
-    bool            hasInfo = false;
-    tr_info         tmp;
+torrentParseImpl (const tr_ctor  * ctor,
+                  tr_info        * setmeInfo,
+                  bool           * setmeHasInfo,
+                  int            * dictLength,
+                  int            * setme_duplicate_id)
+{
+    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;
 }
 
 /**
index 00389fe1e46e076c7b48d1ada734e6840e8735bf..4d3fd82baf1a24cf3d7230c49435b8769ffa1fb8 100644 (file)
@@ -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);
 
 /** @} */
 
index 3fb0e32f1f21de7ff610c09cf0baf3d06261af04..77cd050ab55a31145adeb8faf187fb48052039ba 100644 (file)
@@ -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);