📄 downloader.cpp
字号:
/* * nzb * * Copyright (C) 2004-2006 Mattias Nordstrom <matta at ftlight net> * * 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 * * * Authors: * Mattias Nordstrom <matta at ftlight net> * * $Id: downloader.cpp,v 1.7 2006/05/14 10:37:53 mnordstr Exp $ * This file provides the NNTP downloader. */#include "downloader.h"#include "mainwindow.h"Downloader::Downloader(NzbList *nzblist, int thread_id, QMutex *file_lock, QTableWidget *l, QObject *parent){ this->nzblist = nzblist; this->parent = parent; this->thread_id = thread_id; this->file_lock = file_lock; this->l = l; this->use_ssl = false; connect(this, SIGNAL(downloadEvent(QString, int, int)), parent, SLOT(downloadEvent(QString, int, int)));}void Downloader::run(){ qDebug("Downloader running."); QTimer::singleShot(0, this, SLOT(init())); this->exec(); qDebug("Downloader done.");}void Downloader::init(){ file = 0, seg = 0; downloading = false; connect(this, SIGNAL(processNext()), this, SLOT(processFiles())); use_ssl = ((MainWindow*)parent)->getConfig()->value("server/ssl").toBool(); emit downloadEvent("Connecting", thread_id); ((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_creating.png")); usenet = new QTcpSocket(); connect(usenet, SIGNAL(connected()), this, SLOT(gotConnected())); if (use_ssl) { connect(&ssl, SIGNAL(readyRead()), this, SLOT(gotData())); connect(usenet, SIGNAL(readyRead()), this, SLOT(ssl_readyRead())); connect(&ssl, SIGNAL(outgoingSSLDataReady()), this, SLOT(ssl_outgoingReady())); } else { connect(usenet, SIGNAL(readyRead()), this, SLOT(gotData())); } initialize(((MainWindow*)parent)->getConfig()->value("server/host").toString(), ((MainWindow*)parent)->getConfig()->value("server/port").toInt()); last_time = QTime::currentTime(); last_bytes = 0; total_bytes = 0; QTimer *speedTimer = new QTimer(this); connect(speedTimer, SIGNAL(timeout()), this, SLOT(speedMonitor())); speedTimer->start(5000);}void Downloader::processFiles(){ if (downloading) return; if (getNext()) { downloading = true; emit downloadEvent("Downloading ["+QString::number(file+1)+": "+QString::number(seg+1)+"/"+QString::number(nzblist->getFile(file)->getSegments()->size())+"] "+nzblist->getFile(file)->getSegment(seg)->getMsgid(), thread_id); getArticle(nzblist->getFile(file)->getSegment(seg)->getMsgid()); }}bool Downloader::getNext(){ file_lock->lock(); for (;;) { if (nzblist->getFile(file)->getSegment(seg)->getStatus() == NZB_NONE && l->item(file, 0)->checkState() == Qt::Checked) { nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADING); file_lock->unlock(); return true; } if (nzblist->getFile(file)->getSegment(seg)->getStatus() == NZB_NONE && l->item(file, 0)->checkState() == Qt::Unchecked) { nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DL_SKIPPED); file_lock->unlock(); emit downloadEvent("", file, 2); emit processNext(); return false; } if (nzblist->getFile(file)->getSegments()->size() == seg+1) { if (nzblist->getList()->size() == file+1) { file_lock->unlock(); emit downloadEvent("Disconnecting", thread_id); terminate(); emit downloadEvent("Disconnected", thread_id); return false; } file = file + 1; seg = 0; } else { seg = seg + 1; } } return false;}void Downloader::stop(){ emit downloadEvent("Disconnecting", thread_id); terminate(); emit downloadEvent("Disconnected", thread_id); dldata.clear(); delete usenet; this->exit();}void Downloader::initialize(QString host, int port){ usenet->connectToHost(host, port);}void Downloader::gotConnected(){ if (use_ssl) { if (!ssl.begin()) { ((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_no.png")); usenet->close(); emit downloadEvent("SSL connection failed", thread_id); dldata.clear(); } else { ((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/encrypted.png")); } } else { ((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_established.png")); }}void Downloader::terminate(){ if (use_ssl) { ssl.send(((QString)("QUIT\r\n")).toAscii()); usenet->close(); } else { usenet->write(((QString)("QUIT\r\n")).toAscii()); usenet->close(); } ((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_no.png"));}void Downloader::getArticle(QString msgid){ if (use_ssl) { ssl.send(("ARTICLE "+msgid+"\r\n").toAscii()); } else { usenet->write(("ARTICLE "+msgid+"\r\n").toAscii()); usenet->flush(); } dldata.clear();}void Downloader::ssl_readyRead(){ /*QByteArray buf; int size = usenet->bytesAvailable(); buf.resize(size); usenet->readBlock(buf.data(), size);*/ ssl.putIncomingSSLData(usenet->readAll());}void Downloader::ssl_outgoingReady(){ usenet->write(ssl.getOutgoingSSLData());}void Downloader::gotData(){ QIODevice *buffer; QBuffer ssl_buf; if (use_ssl) { ssl_buf.open(QBuffer::ReadWrite); ssl_buf.write(ssl.recv()); ssl_buf.seek(0); buffer = &ssl_buf; } else { buffer = usenet; } if (!buffer->bytesAvailable()) { qDebug("gotData() empty."); return; } total_bytes += buffer->bytesAvailable(); QByteArray hdata; int pos; if (dldata.isEmpty()) { hdata = buffer->readLine(); if (hdata.left(3) == "200" || hdata.left(3) == "201") { if (((MainWindow*)parent)->getConfig()->value("server/auth").toBool()) { if (use_ssl) { ssl.send(("AUTHINFO USER "+((MainWindow*)parent)->getConfig()->value("server/username").toString()+"\r\n").toAscii()); } else { buffer->write(("AUTHINFO USER "+((MainWindow*)parent)->getConfig()->value("server/username").toString()+"\r\n").toAscii()); ((QTcpSocket*)buffer)->flush(); } return; } else { emit downloadEvent("Connected", thread_id, 3); emit processNext(); return; } } else if (hdata.left(3) == "381") { if (use_ssl) { ssl.send(("AUTHINFO PASS "+((MainWindow*)parent)->getConfig()->value("server/password").toString()+"\r\n").toAscii()); } else { buffer->write(("AUTHINFO PASS "+((MainWindow*)parent)->getConfig()->value("server/password").toString()+"\r\n").toAscii()); ((QTcpSocket*)buffer)->flush(); } return; } else if (hdata.left(3) == "281") { qDebug("Connected"); emit downloadEvent("Connected", thread_id, 3); emit processNext(); return; } else if (hdata.left(1) == "4" || hdata.left(1) == "5") { emit downloadEvent("NNTP Error: "+hdata, thread_id); qDebug() << "Error: " << hdata; return; } else if (hdata.left(2) == "22") { dldata = hdata; dldata += buffer->readAll(); } else { /*emit downloadEvent("Connect failure", thread_id); qDebug("Connection failed."); nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADED); buffer->close(); qDebug("NNTP Protocol handshake error."); qDebug() << "Data: " << hdata; return;*/ dldata = hdata+buffer->readAll(); } } else { dldata += buffer->readAll(); } if (dldata.right(5) == "\r\n.\r\n") { downloading = false; dldata = dldata.left(dldata.length() - 3); pos = dldata.indexOf("\r\n\r\n", 0); dldata = dldata.mid(pos + 4, dldata.length() - (pos + 4)); if (dldata.left(2) == "..") { dldata.remove(0, 1); } pos = 0; while ((pos = dldata.indexOf("\r\n..", pos+3)) != -1) { dldata.remove(pos + 2, 1); } nzblist->getFile(file)->getSegment(seg)->setData(dldata); nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADED); //dldata.clear(); emit downloadEvent("", file, 2); emit processNext(); }}void Downloader::speedMonitor(){ if (int secs = last_time.secsTo(QTime::currentTime())) { double speed = ((total_bytes - last_bytes) / secs) / 1000; last_time = QTime::currentTime(); last_bytes = total_bytes; emit downloadEvent(QString::number(speed), thread_id, 4); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -