#include "sparentprocess.h" #include "sutilfunction.h" #include #include #include extern QString ERROR_MESSAGE[]; namespace { #if defined(Q_OS_WIN32) const QString APPNAME = "effectprocess.exe"; const QString PYTHON = "python"; #else const QString APPNAME = "./effectprocess"; const QString PYTHON = "python3"; #endif const int TIMEOUT = 9; // 3 minutes const QString SPLIT_KEYWORD = "!@#"; const QString PYTAPPNAME = "effectprocess.py"; const QString NAVER_BLOG_1 = "blog.naver.com/"; const QString NAVER_BLOG_2 = ".blog.me/"; const QString NAVER_CAFE = "cafe.naver.com/"; const QString NAVER_NEWS = "news.naver.com"; const QString DAUM_CAFE = "cafe.daum.net/"; const QString INSTAGRAM = "instagram.com/"; const QString KAKAOSTORY = "story.kakao.com/"; const QString FACEBOOK = "www.facebook.com/"; } SParentProcess::SParentProcess():m_pProcess(new QProcess(this)), m_bRunning(false), nTime(0), m_bUserAbort(false), m_eInnerMode(E_INNER_RUN_MODE::MODE_WAIT)//, m_pErrorSender(new SErrorSender(this)) { QObject::connect(m_pProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finishedProcess(int, QProcess::ExitStatus))); QObject::connect(this, &SParentProcess::signalTerminateError, this, &SParentProcess::slotTerminateError); QObject::connect(m_pProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(finishedProcess(QProcess::ProcessError))); } void SParentProcess::clear() { m_vecError.clear(); m_mapReportSummary.clear(); m_erCurrentRow = SEffectRow(); m_error = SError(); m_bUserAbort = false; nTime = 0; m_bRunning = false; } void SParentProcess::setInnerMode(E_INNER_RUN_MODE _mode) { m_eInnerMode = _mode; } QVector SParentProcess::getErrorList() const { return m_vecError; } SReportSummary SParentProcess::getReportSummary(int _id) const { return m_mapReportSummary.value(_id, SReportSummary()); } QMap SParentProcess::getReportSummary() const { return m_mapReportSummary; } SError SParentProcess::getError() const { return m_error; } bool SParentProcess::isWaiting() const { return m_eInnerMode == E_INNER_RUN_MODE::MODE_WAIT; } void SParentProcess::setModeWait() { m_eInnerMode = E_INNER_RUN_MODE::MODE_WAIT; } QStringList SParentProcess::getProcessArguments(const SEffectRow& _row) const { QStringList slargv; if (_row.url.contains(NAVER_BLOG_1, Qt::CaseInsensitive) || _row.url.contains(NAVER_BLOG_2, Qt::CaseInsensitive) || _row.url.contains(NAVER_CAFE, Qt::CaseInsensitive) || _row.url.contains(NAVER_NEWS, Qt::CaseInsensitive) || _row.url.contains(DAUM_CAFE, Qt::CaseInsensitive)) { slargv.append(APPNAME); } else { slargv << PYTHON << PYTAPPNAME; } if (_row.url.contains(NAVER_BLOG_1, Qt::CaseInsensitive) || _row.url.contains(NAVER_BLOG_2, Qt::CaseInsensitive)) { slargv << "naver" << "blog"; } else if (_row.url.contains(NAVER_CAFE, Qt::CaseInsensitive)) { slargv << "naver" << "cafe"; } else if (_row.url.contains(NAVER_NEWS, Qt::CaseInsensitive)) { slargv << "naver" << "news"; } else if (_row.url.contains(DAUM_CAFE, Qt::CaseInsensitive)) { slargv << "daum" << "cafe"; } else if (_row.url.contains(INSTAGRAM, Qt::CaseInsensitive)) { slargv << "instagram"; } else if (_row.url.contains(KAKAOSTORY, Qt::CaseInsensitive)) { slargv << "kakaostory"; } else if (_row.url.contains(FACEBOOK, Qt::CaseInsensitive)) { slargv << "facebook"; } slargv << _row.eventcode << _row.url << _row.company_startdate.toString("yyyy-MM-dd"); return slargv; } void SParentProcess::runProcess(QStringList _arguments) { //qDebug () << _arguments; if (_arguments.size() > 0) { QString arg = _arguments.at(0); _arguments.removeFirst(); qDebug() << arg; qDebug() << _arguments; m_pProcess->start(arg, _arguments); } else { emit signalLog("x : " + m_erCurrentRow.eventcode + " : " + m_erCurrentRow.url + "\n[99:99:99] ERROR:NO_PROGRAM"); emit signalTerminateEachEvent(m_erCurrentRow.company_num, E_CRAWL_STATE::FAIL); m_vecError.append(m_erCurrentRow); setInnerMode(E_INNER_RUN_MODE::MODE_RUN_EVENTCODE); } } void SParentProcess::setError(const SError& _error) { m_error = _error; } void SParentProcess::setError(SError&& _error) { m_error = std::move(_error); } void SParentProcess::stop() { m_bUserAbort = true; killProcess(); } void SParentProcess::update() { switch(m_eInnerMode) { case E_INNER_RUN_MODE::MODE_WAIT: { setInnerMode(E_INNER_RUN_MODE::MODE_RUN_INIT); break; } case E_INNER_RUN_MODE::MODE_RUN_INIT: { runInit(); break; } case E_INNER_RUN_MODE::MODE_RUN_EVENTCODE: { nTime = 0; runEventCode(); break; } case E_INNER_RUN_MODE::MODE_WAIT_EVENTCODE: { if (++nTime >= TIMEOUT) { setInnerMode(E_INNER_RUN_MODE::MODE_WAIT_HANGING); m_pProcess->kill(); } break; } case E_INNER_RUN_MODE::MODE_WAIT_INIT: { break; } case E_INNER_RUN_MODE::MODE_WAIT_TERMINATE: { break; } case E_INNER_RUN_MODE::MODE_WAIT_HANGING: { break; } } } void SParentProcess::finishedProcess(QProcess::ProcessError _error) { if (m_bUserAbort) { setInnerMode(E_INNER_RUN_MODE::MODE_WAIT_HANGING); emit signalUserAbort(); return; } QProcess *pPro = (QProcess*)sender(); QThread::msleep(100); QString str = pPro->readAllStandardOutput(); SError analyzedResult = analyzeStdOut(str.trimmed()); switch (_error) { case QProcess::FailedToStart: { analyzedResult.error_code = E_ERROR_CODE::NO_PROGRAM; break; } } QString strLog = makeLog(analyzedResult); if (analyzedResult.state == E_CRAWL_STATE::OK) { if (!m_mapReportSummary.contains(analyzedResult.company_num)) m_mapReportSummary.insert(analyzedResult.company_num, SReportSummary()); m_mapReportSummary[analyzedResult.company_num].nOk++; } else { if (!m_mapReportSummary.contains(analyzedResult.company_num)) m_mapReportSummary.insert(analyzedResult.company_num, SReportSummary()); m_mapReportSummary[analyzedResult.company_num].nError++; m_vecError.append(m_erCurrentRow); //m_pErrorSender->send(analyzedResult); } emit signalLog(strLog); emit signalTerminateEachEvent(analyzedResult.company_num, analyzedResult.state); setInnerMode(E_INNER_RUN_MODE::MODE_RUN_EVENTCODE); } void SParentProcess::finishedProcess(int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << "finishedProcess"; if (m_bUserAbort) { setInnerMode(E_INNER_RUN_MODE::MODE_WAIT_HANGING); emit signalUserAbort(); return; } QProcess *pPro = (QProcess*)sender(); QThread::msleep(100); QString str = pPro->readAllStandardOutput(); SError analyzedResult = analyzeStdOut(str.trimmed()); QString strLog = makeLog(analyzedResult); if (analyzedResult.state == E_CRAWL_STATE::OK) { if (!m_mapReportSummary.contains(analyzedResult.company_num)) m_mapReportSummary.insert(analyzedResult.company_num, SReportSummary()); m_mapReportSummary[analyzedResult.company_num].nOk++; //add emit signal Finished success? } else { if (!m_mapReportSummary.contains(analyzedResult.company_num)) m_mapReportSummary.insert(analyzedResult.company_num, SReportSummary()); m_mapReportSummary[analyzedResult.company_num].nError++; m_vecError.append(m_erCurrentRow); //m_pErrorSender->send(analyzedResult); } emit signalLog(strLog); emit signalTerminateEachEvent(analyzedResult.company_num, analyzedResult.state); setInnerMode(E_INNER_RUN_MODE::MODE_RUN_EVENTCODE); //This may be unnecessary :( //pPro->kill(); } SError SParentProcess::analyzeStdOut(const QString& _str) { SError errorResult; if (_str.trimmed().size() < 5) // may be timeout case { errorResult.state = E_CRAWL_STATE::FAIL; errorResult.company_num = m_erCurrentRow.company_num; errorResult.event_code = m_erCurrentRow.eventcode; errorResult.platformname_num = m_erCurrentRow.platformname_num; errorResult.error_code = E_ERROR_CODE::TIMEOUT; errorResult.url = m_erCurrentRow.url; errorResult.str_error = _str; return errorResult; } // unknown type log // This result is treated like unknown error. else if (_str.trimmed().at(0) != 'o' && _str.trimmed().at(0) != 'O' && _str.trimmed().at(0) != 'x' && _str.trimmed().at(0) != 'X') { errorResult.state = E_CRAWL_STATE::FAIL; errorResult.company_num = m_erCurrentRow.company_num; errorResult.event_code = m_erCurrentRow.eventcode; errorResult.platformname_num = m_erCurrentRow.platformname_num; errorResult.error_code = E_ERROR_CODE::UNKNOWN_ERROR; errorResult.url = m_erCurrentRow.url; errorResult.str_error = _str.trimmed().left(200); return errorResult; } else { QStringList slLog = _str.split(SPLIT_KEYWORD); if (slLog.size() < 3) { errorResult.state = E_CRAWL_STATE::FAIL; errorResult.company_num = m_erCurrentRow.company_num; errorResult.event_code = m_erCurrentRow.eventcode; errorResult.platformname_num = m_erCurrentRow.platformname_num; errorResult.error_code = E_ERROR_CODE::UNKNOWN_ERROR; errorResult.url = m_erCurrentRow.url; errorResult.str_error = _str.trimmed().left(200); return errorResult; } else if ((slLog.at(0).trimmed() == "o" || slLog.at(0).trimmed() == "O")) { errorResult.state = E_CRAWL_STATE::OK; errorResult.company_num = m_erCurrentRow.company_num; errorResult.event_code = m_erCurrentRow.eventcode; errorResult.url = m_erCurrentRow.url; /* errorResult.event_code = slLog.at(static_cast(E_LOG_COLUMN::EVENT_CODE)); errorResult.url = slLog.at(static_cast(E_LOG_COLUMN::URL)); */ return errorResult; } else if ((slLog.at(0).trimmed() == "x" || slLog.at(0).trimmed() == "X")) { errorResult.state = E_CRAWL_STATE::FAIL; errorResult.company_num = m_erCurrentRow.company_num; errorResult.platformname_num = m_erCurrentRow.platformname_num; /* errorResult.event_code = slLog.at(static_cast(E_LOG_COLUMN::EVENT_CODE)); errorResult.url = slLog.at(static_cast(E_LOG_COLUMN::URL)); */ switch (slLog.size()) { case static_cast(E_LOG_COLUMN::ERROR_MSG) + 1: { errorResult.str_error = slLog.at( static_cast(E_LOG_COLUMN::ERROR_MSG)).trimmed(); } case static_cast(E_LOG_COLUMN::ERROR_CODE) + 1: { errorResult.error_code = strErrorCodeToEnumErrorCode( slLog.at(static_cast(E_LOG_COLUMN::ERROR_CODE)).trimmed()); } case static_cast(E_LOG_COLUMN::URL) + 1: { errorResult.event_code = slLog.at( static_cast(E_LOG_COLUMN::EVENT_CODE)).trimmed(); errorResult.url = slLog.at( static_cast(E_LOG_COLUMN::URL)).trimmed(); } } return errorResult; } else { errorResult.state = E_CRAWL_STATE::FAIL; errorResult.company_num = m_erCurrentRow.company_num; errorResult.event_code = m_erCurrentRow.eventcode; errorResult.platformname_num = m_erCurrentRow.platformname_num; errorResult.error_code = E_ERROR_CODE::UNKNOWN_ERROR; errorResult.url = m_erCurrentRow.url; errorResult.str_error = _str.trimmed().left(200); return errorResult; } } } void SParentProcess::killProcess() { //if (m_pProcess->state() != QProcess::NotRunning) m_pProcess->kill(); qDebug() << "kill processed"; } QString SParentProcess::makeLog(const SError& _error) { QString str; switch (_error.state) { case E_CRAWL_STATE::OK: { str += "o "; str += m_erCurrentRow.company_name + " "; str += _error.event_code + " "; str += _error.url + " "; break; } case E_CRAWL_STATE::FAIL: { str += "x "; str += m_erCurrentRow.company_name + " "; str += _error.event_code + " "; str += _error.url + "\n[99:99:99] "; str += "ERROR:" + errorCodeToString(_error.error_code) + "\n[99:99:99] "; str += "ERRORMSG:" + _error.str_error; break; } } return str; } void SParentProcess::slotTerminateError(const SError &_error) { setInnerMode(E_INNER_RUN_MODE::MODE_WAIT_TERMINATE); emit signalLog(makeLog(_error)); emit signalTerminate(); } bool SParentProcess::isUserAbort() { return m_bUserAbort; } void SParentProcess::setReportSummary(const QMap& _mapSummary) { m_mapReportSummary = _mapSummary; } void SParentProcess::setCurrentEffectRow(const SEffectRow& _row) { m_erCurrentRow = _row; } void SParentProcess::setCurrentEffectRow(SEffectRow&& _row) { //m_erCurrentRow = _row; m_erCurrentRow = std::move(_row); }