------------------------------------------------------------ revno: 3256 committer: poy <p...@123gen.com> branch nick: trunk timestamp: Fri 2013-04-12 23:10:13 +0200 message: Display HTTP downloads in the transfer list modified: changelog.txt dcpp/CID.h dcpp/ClientManager.cpp dcpp/DirectoryListing.cpp dcpp/FavoriteManager.cpp dcpp/HashValue.h dcpp/HttpManager.cpp dcpp/HttpManager.h dcpp/SettingsManager.cpp win32/MainWindow.cpp win32/TransferView.cpp win32/TransferView.h win32/UserInfoBase.cpp win32/WinUtil.cpp
-- 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 'changelog.txt' --- changelog.txt 2013-04-09 17:20:25 +0000 +++ changelog.txt 2013-04-12 21:10:13 +0000 @@ -4,6 +4,7 @@ * [L#249622] Add user commands to transfer menus * Add a tab menu command to disconnect a hub (poy) * Validate input before trying a TTH search (emtee) +* Display HTTP downloads in the transfer list (poy) -- 0.811 2013-03-04 -- * Fix status bar parts when the window is too small (poy) === modified file 'dcpp/CID.h' --- dcpp/CID.h 2013-01-18 21:28:38 +0000 +++ dcpp/CID.h 2013-04-12 21:10:13 +0000 @@ -50,7 +50,7 @@ } const uint8_t* data() const { return cid; } - bool isZero() const { return find_if(cid, cid+SIZE, [](uint8_t c) { return c != 0; }) == (cid+SIZE); } + explicit operator bool() const { return find_if(cid, cid + SIZE, [](uint8_t c) { return c != 0; }) != cid + SIZE; } static CID generate(); === modified file 'dcpp/ClientManager.cpp' --- dcpp/ClientManager.cpp 2013-02-12 19:16:15 +0000 +++ dcpp/ClientManager.cpp 2013-04-12 21:10:13 +0000 @@ -566,7 +566,7 @@ } const CID& ClientManager::getMyPID() { - if(pid.isZero()) + if(!pid) pid = CID(SETTING(PRIVATE_ID)); return pid; } === modified file 'dcpp/DirectoryListing.cpp' --- dcpp/DirectoryListing.cpp 2013-01-18 21:28:38 +0000 +++ dcpp/DirectoryListing.cpp 2013-04-12 21:10:13 +0000 @@ -70,7 +70,7 @@ return UserPtr(); CID cid(name.substr(i + 1)); - if(cid.isZero()) + if(!cid) return UserPtr(); return ClientManager::getInstance()->getUser(cid); === modified file 'dcpp/FavoriteManager.cpp' --- dcpp/FavoriteManager.cpp 2013-04-12 18:24:09 +0000 +++ dcpp/FavoriteManager.cpp 2013-04-12 21:10:13 +0000 @@ -713,6 +713,7 @@ Lock l(cs); publicListMatrix[publicListServer].clear(); } + fire(FavoriteManagerListener::DownloadStarting(), publicListServer); c = HttpManager::getInstance()->download(publicListServer); running = true; } === modified file 'dcpp/HashValue.h' --- dcpp/HashValue.h 2013-01-18 21:28:38 +0000 +++ dcpp/HashValue.h 2013-04-12 21:10:13 +0000 @@ -19,6 +19,8 @@ #ifndef DCPLUSPLUS_DCPP_HASH_VALUE_H #define DCPLUSPLUS_DCPP_HASH_VALUE_H +#include <algorithm> + #include "FastAlloc.h" #include "Encoder.h" @@ -29,7 +31,7 @@ static const size_t BITS = Hasher::BITS; static const size_t BYTES = Hasher::BYTES; - HashValue() { } + HashValue() { memset(data, 0, BYTES); } explicit HashValue(const uint8_t* aData) { memcpy(data, aData, BYTES); } explicit HashValue(const std::string& base32) { Encoder::fromBase32(base32.c_str(), data, BYTES); } @@ -40,6 +42,8 @@ std::string toBase32() const { return Encoder::toBase32(data, BYTES); } std::string& toBase32(std::string& tmp) const { return Encoder::toBase32(data, BYTES, tmp); } + explicit operator bool() const { return find_if(data, data + BYTES, [](uint8_t c) { return c != 0; }) != data + BYTES; } + uint8_t data[BYTES]; }; === modified file 'dcpp/HttpManager.cpp' --- dcpp/HttpManager.cpp 2013-04-12 18:35:46 +0000 +++ dcpp/HttpManager.cpp 2013-04-12 21:10:13 +0000 @@ -19,6 +19,7 @@ #include "stdinc.h" #include "HttpManager.h" +#include "format.h" #include "HttpConnection.h" namespace dcpp { @@ -43,6 +44,27 @@ return conn; } +void HttpManager::disconnect(const string& url) { + HttpConnection* c = nullptr; + + { + Lock l(cs); + conns.erase(std::remove_if(conns.begin(), conns.end(), [&](const Conn& conn) -> bool { + if(conn.c->getUrl() == url) { + c = conn.c; + return true; + } + return false; + }), conns.end()); + } + + if(c) { + fire(HttpManagerListener::Failed(), c, _("Disconnected")); + fire(HttpManagerListener::Removed(), c); + delete c; + } +} + void HttpManager::shutdown() { Lock l(cs); for(auto& conn: conns) { delete conn.c; } @@ -86,6 +108,7 @@ buf.append(reinterpret_cast<const char*>(data), len); } fire(HttpManagerListener::Updated(), c); + printf("size: %d\n", c->getSize()); } void HttpManager::on(HttpConnectionListener::Failed, HttpConnection* c, const string& str) noexcept { @@ -122,14 +145,16 @@ void HttpManager::on(TimerManagerListener::Minute, uint64_t tick) noexcept { vector<HttpConnection*> removed; - Lock l(cs); - conns.erase(std::remove_if(conns.begin(), conns.end(), [tick, &removed](const Conn& conn) -> bool { - if(conn.remove && tick > conn.remove) { - removed.push_back(conn.c); - return true; - } - return false; - }), conns.end()); + { + Lock l(cs); + conns.erase(std::remove_if(conns.begin(), conns.end(), [tick, &removed](const Conn& conn) -> bool { + if(conn.remove && tick > conn.remove) { + removed.push_back(conn.c); + return true; + } + return false; + }), conns.end()); + } for(auto c: removed) { fire(HttpManagerListener::Removed(), c); === modified file 'dcpp/HttpManager.h' --- dcpp/HttpManager.h 2013-04-12 18:35:46 +0000 +++ dcpp/HttpManager.h 2013-04-12 21:10:13 +0000 @@ -44,6 +44,8 @@ HttpConnection* download(string url); HttpConnection* download(string url, const StringMap& postData); + void disconnect(const string& url); + void shutdown(); private: === modified file 'dcpp/SettingsManager.cpp' --- dcpp/SettingsManager.cpp 2013-03-22 15:34:41 +0000 +++ dcpp/SettingsManager.cpp 2013-04-12 21:10:13 +0000 @@ -446,7 +446,7 @@ xml.stepOut(); } - if(SETTING(PRIVATE_ID).length() != 39 || CID(SETTING(PRIVATE_ID)).isZero()) { + if(SETTING(PRIVATE_ID).length() != 39 || !CID(SETTING(PRIVATE_ID))) { set(PRIVATE_ID, CID::generate().toBase32()); } @@ -537,7 +537,7 @@ xml.stepOut(); } catch(const Exception&) { - if(CID(SETTING(PRIVATE_ID)).isZero()) + if(!CID(SETTING(PRIVATE_ID))) set(PRIVATE_ID, CID::generate().toBase32()); } } === modified file 'win32/MainWindow.cpp' --- win32/MainWindow.cpp 2013-04-12 18:24:09 +0000 +++ win32/MainWindow.cpp 2013-04-12 21:10:13 +0000 @@ -159,7 +159,7 @@ layout(); - for(auto conn: conns) { conn = nullptr; } + for(auto& conn: conns) { conn = nullptr; } HttpManager::getInstance()->addListener(this); LogManager::getInstance()->addListener(this); === modified file 'win32/TransferView.cpp' --- win32/TransferView.cpp 2013-04-09 16:00:38 +0000 +++ win32/TransferView.cpp 2013-04-12 21:10:13 +0000 @@ -24,6 +24,8 @@ #include <dcpp/Download.h> #include <dcpp/DownloadManager.h> #include <dcpp/GeoManager.h> +#include <dcpp/HttpConnection.h> +#include <dcpp/HttpManager.h> #include <dcpp/QueueManager.h> #include <dcpp/SettingsManager.h> #include <dcpp/Upload.h> @@ -93,6 +95,7 @@ DownloadManager::getInstance()->addListener(this); UploadManager::getInstance()->addListener(this); QueueManager::getInstance()->addListener(this); + HttpManager::getInstance()->addListener(this); } TransferView::~TransferView() { @@ -103,6 +106,7 @@ ConnectionManager::getInstance()->removeListener(this); DownloadManager::getInstance()->removeListener(this); UploadManager::getInstance()->removeListener(this); + HttpManager::getInstance()->removeListener(this); } TransferView::ItemInfo::ItemInfo() : @@ -130,7 +134,7 @@ auto ca = dynamic_cast<const ConnectionInfo*>(a), cb = dynamic_cast<const ConnectionInfo*>(b); if(ca && cb && ca->status != cb->status) { // sort running conns first. - return ca->status == ConnectionInfo::STATUS_RUNNING ? -1 : 1; + return ca->status == STATUS_RUNNING ? -1 : 1; } switch(col) { @@ -303,7 +307,7 @@ timeleft += conn.timeleft; transferred += conn.transferred; } - if(conn.status == ConnectionInfo::STATUS_RUNNING) { + if(conn.status == STATUS_RUNNING) { ++running; speed += conn.speed; } @@ -386,6 +390,48 @@ } } +TransferView::HttpInfo::HttpInfo(const string& url) : + TransferInfo(TTHValue(), true, url, Util::emptyString), + status(STATUS_WAITING) +{ + columns[COLUMN_PATH] = Text::toT(url); + auto slash = columns[COLUMN_PATH].rfind('/'); + columns[COLUMN_FILE] = slash != tstring::npos ? columns[COLUMN_PATH].substr(slash + 1) : columns[COLUMN_PATH]; + + columns[COLUMN_STATUS] = T_("Downloading"); +} + +void TransferView::HttpInfo::update(const UpdateInfo& ui) { + if(ui.updateMask & UpdateInfo::MASK_STATUS) { + status = ui.status; + } + + if(ui.updateMask & UpdateInfo::MASK_STATUS_STRING) { + columns[COLUMN_STATUS] = ui.statusString; + } + + if(ui.updateMask & UpdateInfo::MASK_TRANSFERRED) { + transferred = ui.transferred; + size = ui.size; + + if(transferred > 0) { + columns[COLUMN_TRANSFERRED] = str(TF_("%1%") % Text::toT(Util::formatBytes(transferred))); + } else { + columns[COLUMN_TRANSFERRED].clear(); + } + + if(size > 0) { + columns[COLUMN_SIZE] = Text::toT(Util::formatBytes(size)); + } else { + columns[COLUMN_SIZE].clear(); + } + } +} + +void TransferView::HttpInfo::disconnect() { + HttpManager::getInstance()->disconnect(path); +} + void TransferView::handleDestroy() { SettingsManager::getInstance()->set(SettingsManager::TRANSFERS_ORDER, WinUtil::toString(transfers->getColumnOrder())); SettingsManager::getInstance()->set(SettingsManager::TRANSFERS_WIDTHS, WinUtil::toString(transfers->getColumnWidths())); @@ -424,7 +470,7 @@ set<TransferInfo*> files; for(auto i: sel) { auto& transfer = transfers->getData(i)->transfer(); - if(!transfer.getText(COLUMN_FILE).empty()) { + if(!dynamic_cast<HttpInfo*>(&transfer) && !transfer.getText(COLUMN_FILE).empty()) { files.insert(&transfer); } } @@ -782,6 +828,47 @@ transferItems.remove(transfer); } +void TransferView::addHttpConn(const UpdateInfo& ui) { + auto item = findHttpItem(ui.path); + if(item) { + removeHttpItem(*item); + } + + httpItems.emplace_back(ui.path); + item = &httpItems.back(); + item->update(ui); + + transfers->insert(item); +} + +void TransferView::updateHttpConn(const UpdateInfo& ui) { + auto item = findHttpItem(ui.path); + if(item) { + item->update(ui); + } +} + +void TransferView::removeHttpConn(const UpdateInfo& ui) { + auto item = findHttpItem(ui.path); + if(item) { + removeHttpItem(*item); + } +} + +TransferView::HttpInfo* TransferView::findHttpItem(const string& url) { + for(auto& item: httpItems) { + if(item.path == url) { + return &item; + } + } + return nullptr; +} + +void TransferView::removeHttpItem(HttpInfo& item) { + transfers->erase(&item); + httpItems.remove(item); +} + TransferView::UserInfoList TransferView::selectedUsersImpl() const { // AspectUserInfo::usersFromTable won't do because not every item represents a user. UserInfoList users; @@ -814,7 +901,7 @@ void TransferView::on(ConnectionManagerListener::Added, ConnectionQueueItem* aCqi) noexcept { auto ui = new UpdateInfo(aCqi->getUser(), aCqi->getDownload()); - ui->setStatus(ConnectionInfo::STATUS_WAITING); + ui->setStatus(STATUS_WAITING); ui->setStatusString(T_("Connecting")); addedConn(ui); @@ -938,23 +1025,60 @@ onFailed(d, aReason); } +void TransferView::on(HttpManagerListener::Added, HttpConnection* c) noexcept { + auto ui = makeHttpUI(c); + ui->setStatus(STATUS_RUNNING); + ui->setTransferred(c->getDone(), c->getDone(), c->getSize()); + + addedConn(ui); +} + +void TransferView::on(HttpManagerListener::Updated, HttpConnection* c) noexcept { + auto ui = makeHttpUI(c); + ui->setTransferred(c->getDone(), c->getDone(), c->getSize()); + + updatedConn(ui); +} + +void TransferView::on(HttpManagerListener::Failed, HttpConnection* c, const string& str) noexcept { + auto ui = makeHttpUI(c); + ui->setStatus(STATUS_WAITING); + ui->setStatusString(Text::toT(str)); + ui->setTransferred(c->getDone(), c->getDone(), c->getSize()); + + updatedConn(ui); +} + +void TransferView::on(HttpManagerListener::Complete, HttpConnection* c, const string&) noexcept { + auto ui = makeHttpUI(c); + ui->setStatus(STATUS_WAITING); + ui->setStatusString(T_("Idle")); + ui->setTransferred(c->getDone(), c->getDone(), c->getSize()); + + updatedConn(ui); +} + +void TransferView::on(HttpManagerListener::Removed, HttpConnection* c) noexcept { + removedConn(makeHttpUI(c)); +} + void TransferView::addedConn(UpdateInfo* ui) { callAsync([this, ui] { - tasks.emplace_back([=](const UpdateInfo& ui) { addConn(ui); }, unique_ptr<UpdateInfo>(ui)); + tasks.emplace_back([=](const UpdateInfo& ui) { ui.isHttp() ? addHttpConn(ui) : addConn(ui); }, unique_ptr<UpdateInfo>(ui)); updateList = true; }); } void TransferView::updatedConn(UpdateInfo* ui) { callAsync([this, ui] { - tasks.emplace_back([=](const UpdateInfo& ui) { updateConn(ui); }, unique_ptr<UpdateInfo>(ui)); + tasks.emplace_back([=](const UpdateInfo& ui) { ui.isHttp() ? updateHttpConn(ui) : updateConn(ui); }, unique_ptr<UpdateInfo>(ui)); updateList = true; }); } void TransferView::removedConn(UpdateInfo* ui) { callAsync([this, ui] { - tasks.emplace_back([=](const UpdateInfo& ui) { removeConn(ui); }, unique_ptr<UpdateInfo>(ui)); + tasks.emplace_back([=](const UpdateInfo& ui) { ui.isHttp() ? removeHttpConn(ui) : removeConn(ui); }, unique_ptr<UpdateInfo>(ui)); updateList = true; }); } @@ -962,7 +1086,7 @@ void TransferView::starting(UpdateInfo* ui, Transfer* t) { ui->setTTH(t->getTTH()); ui->setFile(t->getPath()); - ui->setStatus(ConnectionInfo::STATUS_RUNNING); + ui->setStatus(STATUS_RUNNING); ui->setTransferred(t->getPos(), t->getActual(), t->getSize()); const UserConnection& uc = t->getUserConnection(); ui->setCipher(Text::toT(uc.getCipherName())); @@ -980,7 +1104,7 @@ void TransferView::onTransferComplete(Transfer* t, bool download) { auto ui = new UpdateInfo(t->getHintedUser(), download); ui->setFile(t->getPath()); - ui->setStatus(ConnectionInfo::STATUS_WAITING); + ui->setStatus(STATUS_WAITING); ui->setStatusString(T_("Idle")); ui->setTransferred(t->getPos(), t->getActual(), t->getSize()); @@ -990,8 +1114,15 @@ void TransferView::onFailed(Download* d, const string& aReason) { auto ui = new UpdateInfo(d->getHintedUser(), true, true); ui->setFile(d->getPath()); - ui->setStatus(ConnectionInfo::STATUS_WAITING); + ui->setStatus(STATUS_WAITING); ui->setStatusString(Text::toT(aReason)); updatedConn(ui); } + +TransferView::UpdateInfo* TransferView::makeHttpUI(HttpConnection* c) { + auto ui = new UpdateInfo(true); + ui->setHttp(); + ui->setFile(c->getUrl()); + return ui; +} === modified file 'win32/TransferView.h' --- win32/TransferView.h 2013-03-31 17:09:29 +0000 +++ win32/TransferView.h 2013-04-12 21:10:13 +0000 @@ -26,6 +26,7 @@ #include <dcpp/UploadManagerListener.h> #include <dcpp/ConnectionManagerListener.h> #include <dcpp/QueueManagerListener.h> +#include <dcpp/HttpManagerListener.h> #include <dcpp/forward.h> #include <dcpp/MerkleTree.h> #include <dcpp/Util.h> @@ -45,6 +46,7 @@ private UploadManagerListener, private ConnectionManagerListener, private QueueManagerListener, + private HttpManagerListener, public AspectUserInfo<TransferView>, public AspectUserCommand<TransferView> { @@ -75,6 +77,11 @@ COLUMN_LAST }; + enum Status { + STATUS_RUNNING, ///< Transferring + STATUS_WAITING ///< Idle + }; + struct TransferInfo; struct UpdateInfo; @@ -103,11 +110,6 @@ }; struct ConnectionInfo : public ItemInfo, public UserInfoBase { - enum Status { - STATUS_RUNNING, ///< Transfering - STATUS_WAITING ///< Idle - }; - ConnectionInfo(const HintedUser& u, TransferInfo& parent); bool operator==(const ConnectionInfo& other) const; @@ -120,8 +122,8 @@ double barPos() const; - void force(); - void disconnect(); + virtual void force(); + virtual void disconnect(); bool transferFailed; Status status; @@ -142,8 +144,8 @@ double barPos() const; - void force(); - void disconnect(); + virtual void force(); + virtual void disconnect(); TTHValue tth; bool download; @@ -153,6 +155,16 @@ list<ConnectionInfo> conns; }; + struct HttpInfo : public TransferInfo { + HttpInfo(const string& url); + + void update(const UpdateInfo& ui); + + virtual void disconnect(); + + Status status; + }; + struct UpdateInfo { enum { MASK_STATUS = 1 << 0, @@ -162,11 +174,13 @@ MASK_CIPHER = 1 << 4, MASK_IP = 1 << 5, MASK_COUNTRY = 1 << 6, - MASK_PATH = 1 << 7 + MASK_PATH = 1 << 7, + MASK_HTTP = 1 << 8 }; UpdateInfo(const HintedUser& user, bool download, bool transferFailed = false) : updateMask(0), user(user), download(download), transferFailed(transferFailed) { } + UpdateInfo(bool download) : download(download), transferFailed(false) { } uint32_t updateMask; @@ -182,8 +196,8 @@ string tempPath; void setTempPath(const string& path) { tempPath = path; } - void setStatus(ConnectionInfo::Status aStatus) { status = aStatus; updateMask |= MASK_STATUS; } - ConnectionInfo::Status status; + void setStatus(Status aStatus) { status = aStatus; updateMask |= MASK_STATUS; } + Status status; void setTransferred(int64_t aTransferred, int64_t aActual, int64_t aSize) { transferred = aTransferred; actual = aActual; size = aSize; updateMask |= MASK_TRANSFERRED; } @@ -201,6 +215,9 @@ tstring ip; void setCountry(const tstring& aCountry) { country = aCountry; updateMask |= MASK_COUNTRY; } tstring country; + + void setHttp() { updateMask |= MASK_HTTP; } + bool isHttp() const { return (updateMask & MASK_HTTP) == MASK_HTTP; } }; typedef TypedTable<ItemInfo, false, dwt::TableTree> WidgetTransfers; @@ -209,6 +226,7 @@ list<TransferInfo> transferItems; /* the LPARAM data of table entries are direct pointers to objects stored by this container, hence the std::list. */ + list<HttpInfo> httpItems; TabViewPtr mdi; @@ -242,6 +260,13 @@ void removeConn(ConnectionInfo& conn); void removeTransfer(TransferInfo& transfer); + void addHttpConn(const UpdateInfo& ui); + void updateHttpConn(const UpdateInfo& ui); + void removeHttpConn(const UpdateInfo& ui); + + HttpInfo* findHttpItem(const string& url); + void removeHttpItem(HttpInfo& item); + // AspectUserInfo UserInfoList selectedUsersImpl() const; @@ -264,6 +289,12 @@ virtual void on(QueueManagerListener::CRCFailed, Download* d, const string& aReason) noexcept; + virtual void on(HttpManagerListener::Added, HttpConnection*) noexcept; + virtual void on(HttpManagerListener::Updated, HttpConnection*) noexcept; + virtual void on(HttpManagerListener::Failed, HttpConnection*, const string&) noexcept; + virtual void on(HttpManagerListener::Complete, HttpConnection*, const string&) noexcept; + virtual void on(HttpManagerListener::Removed, HttpConnection*) noexcept; + void addedConn(UpdateInfo* ui); void updatedConn(UpdateInfo* ui); void removedConn(UpdateInfo* ui); @@ -272,6 +303,7 @@ void onTransferTick(Transfer* t, bool download); void onTransferComplete(Transfer* t, bool download); void onFailed(Download* aDownload, const string& aReason); + UpdateInfo* makeHttpUI(HttpConnection* c); }; #endif // !defined(TRANSFER_VIEW_H) === modified file 'win32/UserInfoBase.cpp' --- win32/UserInfoBase.cpp 2013-03-03 20:15:35 +0000 +++ win32/UserInfoBase.cpp 2013-04-12 21:10:13 +0000 @@ -48,7 +48,7 @@ } } void UserInfoBase::browseList() { - if(user.user->getCID().isZero()) + if(!user.user->getCID()) return; try { QueueManager::getInstance()->addList(user, QueueItem::FLAG_CLIENT_VIEW | QueueItem::FLAG_PARTIAL_LIST); === modified file 'win32/WinUtil.cpp' --- win32/WinUtil.cpp 2013-03-22 16:30:58 +0000 +++ win32/WinUtil.cpp 2013-04-12 21:10:13 +0000 @@ -764,6 +764,7 @@ } void WinUtil::addHashItems(Menu* menu, const TTHValue& tth, const tstring& filename, int64_t size) { + if(!tth) { return; } menu->appendItem(T_("Search for alternates"), [=] { searchHash(tth); }, menuIcon(IDI_SEARCH)); menu->appendItem(T_("Lookup TTH at Bitzi.com"), [=] { bitziLink(tth); }); menu->appendItem(T_("Copy magnet link to clipboard"), [=] { copyMagnet(tth, filename, size); }, menuIcon(IDI_MAGNET));
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp