From ad9e466df9f59f7f4f1dc870169f7748e8f9a1de Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 14 Jul 2021 17:36:26 -0400 Subject: [PATCH] 2021-07-14 Fred Gleason * Restored the ability to post to RSS feeds in rdcatch(1). Signed-off-by: Fred Gleason --- ChangeLog | 2 + rdcatchd/batch.cpp | 165 +++++++++++++++++++++++------------------- rdcatchd/rdcatchd.cpp | 94 +++--------------------- rdcatchd/rdcatchd.h | 13 +--- 4 files changed, 105 insertions(+), 169 deletions(-) diff --git a/ChangeLog b/ChangeLog index 549279eb..efd6a731 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22047,3 +22047,5 @@ * Added a 'timeengine_test' test harness. 2021-07-14 Fred Gleason * Removed the 'RDTimeEvent' class. +2021-07-14 Fred Gleason + * Restored the ability to post to RSS feeds in rdcatch(1). diff --git a/rdcatchd/batch.cpp b/rdcatchd/batch.cpp index 0f168bdf..0f4c2a80 100644 --- a/rdcatchd/batch.cpp +++ b/rdcatchd/batch.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include #include @@ -290,20 +292,6 @@ void MainObject::RunUpload(CatchEvent *evt) (const char *)evt->cutName().toUtf8(), (const char *)evt->tempName().toUtf8(),evt->id()); - // - // Load Podcast Parameters - // - if(evt->feedId()>0) { - QFile *file=new QFile(evt->tempName()); - evt->setPodcastLength(file->size()); - delete file; - RDWaveFile *wave=new RDWaveFile(evt->tempName()); - if(wave->openWave()) { - evt->setPodcastTime(wave->getExtTimeLength()); - } - delete wave; - } - // // Execute Upload // @@ -311,67 +299,98 @@ void MainObject::RunUpload(CatchEvent *evt) (const char *)evt->tempName().toUtf8(), (const char *)evt->resolvedUrl().toUtf8(), evt->id()); - RDUpload *conv=new RDUpload(rda->config(),this); - conv->setSourceFile(evt->tempName()); - conv->setDestinationUrl(evt->resolvedUrl()); - QString url_username=evt->urlUsername(); - QString url_password=evt->urlPassword(); - if(url_username.isEmpty()&& - (QUrl(evt->resolvedUrl()).scheme().toLower()=="ftp")) { - url_username=RD_ANON_FTP_USERNAME; - url_password=QString(RD_ANON_FTP_PASSWORD)+"-"+VERSION; + if(evt->feedId()<=0) { // Standard upload + RDUpload *conv=new RDUpload(rda->config(),this); + conv->setSourceFile(evt->tempName()); + conv->setDestinationUrl(evt->resolvedUrl()); + QString url_username=evt->urlUsername(); + QString url_password=evt->urlPassword(); + if(url_username.isEmpty()&& + (QUrl(evt->resolvedUrl()).scheme().toLower()=="ftp")) { + url_username=RD_ANON_FTP_USERNAME; + url_password=QString(RD_ANON_FTP_PASSWORD)+"-"+VERSION; + } + // + // FIXME: Finish implementing ssh(1) identity keys! + // + switch((conv_err=conv->runUpload(url_username,url_password,"",false, + rda->config()->logXloadDebugData()))) { + case RDUpload::ErrorOk: + catch_connect->setExitCode(evt->id(),RDRecording::Ok,tr("Ok")); + qApp->processEvents(); + rda->syslog(LOG_INFO,"finished upload of %s to %s, id=%d", + (const char *)evt->tempName().toUtf8(), + (const char *)evt->resolvedUrl().toUtf8(), + evt->id()); + break; + + case RDUpload::ErrorInternal: + catch_connect->setExitCode(evt->id(),RDRecording::InternalError, + RDUpload::errorText(conv_err)); + qApp->processEvents(); + rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d", + (const char *)evt->tempName().toUtf8(), + (const char *)RDUpload::errorText(conv_err).toUtf8(), + evt->id()); + break; + + default: + catch_connect->setExitCode(evt->id(),RDRecording::ServerError, + RDUpload::errorText(conv_err)); + qApp->processEvents(); + rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d", + (const char *)evt->tempName().toUtf8(), + (const char *)RDUpload::errorText(conv_err).toUtf8(), + evt->id()); + break; + } + delete conv; + + // + // Clean Up + // + if(evt->deleteTempFile()) { + unlink(evt->tempName().toUtf8()); + rda-> + syslog(LOG_INFO,"deleted file %s",evt->tempName().toUtf8().constData()); + } + else { + RDCheckExitCode("batch.cpp chown",chown(evt->tempName().toUtf8(), + rda->config()->uid(), + rda->config()->gid())); + } } - // - // FIXME: Finish implementing ssh(1) identity keys! - // - switch((conv_err=conv->runUpload(url_username,url_password,"",false, - rda->config()->logXloadDebugData()))) { - case RDUpload::ErrorOk: + else { // Podcast upload + unsigned cast_id; + RDFeed::Error feed_err=RDFeed::ErrorOk; + + RDFeed *feed=new RDFeed(evt->feedId(),rda->config(),this); + rda->syslog(LOG_INFO,"starting post of %s to feed \"%s\", id=%d", + evt->tempName().toUtf8().constData(), + feed->keyName().toUtf8().constData(), + evt->id()); + if((cast_id=feed->postFile(evt->tempName(),&feed_err))==0) { + rda->syslog(LOG_WARNING,"post of %s to feed \"%s\" failed [%s], id=%d", + evt->tempName().toUtf8().constData(), + feed->keyName().toUtf8().constData(), + RDFeed::errorString(feed_err).toUtf8().constData(), + evt->id()); + catch_connect->setExitCode(evt->id(),RDRecording::ServerError, + RDFeed::errorString(feed_err)); + delete feed; + return; + } + rda->syslog(LOG_INFO,"post of %s to cast id %u successful, id=%d", + evt->tempName().toUtf8().constData(), + cast_id, + evt->id()); + RDCart *cart=new RDCart(RDCut::cartNumber(evt->cutName())); + RDPodcast *cast=new RDPodcast(rda->config(),cast_id); + cast->setItemTitle(cart->title()); catch_connect->setExitCode(evt->id(),RDRecording::Ok,tr("Ok")); - qApp->processEvents(); - rda->syslog(LOG_INFO,"finished upload of %s to %s, id=%d", - (const char *)evt->tempName().toUtf8(), - (const char *)evt->resolvedUrl().toUtf8(), - evt->id()); - break; - - case RDUpload::ErrorInternal: - catch_connect->setExitCode(evt->id(),RDRecording::InternalError, - RDUpload::errorText(conv_err)); - qApp->processEvents(); - rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d", - (const char *)evt->tempName().toUtf8(), - (const char *)RDUpload::errorText(conv_err).toUtf8(), - evt->id()); - break; - - default: - catch_connect->setExitCode(evt->id(),RDRecording::ServerError, - RDUpload::errorText(conv_err)); - qApp->processEvents(); - rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d", - (const char *)evt->tempName().toUtf8(), - (const char *)RDUpload::errorText(conv_err).toUtf8(), - evt->id()); - break; - } - delete conv; - - // - // Clean Up - // - if(evt->feedId()>0) { - CheckInPodcast(evt); - } - if(evt->deleteTempFile()) { - unlink(evt->tempName().toUtf8()); - rda->syslog(LOG_INFO,"deleted file %s", - (const char *)evt->tempName().toUtf8()); - } - else { - RDCheckExitCode("batch.cpp chown",chown(evt->tempName().toUtf8(), - rda->config()->uid(), - rda->config()->gid())); + delete cast; + delete cart; + delete feed; } } diff --git a/rdcatchd/rdcatchd.cpp b/rdcatchd/rdcatchd.cpp index f906f4ec..ebaff1f7 100644 --- a/rdcatchd/rdcatchd.cpp +++ b/rdcatchd/rdcatchd.cpp @@ -349,7 +349,6 @@ MainObject::MainObject(QObject *parent) // Time Engine // catch_engine=new RDTimeEngine(this); - catch_engine->setTimeOffset(rda->station()->timeOffset()); connect(catch_engine,SIGNAL(timeout(int)),this,SLOT(engineData(int))); LoadEngine(); @@ -572,7 +571,6 @@ void MainObject::offsetTimerData(int id) void MainObject::engineData(int id) { - // LogLine(QString().sprintf("engineData(%d)",id)); QString sql; RDSqlQuery *q; RDStation *rdstation; @@ -583,9 +581,6 @@ void MainObject::engineData(int id) // QDate date=QDate::currentDate(); QTime current_time=QTime::currentTime(); - if((current_time.msecsTo(QTime(23,59,59))+1000)timeOffset()) { - date=date.addDays(1); - } // // Ignore inactive or non-existent events @@ -810,10 +805,10 @@ void MainObject::engineData(int id) delete q; catch_events[event]. setResolvedUrl(RDDateTimeDecode(catch_events[event].url(), - QDateTime(date.addDays(catch_events[event].eventdateOffset()), - current_time),rda->station(),RDConfiguration())); - StartDownloadEvent(event); - break; + QDateTime(date.addDays(catch_events[event].eventdateOffset()), + current_time),rda->station(),RDConfiguration())); + StartDownloadEvent(event); + break; case RDRecording::Upload: if(!RDCut::exists(catch_events[event].cutName())) { @@ -1664,11 +1659,6 @@ void MainObject::DispatchCommand(ServerConnection *conn) LoadDeckList(); } - if(cmds.at(0)=="RO") { // Reload Time Offset - EchoArgs(conn->id(),'+'); - catch_engine->setTimeOffset(rda->station()->timeOffset()); - } - if((cmds.at(0)=="RE")&&(cmds.size()==2)) { // Request Status chan=cmds.at(1).toInt(&ok); if(!ok) { @@ -1959,6 +1949,12 @@ void MainObject::LoadEvent(RDSqlQuery *q,CatchEvent *e,bool add) e->setChannels(q->value(20).toInt()); e->setSampleRate(q->value(21).toUInt()); e->setBitrate(q->value(22).toInt()); + e->setUrl(q->value(37).toString()); + e->setUrlUsername(q->value(38).toString()); + e->setUrlPassword(q->value(39).toString()); + e->setQuality(q->value(40).toInt()); + e->setNormalizeLevel(q->value(41).toInt()); + e->setFeedId(q->value(45).toUInt()); e->setMacroCart(q->value(23).toInt()); e->setSwitchInput(q->value(24).toInt()); e->setSwitchOutput(q->value(25).toInt()); @@ -1974,15 +1970,9 @@ void MainObject::LoadEvent(RDSqlQuery *q,CatchEvent *e,bool add) e->setEndLength(q->value(34).toInt()); e->setEndMatrix(q->value(35).toInt()); e->setEndLine(q->value(36).toInt()); - e->setUrl(q->value(37).toString()); - e->setUrlUsername(q->value(38).toString()); - e->setUrlPassword(q->value(39).toString()); - e->setQuality(q->value(40).toInt()); - e->setNormalizeLevel(q->value(41).toInt()); e->setAllowMultipleRecordings(RDBool(q->value(42).toString())); e->setMaxGpiRecordLength(q->value(43).toUInt()); e->setDescription(q->value(44).toString()); - e->setFeedId(q->value(45).toUInt()); e->setEventdateOffset(q->value(46).toInt()); e->setEnableMetadata(RDBool(q->value(47).toString())); @@ -2347,70 +2337,6 @@ void MainObject::CheckInRecording(QString cutname,CatchEvent *evt, } -void MainObject::CheckInPodcast(CatchEvent *e) const -{ - QString sql; - RDSqlQuery *q; - - // - // Purge Stale Casts - // - sql=QString("delete from `PODCASTS` where ")+ - QString().sprintf("(`FEED_ID`=%d)&&",e->feedId())+ - "(`AUDIO_FILENAME`='"+RDEscapeString(RDGetBasePart(e->resolvedUrl()))+"')"; - RDSqlQuery::apply(sql); - - // - // Get Channel Parameters - // - sql=QString("select ")+ - "`ENABLE_AUTOPOST`,"+ // 00 - "`CHANNEL_TITLE`,"+ // 01 - "`CHANNEL_DESCRIPTION`,"+ // 02 - "`CHANNEL_CATEGORY`,"+ // 03 - "`CHANNEL_LINK`,"+ // 04 - "`MAX_SHELF_LIFE` "+ // 05 - "from `FEEDS` where "+ - QString().sprintf("`ID`=%u",e->feedId()); - q=new RDSqlQuery(sql); - if(!q->first()) { - delete q; - return; - } - - // - // Add the Cast Entry - // - RDPodcast::Status status=RDPodcast::StatusPending; - if(q->value(0).toString().toLower()=="y") { - status=RDPodcast::StatusActive; - } - sql=QString("insert into `PODCASTS` set ")+ - QString().sprintf("`FEED_ID`=%u,",e->feedId())+ - QString().sprintf("`STATUS`=%u,",status)+ - "`ITEM_TITLE`='"+RDEscapeString(q->value(1).toString())+"',"+ - "`ITEM_DESCRIPTION`='"+RDEscapeString(q->value(2).toString())+"',"+ - "`ITEM_CATEGORY`='"+RDEscapeString(q->value(3).toString())+"',"+ - "`ITEM_LINK`='"+RDEscapeString(q->value(4).toString())+"',"+ - "`AUDIO_FILENAME`='"+RDEscapeString(RDGetBasePart(e->resolvedUrl()))+"',"+ - QString().sprintf("`AUDIO_LENGTH`=%u,",e->podcastLength())+ - QString().sprintf("`AUDIO_TIME`=%u,",e->podcastTime())+ - QString().sprintf("`SHELF_LIFE`=%u,",q->value(5).toUInt())+ - "`EFFECTIVE_DATETIME`=now(),"+ - "`ORIGIN_DATETIME`=now()"; - delete q; - RDSqlQuery::apply(sql); - - // - // Update the Build Date - // - sql=QString("update `FEEDS` set ")+ - "`LAST_BUILD_DATETIME`=now() where "+ - QString().sprintf("`ID`=%u",e->feedId()); - RDSqlQuery::apply(sql); -} - - RDRecording::ExitCode MainObject::ReadExitCode(int event) { RDRecording::ExitCode code=RDRecording::InternalError; diff --git a/rdcatchd/rdcatchd.h b/rdcatchd/rdcatchd.h index 5e87e585..c6862f4e 100644 --- a/rdcatchd/rdcatchd.h +++ b/rdcatchd/rdcatchd.h @@ -24,17 +24,7 @@ #define XLOAD_UPDATE_INTERVAL 1000 #define RDCATCHD_USAGE "[-d][--event-id=]\n\nOptions:\n\n-d\n Set 'debug' mode, causing rdcatchd(8) to stay in the foreground\n and print debugging info on standard output.\n\n--event-id=\n Execute event and then exit.\n\n" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include @@ -178,7 +168,6 @@ class MainObject : public QObject void LoadHeartbeat(); void CheckInRecording(QString cutname,CatchEvent *evt,unsigned msecs, unsigned threshold); - void CheckInPodcast(CatchEvent *e) const; RDRecording::ExitCode ReadExitCode(int event); void WriteExitCode(int event,RDRecording::ExitCode code, const QString &err_text="");