📄 queuemanager.cpp
字号:
}
q->removeSource(aUser, reason);
fire(QueueManagerListener::SOURCES_UPDATED, q);
setDirty();
}
if(!x.empty()) {
DownloadManager::getInstance()->abortDownload(x);
}
}
void QueueManager::removeSources(User::Ptr& aUser, int reason) throw() {
string x;
{
Lock l(cs);
QueueItem* qi = NULL;
while( (qi = userQueue.getNext(aUser, QueueItem::PAUSED)) != NULL) {
if(qi->isSet(QueueItem::FLAG_USER_LIST)) {
remove(qi->getTarget());
} else {
userQueue.remove(qi, aUser);
qi->removeSource(aUser, reason);
fire(QueueManagerListener::SOURCES_UPDATED, qi);
setDirty();
}
}
qi = userQueue.getRunning(aUser);
if(qi != NULL) {
if(qi->isSet(QueueItem::FLAG_USER_LIST)) {
remove(qi->getTarget());
} else {
userQueue.setWaiting(qi);
userQueue.remove(qi, aUser);
x = qi->getTarget();
qi->removeSource(aUser, reason);
fire(QueueManagerListener::SOURCES_UPDATED, qi);
setDirty();
}
}
}
if(!x.empty()) {
DownloadManager::getInstance()->abortDownload(x);
}
}
void QueueManager::setPriority(const string& aTarget, QueueItem::Priority p) throw() {
User::List ul;
{
Lock l(cs);
QueueItem* q = findByTarget(aTarget);
if( (q != NULL) && (q->getPriority() != p) ) {
if( q->getStatus() != QueueItem::STATUS_RUNNING ) {
if(q->getPriority() == QueueItem::PAUSED) {
// Problem, we have to request connections to all these users...
userQueue.getUserList(ul, QueueItem::PAUSED);
}
userQueue.remove(q);
q->setPriority(p);
userQueue.add(q);
} else {
q->setPriority(p);
}
setDirty();
fire(QueueManagerListener::STATUS_UPDATED, q);
}
}
for(User::Iter i = ul.begin(); i != ul.end(); ++i) {
ConnectionManager::getInstance()->getDownloadConnection(*i);
}
}
QueueItem* QueueManager::findByTarget(const string& aTarget) {
// The hash is (hopefully...) case-insensitive...
QueueItem::StringIter i = queue.find(aTarget);
return (i == queue.end()) ? NULL : i->second;
}
void QueueManager::saveQueue() throw() {
if(!dirty)
return;
Lock l(cs);
try {
#define STRINGLEN(n) n, sizeof(n)-1
#define CHECKESCAPE(n) SimpleXML::needsEscape(n, true) ? SimpleXML::escape(n, true) : n
BufferedFile f(getQueueFile() + ".tmp", File::WRITE, File::CREATE | File::TRUNCATE);
f.write(STRINGLEN("<?xml version=\"1.0\" encoding=\"windows-1252\"?>\r\n"));
f.write(STRINGLEN("<Downloads>\r\n"));
for(QueueItem::StringIter i = queue.begin(); i != queue.end(); ++i) {
const QueueItem::Ptr& d = i->second;
if(!d->isSet(QueueItem::FLAG_USER_LIST)) {
f.write(STRINGLEN("\t<Download Target=\""));
f.write(CHECKESCAPE(d->getTarget()));
f.write(STRINGLEN("\" Resume=\""));
f.write(Util::toString(d->isSet(QueueItem::FLAG_RESUME)));
f.write(STRINGLEN("\" Size=\""));
f.write(Util::toString(d->getSize()));
f.write(STRINGLEN("\" Priority=\""));
f.write(Util::toString((int)d->getPriority()));
f.write(STRINGLEN("\" TempTarget=\""));
f.write(CHECKESCAPE(d->getTempTarget()));
f.write(STRINGLEN("\">\r\n"));
for(QueueItem::Source::List::const_iterator j = d->sources.begin(); j != d->sources.end(); ++j) {
QueueItem::Source* s = *j;
f.write(STRINGLEN("\t\t<Source Nick=\""));
f.write(CHECKESCAPE(s->getUser()->getNick()));
f.write(STRINGLEN("\" Path=\""));
f.write(CHECKESCAPE(s->getPath()));
f.write(STRINGLEN("\"/>\r\n"));
}
f.write(STRINGLEN("\t</Download>\r\n"));
}
}
for(DirectoryItem::DirectoryIter j = directories.begin(); j != directories.end(); ++j) {
DirectoryItem::Ptr d = j->second;
f.write(STRINGLEN("\t<Directory Target=\""));
f.write(CHECKESCAPE(d->getTarget()));
f.write(STRINGLEN("\" Nick=\""));
f.write(CHECKESCAPE(d->getUser()->getNick()));
f.write(STRINGLEN("\" Priority=\""));
f.write(Util::toString((int)d->getPriority()));
f.write(STRINGLEN("\" Source=\""));
f.write(CHECKESCAPE(d->getName()));
f.write(STRINGLEN("\"/>\r\n"));
}
f.write("</Downloads>\r\n");
f.close();
File::deleteFile(getQueueFile());
File::renameFile(getQueueFile() + ".tmp", getQueueFile());
dirty = false;
lastSave = GET_TICK();
} catch(const FileException&) {
// ...
}
}
void QueueManager::loadQueue() throw() {
try {
SimpleXML xml(5);
xml.fromXML(File(getQueueFile(), File::READ, File::OPEN).read());
load(&xml);
} catch(const Exception&) {
// ...
}
}
void QueueManager::load(SimpleXML* aXml) {
Lock l(cs);
aXml->resetCurrentChild();
if(aXml->findChild("Downloads")) {
const string sDownload = "Download";
const string sTempTarget = "TempTarget";
const string sTarget = "Target";
const string sResume = "Resume";
const string sSize = "Size";
const string sPriority = "Priority";
const string sSource = "Source";
const string sNick = "Nick";
const string sPath = "Path";
const string sDirectory = "Directory";
aXml->stepIn();
while(aXml->findChild(sDownload)) {
const string& tempTarget = aXml->getChildAttrib(sTempTarget);
const string& target = aXml->getChildAttrib(sTarget);
bool resume = aXml->getBoolChildAttrib(sResume);
int64_t size = aXml->getLongLongChildAttrib(sSize);
QueueItem::Priority p = (QueueItem::Priority)aXml->getIntChildAttrib(sPriority);
aXml->stepIn();
if(aXml->findChild(sSource)) {
do {
const string& nick = aXml->getChildAttrib(sNick);
const string& path = aXml->getChildAttrib(sPath);
try {
add(path, size, ClientManager::getInstance()->getUser(nick), target, resume, p, tempTarget);
} catch(const Exception&) {
// ...
}
} while(aXml->findChild(sSource));
} else {
// Sourceless file!
Lock l(cs);
bool newItem = false;
if(target.find('\\') == string::npos)
continue;
QueueItem* qi = getQueueItem(target, size, resume, newItem);
if(newItem) {
qi->setPriority(p);
qi->setTempTarget(tempTarget);
if(lastInsert == queue.end()) {
lastInsert = queue.insert(make_pair(qi->getTarget(), qi)).first;
} else {
lastInsert = queue.insert(lastInsert, make_pair(qi->getTarget(), qi));
}
fire(QueueManagerListener::ADDED, qi);
}
}
aXml->stepOut();
}
aXml->resetCurrentChild();
while(aXml->findChild(sDirectory)) {
const string& name = aXml->getChildAttrib(sSource);
const string& target = aXml->getChildAttrib(sTarget);
const string& nick = aXml->getChildAttrib(sNick);
QueueItem::Priority p = (QueueItem::Priority)aXml->getIntChildAttrib(sPriority);
addDirectory(name, ClientManager::getInstance()->getUser(nick), target, p);
}
aXml->stepOut();
}
// We don't need to save the queue when we've just loaded it...
dirty = false;
}
void QueueManager::importNMQueue(const string& aFile) throw(FileException) {
File f(aFile, File::READ, File::OPEN);
u_int32_t size = (u_int32_t)f.getSize();
string tmp;
if(size > 16) {
AutoArray<u_int8_t> buf(size);
f.read(buf, size);
try {
CryptoManager::getInstance()->decodeHuffman(buf, tmp);
} catch(const CryptoException&) {
return;
}
} else {
tmp = Util::emptyString;
}
StringTokenizer line(tmp);
StringList& tokens = line.getTokens();
for(StringIter i = tokens.begin(); i != tokens.end(); i++) {
const string& tok = *i;
string::size_type k = tok.find('|');
if( (k == string::npos) || ((k+1) >= tok.size()) )
continue;
string tmp = tok.substr(k+1);
if( (tmp == "Active") || (tmp == "Paused") ) {
continue; // ignore first line
}
StringTokenizer t(tok, '\t');
StringList& records = t.getTokens();
if(records.size() < 5)
continue;
StringIter j = records.begin();
++j; // filename
const string& size = *(++j);
const string& target = *(++j);
const string& file = *(++j);
const string& nick = *(++j);
try {
add(file, size, ClientManager::getInstance()->getUser(nick), target);
} catch(const Exception&) {
// ...
}
}
}
// SearchManagerListener
void QueueManager::onAction(SearchManagerListener::Types type, SearchResult* sr) throw() {
if(type == SearchManagerListener::SEARCH_RESULT && BOOLSETTING(AUTO_SEARCH)) {
StringList l = getTargetsBySize(sr->getSize(), Util::getExtension(sr->getFile()));
StringTokenizer t(SearchManager::clean(sr->getFileName()), ' ');
StringList& tok = t.getTokens();
for(StringIter i = l.begin(); i != l.end(); ++i) {
bool found = true;
for(StringIter j = tok.begin(); j != tok.end(); ++j) {
if(Util::findSubString(*i, *j) == string::npos) {
found = false;
break;
}
}
if(found) {
// Wow! found a new source that seems to match...add it...
dcdebug("QueueManager::onAction New source %s for target %s found\n", sr->getUser()->getNick().c_str(), i->c_str());
try {
add(sr->getFile(), sr->getSize(), sr->getUser(), *i, true,
QueueItem::DEFAULT, Util::emptyString, false);
} catch(const Exception&) {
// ...
}
}
}
}
}
// ClientManagerListener
void QueueManager::onAction(ClientManagerListener::Types type, const User::Ptr& aUser) throw() {
bool hasDown = false;
switch(type) {
case ClientManagerListener::USER_UPDATED:
{
Lock l(cs);
for(int i = 0; i < QueueItem::LAST; ++i) {
QueueItem::UserListIter j = userQueue.getList(i).find(aUser);
if(j != userQueue.getList(i).end()) {
for(QueueItem::Iter m = j->second.begin(); m != j->second.end(); ++m)
fire(QueueManagerListener::SOURCES_UPDATED, *m);
if(i != QueueItem::PAUSED)
hasDown = true;
}
}
}
break;
}
if(aUser->isOnline() && hasDown)
ConnectionManager::getInstance()->getDownloadConnection(aUser);
}
void QueueManager::onAction(TimerManagerListener::Types type, u_int32_t aTick) throw() {
switch(type) {
case TimerManagerListener::MINUTE:
onTimerMinute(aTick); break;
case TimerManagerListener::SECOND:
if(dirty && ((lastSave + 10000) < aTick)) {
saveQueue();
}
break;
}
}
/**
* @file
* $Id: QueueManager.cpp,v 1.42 2003/06/20 10:49:27 arnetheduck Exp $
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -