linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #05452
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2883: friendly magnet links
------------------------------------------------------------
revno: 2883
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-03-18 18:52:34 +0100
message:
friendly magnet links
added:
dcpp/Magnet.cpp
dcpp/Magnet.h
modified:
dcpp/ChatMessage.cpp
win32/WinUtil.cpp
win32/WinUtil.h
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/ChatMessage.cpp'
--- dcpp/ChatMessage.cpp 2012-03-18 15:43:00 +0000
+++ dcpp/ChatMessage.cpp 2012-03-18 17:52:34 +0000
@@ -21,6 +21,7 @@
#include "Client.h"
#include "format.h"
+#include "Magnet.h"
#include "OnlineUser.h"
#include "SettingsManager.h"
#include "SimpleXML.h"
@@ -106,13 +107,15 @@
/* link formatting - optimize the lookup a bit by using the fact that every link identifier
(except www ones) contains a colon. */
/// @todo add support for spaces within links enclosed by brackets / quotes (see URI RFC)
- /// @todo friendly magnet links
- auto addLink = [&tmp, &xmlTmp, &tags](size_t begin, size_t end) {
- Tag openingTag = { "<a href=\"" + SimpleXML::escape(tmp.substr(begin, end - begin), xmlTmp, true) + "\">", true, end },
+ auto addLinkStr = [&xmlTmp, &tags](size_t begin, size_t end, const string& link) {
+ Tag openingTag = { "<a href=\"" + SimpleXML::escape(link, xmlTmp, true) + "\">", true, end },
closingTag = { "</a>", false, begin };
tags[begin] = std::move(openingTag);
tags[end] = std::move(closingTag);
};
+ auto addLink = [&tmp, &addLinkStr](size_t begin, size_t end) {
+ addLinkStr(begin, end, tmp.substr(begin, end - begin));
+ };
static const string delimiters = " \t\r\n<>\"";
@@ -126,12 +129,28 @@
if(i > 0 && (
(i + 4 < n && tmp[i + 1] == '/' && tmp[i + 2] == '/') || // "http://", etc
- (i == begin + 6 && !tmp.compare(begin, 6, "magnet")) ||
- (i == begin + 6 && !tmp.compare(begin, 6, "mailto"))))
+ (i == begin + 6 && i + 1 <= n && !tmp.compare(begin, 6, "mailto"))))
{
addLink(begin, end);
i = end;
+ } else if(i == begin + 6 && i + 2 <= n && !tmp.compare(begin, 6, "magnet") && tmp[i + 1] == '?') {
+ string link = tmp.substr(begin, end - begin), hash, name, key;
+ if(Magnet::parseUri(link, hash, name, key)) {
+
+ if(!name.empty()) {
+ // magnet link: replace with the friendly name
+ tmp.replace(begin, end - begin, name);
+ end += name.size() - link.size();
+ }
+
+ addLinkStr(begin, end, link);
+ i = end;
+
+ } else {
+ ++i;
+ }
+
} else {
++i;
}
=== added file 'dcpp/Magnet.cpp'
--- dcpp/Magnet.cpp 1970-01-01 00:00:00 +0000
+++ dcpp/Magnet.cpp 2012-03-18 17:52:34 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdinc.h"
+#include "Magnet.h"
+
+#include "StringTokenizer.h"
+#include "Text.h"
+#include "Util.h"
+
+namespace dcpp {
+
+using std::map;
+
+bool Magnet::parseUri(const string& uri, string& hash, string& name, string& key) {
+ if(Util::strnicmp(uri.c_str(), "magnet:?", 8)) {
+ return false;
+ }
+
+ // official types that are of interest to us
+ // xt = exact topic
+ // xs = exact substitute
+ // as = acceptable substitute
+ // dn = display name
+
+ StringTokenizer<string> mag(uri.substr(8), '&');
+ map<string, string> hashes;
+ string type, param;
+ for(auto& idx: mag.getTokens()) {
+
+ // break into pairs
+ auto pos = idx.find('=');
+ if(pos != string::npos) {
+ type = Text::toLower(Util::encodeURI(idx.substr(0, pos), true));
+ param = Util::encodeURI(idx.substr(pos + 1), true);
+ } else {
+ type = Util::encodeURI(idx, true);
+ param.clear();
+ }
+
+ // extract what is of value
+ if(param.size() == 85 && Util::strnicmp(param.c_str(), "urn:bitprint:", 13) == 0) {
+ hashes[type] = param.substr(46);
+ } else if(param.size() == 54 && Util::strnicmp(param.c_str(), "urn:tree:tiger:", 15) == 0) {
+ hashes[type] = param.substr(15);
+ } else if(param.size() == 55 && Util::strnicmp(param.c_str(), "urn:tree:tiger/:", 16) == 0) {
+ hashes[type] = param.substr(16);
+ } else if(param.size() == 59 && Util::strnicmp(param.c_str(), "urn:tree:tiger/1024:", 20) == 0) {
+ hashes[type] = param.substr(20);
+ } else if(type.size() == 2 && Util::strnicmp(type.c_str(), "dn", 2) == 0) {
+ name = param;
+ } else if(type.size() == 2 && Util::strnicmp(type.c_str(), "kt", 2) == 0) {
+ key = param;
+ }
+ }
+
+ // pick the most authoritative hash out of all of them.
+ if(hashes.find("xt") != hashes.end()) {
+ hash = hashes["xt"];
+ } else if(hashes.find("xs") != hashes.end()) {
+ hash = hashes["xs"];
+ } else if(hashes.find("as") != hashes.end()) {
+ hash = hashes["as"];
+ }
+
+ if(!hash.empty() || !key.empty()) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace dcpp
=== added file 'dcpp/Magnet.h'
--- dcpp/Magnet.h 1970-01-01 00:00:00 +0000
+++ dcpp/Magnet.h 2012-03-18 17:52:34 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_DCPP_MAGNET_H
+#define DCPLUSPLUS_DCPP_MAGNET_H
+
+#include "forward.h"
+
+#include <string>
+
+namespace dcpp {
+
+using std::string;
+
+struct Magnet {
+ static bool parseUri(const string& uri, string& hash, string& name, string& key);
+};
+
+} // namespace dcpp
+
+#endif
=== modified file 'win32/WinUtil.cpp'
--- win32/WinUtil.cpp 2012-03-11 18:06:18 +0000
+++ win32/WinUtil.cpp 2012-03-18 17:52:34 +0000
@@ -30,6 +30,7 @@
#include <dcpp/File.h>
#include <dcpp/HashManager.h>
#include <dcpp/LogManager.h>
+#include <dcpp/Magnet.h>
#include <dcpp/QueueManager.h>
#include <dcpp/SettingsManager.h>
#include <dcpp/ShareManager.h>
@@ -1421,81 +1422,20 @@
Util::strnicmp(str.c_str(), _T("mailto:"), 7) == 0) {
openLink(str);
return true;
+
} else if(host == "magnet") {
- parseMagnetUri(str);
- return true;
- }
-
- return false;
-}
-
-void WinUtil::parseMagnetUri(const tstring& aUrl, bool /*aOverride*/) {
- // official types that are of interest to us
- // xt = exact topic
- // xs = exact substitute
- // as = acceptable substitute
- // dn = display name
- if(Util::strnicmp(aUrl.c_str(), _T("magnet:?"), 8) == 0) {
- LogManager::getInstance()->message(str(F_("MAGNET Link detected: %1%") % Text::fromT(aUrl)));
- StringTokenizer<tstring> mag(aUrl.substr(8), _T('&'));
- typedef map<tstring, tstring> MagMap;
- MagMap hashes;
- tstring fname, fhash, type, param, fkey;
- for(auto& idx: mag.getTokens()) {
- // break into pairs
- string::size_type pos = idx.find(_T('='));
- if(pos != string::npos) {
- type = Text::toT(Text::toLower(Util::encodeURI(Text::fromT(idx.substr(0, pos)), true)));
- param = Text::toT(Util::encodeURI(Text::fromT(idx.substr(pos + 1)), true));
- } else {
- type = Text::toT(Util::encodeURI(Text::fromT(idx), true));
- param.clear();
- }
- // extract what is of value
- if(param.length() == 85 && Util::strnicmp(param.c_str(), _T("urn:bitprint:"), 13) == 0) {
- hashes[type] = param.substr(46);
- } else if(param.length() == 54 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger:"), 15) == 0) {
- hashes[type] = param.substr(15);
- } else if(param.length() == 55 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger/:"), 16) == 0) {
- hashes[type] = param.substr(16);
- } else if(param.length() == 59 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger/1024:"), 20) == 0) {
- hashes[type] = param.substr(20);
- } else if(type.length() == 2 && Util::strnicmp(type.c_str(), _T("dn"), 2) == 0) {
- fname = param;
- } else if(type.length() == 2 && Util::strnicmp(type.c_str(), _T("kt"), 2) == 0) {
- fkey = param;
- }
- }
- // pick the most authoritative hash out of all of them.
- if(hashes.find(_T("as")) != hashes.end()) {
- fhash = hashes[_T("as")];
- }
- if(hashes.find(_T("xs")) != hashes.end()) {
- fhash = hashes[_T("xs")];
- }
- if(hashes.find(_T("xt")) != hashes.end()) {
- fhash = hashes[_T("xt")];
- }
- if(!fhash.empty() || !fkey.empty()) {
- // ok, we have a hash, and maybe a filename.
- //if(!BOOLSETTING(MAGNET_ASK)) {
- // switch(SETTING(MAGNET_ACTION)) {
- // case SettingsManager::MAGNET_AUTO_DOWNLOAD:
- // break;
- // case SettingsManager::MAGNET_AUTO_SEARCH:
- // SearchFrame::openWindow(mainWindow->getTabView(), fhash, SearchManager::TYPE_TTH);
- // break;
- // };
- //} else {
- // use aOverride to force the display of the dialog. used for auto-updating
- MagnetDlg(mainWindow, fhash, fname, fkey).run();
- //}
+ string hash, name, key;
+ if(Magnet::parseUri(Text::fromT(str), hash, name, key)) {
+ MagnetDlg(mainWindow, Text::toT(hash), Text::toT(name), Text::toT(key)).run();
} else {
dwt::MessageBox(mainWindow).show(
T_("A MAGNET link was given to DC++, but it didn't contain a valid file hash for use on the Direct Connect network. No action will be taken."),
T_("MAGNET Link detected"), dwt::MessageBox::BOX_OK, dwt::MessageBox::BOX_ICONEXCLAMATION);
}
+ return true;
}
+
+ return false;
}
namespace {
=== modified file 'win32/WinUtil.h'
--- win32/WinUtil.h 2012-03-11 16:34:55 +0000
+++ win32/WinUtil.h 2012-03-18 17:52:34 +0000
@@ -293,7 +293,6 @@
static bool getUCParams(dwt::Widget* parent, const UserCommand& cmd, ParamMap& params) noexcept;
static bool parseLink(const tstring& aString);
- static void parseMagnetUri(const tstring& /*aUrl*/, bool aOverride = false);
static void help(dwt::Control* widget);
static void helpId(dwt::Control* widget, unsigned id);