📄 output.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: output.cpp,v 1.12 2005/10/16 12:03:32 mnordstr Exp $ * This file provides the output functions. */#include "output.h"#include "mainwindow.h"Output::Output(NzbList *nzblist, int thread_id, QMutex *file_lock, QObject *parent){ this->nzblist = nzblist; this->parent = parent; this->thread_id = thread_id; this->file_lock = file_lock; connect(this, SIGNAL(outputEvent(QString, int)), parent, SLOT(outputEvent(QString, int)));}void Output::run(){ qDebug("Output running."); file = 0; seg = 0; ms = NULL; streamer = NULL; mp = NULL; player = NULL; fout = NULL; this->exec(); qDebug("Output done.");}void Output::process(){ if (stream && ((MainWindow*)parent)->getConfig()->value("output/stream").toBool() && file == 0 && seg == 0 && streamer == NULL) { streamer = new QTcpServer(); connect(streamer, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::DirectConnection); streamer->listen(QHostAddress::Any, 4321); qDebug("Starting media player"); if (!((MainWindow*)parent)->getConfig()->value("output/mediaplayer").toString().isEmpty()) { player = new DetachedPlayer(((MainWindow*)parent)->getConfig()->value("output/mediaplayer").toString()+" http://127.0.0.1:4321/"); player->start(); qDebug("Media player started"); } else { qDebug("No media player specified, none launched"); } qDebug("Waiting for connection..."); } if (stream && ((MainWindow*)parent)->getConfig()->value("output/stream").toBool() && ms == NULL) { QTimer::singleShot(1000, this, SLOT(process())); return; } if (getNext(&file, &seg)) { if (nzblist->getFile(file)->getSegment(seg)->getEncStatus() != NZB_ENC_ERROR) { writeOut(file, seg); } nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DONE); }}bool Output::getNext(int *file, int *seg){ if (nzblist->getList()->size() == 0) return false; file_lock->lock(); for (;;) { if (nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_NONE || nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DOWNLOADING || nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DOWNLOADED || nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DL_SKIPPED) { file_lock->unlock(); return false; } if (nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DECODING) { file_lock->unlock(); return false; } if (nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DECODED) { nzblist->getFile(*file)->getSegment(*seg)->setStatus(NZB_PROCESSING); file_lock->unlock(); return true; } if (nzblist->getFile(*file)->getSegment(*seg)->getStatus() == NZB_DEC_SKIPPED) { if (*file == nzblist->getList()->size()-1 && *seg == nzblist->getFile(*file)->getSegments()->size()-1) { emit outputEvent("", 1); } } if (nzblist->getFile(*file)->getSegments()->size() == *seg+1) { if (nzblist->getList()->size() == *file+1) { file_lock->unlock(); return false; } *file = *file + 1; *seg = 0; } else { *seg = *seg + 1; } } file_lock->unlock(); return false;}void Output::writeOut(int file, int seg){ int hdrsize = 0; const char rarhdr[] = {0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00, '\0'}; // RAR Format header + null character. bool streamsrv = false; if (((MainWindow*)parent)->getConfig()->value("output/stream").toBool()) { streamsrv = true; } if (!stream) { if (seg == 0) { QString fn = ((MainWindow*)parent)->getConfig()->value("output/savepath").toString(); if (fn.isEmpty()) { emit outputEvent("Please specify a save path under the output tab in options.", 2); return; } fn += "/"; if (((MainWindow*)parent)->getConfig()->value("output/subfolders").toBool()) { QString fileName; int pos = nzblist->getFile(file)->getNzbFileName().lastIndexOf(QRegExp("[/\\\\]")); if (pos != -1) { fileName = nzblist->getFile(file)->getNzbFileName().right(nzblist->getFile(file)->getNzbFileName().length() - pos - 1); } else { fileName = nzblist->getFile(file)->getNzbFileName(); } if (((MainWindow*)parent)->getConfig()->value("output/guessalbum").toBool()) { pos = fileName.indexOf(QRegExp("[-]")); if (pos != -1) { QString first = fileName.mid(0, pos); QString last = fileName.mid(pos+1); if (first.left(6) == "msgid_") { first = first.mid(first.indexOf(QRegExp("[_]"), 6)); } if (last.right(4) == ".nzb") { last = last.left(last.length() - 4); } first.replace("_", " "); last.replace("_", " "); first = first.trimmed(); last = last.trimmed(); QDir dir; if (!dir.exists(fn+first+"/"+last)) { if (dir.mkpath(fn+first+"/"+last)) { fn += first+"/"+last+"/"; } } else { fn += first+"/"+last+"/"; } } else if (fileName.right(4) == ".nzb") { QDir dir; if (!dir.exists(fn+fileName.left(fileName.length() - 4))) { if (dir.mkdir(fn+fileName.left(fileName.length() - 4))) { fn += fileName.left(fileName.length() - 4)+"/"; } } else { fn += fileName.left(fileName.length() - 4)+"/"; } } else { QDir dir; if (!dir.exists(fn+fileName)) { if (dir.mkdir(fn+fileName)) { fn += fileName+"/"; } } else { fn += fileName+"/"; } } } else if (fileName.right(4) == ".nzb") { QDir dir; if (!dir.exists(fn+fileName.left(fileName.length() - 4))) { if (dir.mkdir(fn+fileName.left(fileName.length() - 4))) { fn += fileName.left(fileName.length() - 4)+"/"; } } else { fn += fileName.left(fileName.length() - 4)+"/"; } } else { QDir dir; if (!dir.exists(fn+fileName)) { if (dir.mkdir(fn+fileName)) { fn += fileName+"/"; } } else { fn += fileName+"/"; } } } fn += nzblist->getFile(file)->getSegment(seg)->getFilename(); fout = new QFile(fn); fout->open(QIODevice::WriteOnly); } if (fout != NULL && fout->error() == QFile::NoError) { fout->write(*(nzblist->getFile(file)->getSegment(seg)->getDecoded())); if (seg == nzblist->getFile(file)->getSegments()->size()-1) { fout->close(); delete fout; fout = NULL; } } if (file == nzblist->getList()->size()-1 && seg == nzblist->getFile(file)->getSegments()->size()-1) { emit outputEvent("", 1); } } else { if (file == 0 && seg == 0) { if (streamsrv) { qDebug("Sending reply"); QString reply = "HTTP/1.0 200 OK\nServer: nzb/"+QString(NZB_VERSION)+"\nConnection: close\nContent-Type: application/octet-stream\n\n"; ms->write(reply.toAscii()); qDebug("Reply sent"); } else { if (((MainWindow*)parent)->getConfig()->value("output/mediaplayer").toString().isEmpty()) { emit outputEvent("Please specify a media player under the output tab in options.", 2); return; } mp = new QProcess(); mp->start(((MainWindow*)parent)->getConfig()->value("output/mediaplayer").toString().toAscii()); mp->waitForStarted(); } } if (!streamsrv && mp == NULL) { return; } if (seg == 0 && (nzblist->getFile(file)->getSegment(seg)->getFilename().mid(nzblist->getFile(file)->getSegment(seg)->getFilename().length() - 4, 2) == ".r" || nzblist->getFile(file)->getSegment(seg)->getFilename().mid(nzblist->getFile(file)->getSegment(seg)->getFilename().length() - 4, 2) == ".R") && strcmp((nzblist->getFile(file)->getSegment(seg)->getDecoded()->mid(0, 7)), rarhdr) == 0) { qDebug() << "nzb: RAR format detected, extracting.\n"; if (nzblist->getFile(file)->getSegment(seg)->getDecoded()->at(45) == 0x30) { hdrsize = (unsigned int)nzblist->getFile(file)->getSegment(seg)->getDecoded()->at(25); if (streamsrv) { ms->write(nzblist->getFile(file)->getSegment(seg)->getDecoded()->mid(20 + hdrsize, nzblist->getFile(file)->getSegment(seg)->getDecoded()->length() - (20 + hdrsize))); } else { mp->write(nzblist->getFile(file)->getSegment(seg)->getDecoded()->mid(20 + hdrsize, nzblist->getFile(file)->getSegment(seg)->getDecoded()->length() - (20 + hdrsize))); //mp->waitForBytesWritten(-1); } } else { qDebug() << "nzb: [Error] Compressed RAR, can't decompress.\n"; emit outputEvent("Compressed RAR, can't decompress.", 2); } } else { QStringList notok; QString src; notok << ".nzb" << ".sfv" << ".par" << ".par2" << ".nfo" << ".jpg"; src = nzblist->getFile(file)->getSegment(seg)->getFilename().mid(nzblist->getFile(file)->getSegment(seg)->getFilename().length() - 4, 4); if (!notok.contains(src.toLower())) { if (streamsrv) { ms->write(*(nzblist->getFile(file)->getSegment(seg)->getDecoded())); //ms->waitForBytesWritten(-1); } else { mp->write(*(nzblist->getFile(file)->getSegment(seg)->getDecoded())); //mp->waitForBytesWritten(-1); } } } if (file == nzblist->getList()->size()-1 && seg == nzblist->getFile(file)->getSegments()->size()-1) { emit outputEvent("", 1); } } nzblist->getFile(file)->getSegment(seg)->setDecoded("");}void Output::stop(){ bool streamsrv = false; if (((MainWindow*)parent)->getConfig()->value("output/stream").toBool()) { streamsrv = true; } if (stream) { if (streamsrv) { if (ms) ms->close(); if (streamer) streamer->close(); } else { if (mp) { mp->closeWriteChannel(); qDebug("Waiting for write finish..."); mp->waitForFinished(-1); qDebug("Done waiting"); delete mp; } this->exit(); } }}void Output::closeStream(){ qDebug("Streamer disconneced"); if (player) { player->quit(); player->wait(); delete player; } //if (ms) delete ms; //if (streamer) delete streamer; qDebug("Killing output"); this->exit();}void Output::newConnection(){ qDebug("Got connection"); ms = streamer->nextPendingConnection(); connect(ms, SIGNAL(disconnected()), this, SLOT(closeStream())); qDebug("Waiting for request"); ms->waitForReadyRead(5000);}void DetachedPlayer::run(){ QProcess::execute(cmd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -