From f36547aab56acf8be5c3c152e9e1829c73ba6033 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 17 May 2018 22:43:47 +0000 Subject: [PATCH] 2018-05-17 Fred Gleason * Added a 'RDAIRPLAY.VIRTUAL_EXIT_CODE' field to the database. * Incremented the database version to 281. * Added 'RDAirPlayConf::virtualExitCode()' and 'RDAirPlayConf::setVirtualExitCode()' methods. * Implemented Start/Stop settings for vlogs. --- ChangeLog | 6 ++ docs/tables/rd_airplay.txt | 50 +--------- lib/dbversion.h | 2 +- lib/rdairplay_conf.cpp | 13 +++ lib/rdairplay_conf.h | 2 + rdadmin/createdb.cpp | 46 ++------- rdvairplay/rdvairplay.cpp | 186 ++++++++++++++++++++++++++++++++---- rdvairplay/rdvairplay.h | 8 ++ utils/rdrevert/rdrevert.cpp | 19 +++- utils/rdrevert/rdrevert.h | 1 + 10 files changed, 225 insertions(+), 108 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0de56557..7bea162f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16838,3 +16838,9 @@ * Added an 'RLM_VLOG_QUANTITY' define to 'rlm.h'. * Updated 'RLM_VERSION' to 18 in 'rlm.h'. * Updated the 'rlm_icecast2' plug-in to support vlogs. +2018-05-17 Fred Gleason + * Added a 'RDAIRPLAY.VIRTUAL_EXIT_CODE' field to the database. + * Incremented the database version to 281. + * Added 'RDAirPlayConf::virtualExitCode()' and + 'RDAirPlayConf::setVirtualExitCode()' methods. + * Implemented Start/Stop settings for vlogs. diff --git a/docs/tables/rd_airplay.txt b/docs/tables/rd_airplay.txt index c39762ba..82cc8578 100644 --- a/docs/tables/rd_airplay.txt +++ b/docs/tables/rd_airplay.txt @@ -28,23 +28,8 @@ BUTTON_LABEL_TEMPLATE char(32) PAUSE_ENABLED enum('N','Y') DEFAULT_SERVICE char(10) From SERVICES.NAME HOUR_SELECTOR_ENABLED enum('N','Y') - -*** RETIRED *** -UDP_ADDR0 char(255) -UDP_PORT0 int(10) unsigned -UDP_STRING0 char(255) -LOG_RML0 char(255) -UDP_ADDR1 char(255) -UDP_PORT1 int(10) unsigned -UDP_STRING1 char(255) -LOG_RML1 char(255) -UDP_ADDR2 char(255) -UDP_PORT2 int(10) unsigned -UDP_STRING2 char(255) -LOG_RML2 char(255) -*** RETIRED *** - EXIT_CODE int(11) 0=clean, 1=dirty +VIRTUAL_EXIT_CODE int(11) 0=clean, 1=dirty EXIT_PASSWORD char(41) SKIN_PATH char(255) SHOW_COUNTERS enum('N','Y') @@ -53,36 +38,3 @@ TITLE_TEMPLATE char(64) ARTIST_TEMPLATE char(64) OUTCUE_TEMPLATE char(64) DESCRIPTION_TEMPLATE char(64) - -*** RETIRED *** -LOG0_START_MODE int(11) 0=start empty, 1=load last, - 2=load specified -LOG0_AUTO_RESTART enum('N','Y') -LOG0_LOG_NAME char(64) From LOGS.NAME -LOG0_CURRENT_LOG char(64) From LOGS.NAME -LOG0_RUNNING enum('N','Y') -LOG0_LOG_ID int(11) -LOG0_LOG_LINE int(11) -LOG0_NOW_CART int(10) unsigned -LOG0_NEXT_CART int(10) unsigned -LOG1_START_MODE int(11) 0=start empty, 1=load last, - 2=load specified -LOG1_AUTO_RESTART enum('N','Y') -LOG1_LOG_NAME char(64) From LOGS.NAME -LOG1_CURRENT_LOG char(64) From LOGS.NAME -LOG1_RUNNING enum('N','Y') -LOG1_LOG_ID int(11) -LOG1_LOG_LINE int(11) -LOG1_NOW_CART int(10) unsigned -LOG1_NEXT_CART int(10) unsigned -LOG2_START_MODE int(11) 0=start empty, 1=load last, - 2=load specified -LOG2_AUTO_RESTART enum('N','Y') -LOG2_LOG_NAME char(64) From LOGS.NAME -LOG2_CURRENT_LOG char(64) From LOGS.NAME -LOG2_RUNNING enum('N','Y') -LOG2_LOG_ID int(11) -LOG2_LOG_LINE int(11) -LOG2_NOW_CART int(10) unsigned -LOG2_NEXT_CART int(10) unsigned -*** RETIRED *** diff --git a/lib/dbversion.h b/lib/dbversion.h index 62d9c1de..593d588c 100644 --- a/lib/dbversion.h +++ b/lib/dbversion.h @@ -24,7 +24,7 @@ /* * Current Database Version */ -#define RD_VERSION_DATABASE 280 +#define RD_VERSION_DATABASE 281 #endif // DBVERSION_H diff --git a/lib/rdairplay_conf.cpp b/lib/rdairplay_conf.cpp index 836af076..44e0a598 100644 --- a/lib/rdairplay_conf.cpp +++ b/lib/rdairplay_conf.cpp @@ -759,6 +759,19 @@ void RDAirPlayConf::setExitCode(RDAirPlayConf::ExitCode code) const } +RDAirPlayConf::ExitCode RDAirPlayConf::virtualExitCode() const +{ + return (RDAirPlayConf::ExitCode) + RDGetSqlValue(air_tablename,"ID",air_id,"VIRTUAL_EXIT_CODE").toInt(); +} + + +void RDAirPlayConf::setVirtualExitCode(RDAirPlayConf::ExitCode code) const +{ + SetRow("VIRTUAL_EXIT_CODE",(int)code); +} + + bool RDAirPlayConf::exitPasswordValid(const QString &passwd) const { QString sql; diff --git a/lib/rdairplay_conf.h b/lib/rdairplay_conf.h index 2614e52b..3bf25f08 100644 --- a/lib/rdairplay_conf.h +++ b/lib/rdairplay_conf.h @@ -139,6 +139,8 @@ class RDAirPlayConf void setLogRml(int logno,const QString &str) const; RDAirPlayConf::ExitCode exitCode() const; void setExitCode(RDAirPlayConf::ExitCode code) const; + RDAirPlayConf::ExitCode virtualExitCode() const; + void setVirtualExitCode(RDAirPlayConf::ExitCode code) const; bool exitPasswordValid(const QString &passwd) const; void setExitPassword(const QString &passwd) const; QString skinPath() const; diff --git a/rdadmin/createdb.cpp b/rdadmin/createdb.cpp index 36d7fd3a..946f31c1 100644 --- a/rdadmin/createdb.cpp +++ b/rdadmin/createdb.cpp @@ -1087,51 +1087,13 @@ bool CreateDb(QString name,QString pwd,RDConfig *config) "ARTIST_TEMPLATE char(64) default '%a',"+ "OUTCUE_TEMPLATE char(64) default '%o',"+ "DESCRIPTION_TEMPLATE char(64) default '%i',"+ - "UDP_ADDR0 char(255),"+ - "UDP_PORT0 int unsigned,"+ - "UDP_STRING0 char(255),"+ - "LOG_RML0 char(255),"+ - "UDP_ADDR1 char(255),"+ - "UDP_PORT1 int unsigned,"+ - "UDP_STRING1 char(255),"+ - "LOG_RML1 char(255),"+ - "UDP_ADDR2 char(255),"+ - "UDP_PORT2 int unsigned,"+ - "UDP_STRING2 char(255),"+ - "LOG_RML2 char(255),"+ "EXIT_CODE int default 0,"+ + "VIRTUAL_EXIT_CODE int default 0,"+ "EXIT_PASSWORD char(41) default \"\","+ "SKIN_PATH char(255) default \""+ RDEscapeString(RD_DEFAULT_RDAIRPLAY_SKIN)+"\","+ "SHOW_COUNTERS enum('N','Y') default 'N',"+ "AUDITION_PREROLL int default 10000,"+ - "LOG0_START_MODE int default 0,"+ - "LOG0_AUTO_RESTART enum('N','Y') default 'N',"+ - "LOG0_LOG_NAME char(64),"+ - "LOG0_CURRENT_LOG char(64),"+ - "LOG0_RUNNING enum('N','Y') default 'N',"+ - "LOG0_LOG_ID int default -1,"+ - "LOG0_LOG_LINE int default -1,"+ - "LOG0_NOW_CART int unsigned default 0,"+ - "LOG0_NEXT_CART int unsigned default 0,"+ - "LOG1_START_MODE int default 0,"+ - "LOG1_AUTO_RESTART enum('N','Y') default 'N',"+ - "LOG1_LOG_NAME char(64),"+ - "LOG1_CURRENT_LOG char(64),"+ - "LOG1_RUNNING enum('N','Y') default 'N',"+ - "LOG1_LOG_ID int default -1,"+ - "LOG1_LOG_LINE int default -1,"+ - "LOG1_NOW_CART int unsigned default 0,"+ - "LOG1_NEXT_CART int unsigned default 0,"+ - "LOG2_START_MODE int default 0,"+ - "LOG2_AUTO_RESTART enum('N','Y') default 'N',"+ - "LOG2_LOG_NAME char(64),"+ - "LOG2_CURRENT_LOG char(64),"+ - "LOG2_RUNNING enum('N','Y') default 'N',"+ - "LOG2_LOG_ID int default -1,"+ - "LOG2_LOG_LINE int default -1,"+ - "LOG2_NOW_CART int unsigned default 0,"+ - "LOG2_NEXT_CART int unsigned default 0,"+ "index STATION_IDX (STATION))"+ config->createTablePostfix(); if(!RunQuery(sql)) { @@ -8246,6 +8208,12 @@ int UpdateDb(int ver,RDConfig *config) } } + if(ver<281) { + sql=QString("alter table RDAIRPLAY add column ")+ + "VIRTUAL_EXIT_CODE int default 0 after EXIT_CODE"; + q=new RDSqlQuery(sql,false); + delete q; + } // diff --git a/rdvairplay/rdvairplay.cpp b/rdvairplay/rdvairplay.cpp index f33552ea..236783c0 100644 --- a/rdvairplay/rdvairplay.cpp +++ b/rdvairplay/rdvairplay.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,19 @@ #include "rdvairplay.h" +bool global_exiting=false; + +void SigHandler(int signo) +{ + switch(signo) { + case SIGINT: + case SIGTERM: + global_exiting=true; + break; + } +} + + MainObject::MainObject(QObject *parent) :QObject(parent) { @@ -56,6 +70,11 @@ MainObject::MainObject(QObject *parent) // RDInitializeDaemons(); + // + // Startup DateTime + // + air_startup_datetime=QDateTime::currentDateTime(); + // // Open the Database // @@ -64,6 +83,8 @@ MainObject::MainObject(QObject *parent) fprintf(stderr,"rdvairplay: %s\n",(const char *)err_msg); exit(1); } + air_previous_exit_code=rda->airplayConf()->virtualExitCode(); + rda->airplayConf()->setVirtualExitCode(RDAirPlayConf::ExitDirty); // // Read Command Options @@ -90,7 +111,8 @@ MainObject::MainObject(QObject *parent) // // RIPC Connection // - // connect(rda->ripc(),SIGNAL(connected(bool)),this,SLOT(ripcConnected(bool))); + connect(rda->ripc(),SIGNAL(connected(bool)), + this,SLOT(ripcConnectedData(bool))); connect(rda,SIGNAL(userChanged()),this,SLOT(userData())); connect(rda->ripc(),SIGNAL(rmlReceived(RDMacro *)), this,SLOT(rmlReceivedData(RDMacro *))); @@ -115,7 +137,6 @@ MainObject::MainObject(QObject *parent) QSignalMapper *reload_mapper=new QSignalMapper(this); connect(reload_mapper,SIGNAL(mapped(int)),this,SLOT(logReloadedData(int))); QSignalMapper *rename_mapper=new QSignalMapper(this); - // connect(rename_mapper,SIGNAL(mapped(int)),this,SLOT(logRenamedData(int))); QString default_svcname=rda->airplayConf()->defaultSvc(); for(int i=0;istart(100); + ::signal(SIGINT,SigHandler); + ::signal(SIGTERM,SigHandler); +} + + +void MainObject::ripcConnectedData(bool state) +{ + QHostAddress addr; + QString sql; + RDSqlQuery *q; + RDMacro rml; + rml.setRole(RDMacro::Cmd); + addr.setAddress("127.0.0.1"); + rml.setAddress(addr); + rml.setEchoRequested(false); + + // + // Get Onair Flag State + // + rda->ripc()->sendOnairFlag(); + + // + // Load Initial Logs + // + for(unsigned i=0;iairplayConf()->startMode(mach)) { + case RDAirPlayConf::StartEmpty: + break; + + case RDAirPlayConf::StartPrevious: + air_start_lognames[i]=RDDateTimeDecode(rda->airplayConf()->currentLog(mach), + air_startup_datetime,rda->station(),rda->config()); + if(!air_start_lognames[i].isEmpty()) { + if(air_previous_exit_code==RDAirPlayConf::ExitDirty) { + if((air_start_lines[i]=rda->airplayConf()->logCurrentLine(mach))>=0) { + air_start_starts[i]=rda->airplayConf()->autoRestart(mach)&& + rda->airplayConf()->logRunning(mach); + } + } + else { + air_start_lines[i]=0; + air_start_starts[i]=false; + } + } + break; + + case RDAirPlayConf::StartSpecified: + air_start_lognames[i]=RDDateTimeDecode(rda->airplayConf()->logName(mach), + air_startup_datetime,rda->station(), + rda->config()); + if(!air_start_lognames[i].isEmpty()) { + if(air_previous_exit_code==RDAirPlayConf::ExitDirty) { + if(air_start_lognames[i]==rda->airplayConf()->currentLog(mach)) { + if((air_start_lines[i]=rda->airplayConf()->logCurrentLine(mach))>=0) { + air_start_starts[i]=rda->airplayConf()->autoRestart(mach)&& + rda->airplayConf()->logRunning(mach); + } + else { + air_start_lines[i]=0; + air_start_starts[i]=false; + } + } + } + } + break; + } + if(!air_start_lognames[i].isEmpty()) { + sql=QString("select NAME from LOGS where ")+ + "NAME=\""+RDEscapeString(air_start_lognames[i])+"\""; + q=new RDSqlQuery(sql); + if(q->first()) { + rml.setCommand(RDMacro::LL); // Load Log + rml.setArgQuantity(2); + rml.setArg(0,mach+1); + rml.setArg(1,air_start_lognames[i]); + rda->ripc()->sendRml(&rml); + } + else { + rda->log(RDConfig::LogWarning,QString().sprintf("vlog %d: ",mach+1)+ + "log \""+air_start_lognames[i]+"\" doesn't exist"); + } + delete q; + } + } } void MainObject::userData() { - printf("User connected!\n"); + // printf("User connected!\n"); } void MainObject::logReloadedData(int log) { + QHostAddress addr; + int mach=log+RD_RDVAIRPLAY_LOG_BASE; + + // + // Load Initial Log + // + if(air_start_lognames[log].isEmpty()) { + return; + } + RDMacro rml; + rml.setRole(RDMacro::Cmd); + addr.setAddress("127.0.0.1"); + rml.setAddress(addr); + rml.setEchoRequested(false); + + if(air_start_lines[log]size()) { + rml.setCommand(RDMacro::MN); // Make Next + rml.setArgQuantity(2); + rml.setArg(0,mach+1); + rml.setArg(1,air_start_lines[log]); + rda->ripc()->sendRml(&rml); + + if(air_start_starts[log]) { + rml.setCommand(RDMacro::PN); // Start Next + rml.setArgQuantity(1); + rml.setArg(0,mach+1); + rda->ripc()->sendRml(&rml); + } + } + else { + rda->log(RDConfig::LogWarning,QString().sprintf("vlog %d: ",mach+1)+ + QString().sprintf("line %d doesn't exist ",air_start_lines[log])+ + "in log \""+air_start_lognames[log]+"\""); + } + air_start_lognames[log]=""; +} + + +void MainObject::exitData() +{ + if(global_exiting) { + for(unsigned i=0;iunload(); + } + for(int i=0;iairplayConf()->setVirtualExitCode(RDAirPlayConf::ExitClean); + rda->log(RDConfig::LogInfo,"RDVAirPlay exiting"); + air_lock->unlock(); + exit(0); + } } @@ -207,22 +372,7 @@ void MainObject::SetAutoMode(int index) void MainObject::SetLiveAssistMode(int index) { - /* - if(mach==0) { - air_pie_counter->setOpMode(RDAirPlayConf::LiveAssist); - } - air_mode_display->setOpMode(mach,RDAirPlayConf::LiveAssist); - air_op_mode[mach]=RDAirPlayConf::LiveAssist; - rda->airplayConf()->setOpMode(mach,RDAirPlayConf::LiveAssist); - */ air_logs[index]->setOpMode(RDAirPlayConf::LiveAssist); - /* - air_log_list[mach]->setOpMode(RDAirPlayConf::LiveAssist); - if(mach==0) { - air_button_list->setOpMode(RDAirPlayConf::LiveAssist); - air_post_counter->setDisabled(true); - } - */ rda->log(RDConfig::LogInfo, QString().sprintf("log machine %d mode set to LIVE ASSIST", index+RD_RDVAIRPLAY_LOG_BASE+1)); diff --git a/rdvairplay/rdvairplay.h b/rdvairplay/rdvairplay.h index 412ded2f..14ae3371 100644 --- a/rdvairplay/rdvairplay.h +++ b/rdvairplay/rdvairplay.h @@ -40,9 +40,11 @@ class MainObject : public QObject MainObject(QObject *parent=0); private slots: + void ripcConnectedData(bool state); void userData(); void rmlReceivedData(RDMacro*); void logReloadedData(int log); + void exitData(); private: void SetAutoMode(int index); @@ -50,10 +52,16 @@ class MainObject : public QObject void SetManualMode(int index); int LogMachineIndex(int log_mach,bool *all=NULL) const; RDLogPlay *air_logs[RD_RDVAIRPLAY_LOG_QUAN]; + QString air_start_lognames[RD_RDVAIRPLAY_LOG_QUAN]; + int air_start_lines[RD_RDVAIRPLAY_LOG_QUAN]; + bool air_start_starts[RD_RDVAIRPLAY_LOG_QUAN]; std::vector air_plugin_hosts; RDInstanceLock *air_lock; RDEventPlayer *air_event_player; QSocketDevice *air_nownext_socket; + QDateTime air_startup_datetime; + RDAirPlayConf::ExitCode air_previous_exit_code; + QTimer *air_exit_timer; }; diff --git a/utils/rdrevert/rdrevert.cpp b/utils/rdrevert/rdrevert.cpp index ade406e1..e17851d9 100644 --- a/utils/rdrevert/rdrevert.cpp +++ b/utils/rdrevert/rdrevert.cpp @@ -279,6 +279,10 @@ void MainObject::Revert(int schema) const case 280: Revert280(); break; + + case 281: + Revert281(); + break; } } @@ -1039,6 +1043,19 @@ void MainObject::Revert280() const } +void MainObject::Revert281() const +{ + QString sql; + RDSqlQuery *q; + + sql=QString("alter table RDAIRPLAY drop column VIRTUAL_EXIT_CODE"); + q=new RDSqlQuery(sql,false); + delete q; + + SetVersion(280); +} + + int MainObject::GetVersion() const { QString sql; @@ -1085,7 +1102,7 @@ int MainObject::MapSchema(const QString &ver) version_map["2.17"]=268; version_map["2.18"]=272; version_map["2.19"]=275; - version_map["2.20"]=280; + version_map["2.20"]=281; // // Normalize String diff --git a/utils/rdrevert/rdrevert.h b/utils/rdrevert/rdrevert.h index 62dbb040..45591b74 100644 --- a/utils/rdrevert/rdrevert.h +++ b/utils/rdrevert/rdrevert.h @@ -76,6 +76,7 @@ class MainObject : public QObject void Revert278() const; void Revert279() const; void Revert280() const; + void Revert281() const; int GetVersion() const; void SetVersion(int schema) const; int MapSchema(const QString &ver);