mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-07-30 07:29:33 +02:00
2023-04-12 Fred Gleason <fredg@paravelsystems.com>
* Added 'RDReplicator::roundDownToDow()' methods. * Added a 'Westwood One Wegener Portal' replicator. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
parent
423e2b0e81
commit
4d95134b13
@ -24023,3 +24023,6 @@
|
|||||||
* Incremented the package version to 4.0.0rc2int0.
|
* Incremented the package version to 4.0.0rc2int0.
|
||||||
2023-04-12 Fred Gleason <fredg@paravelsystems.com>
|
2023-04-12 Fred Gleason <fredg@paravelsystems.com>
|
||||||
* Added a 'RDUpload::createDestinationDirs()' method.
|
* Added a 'RDUpload::createDestinationDirs()' method.
|
||||||
|
2023-04-12 Fred Gleason <fredg@paravelsystems.com>
|
||||||
|
* Added 'RDReplicator::roundDownToDow()' methods.
|
||||||
|
* Added a 'Westwood One Wegener Portal' replicator.
|
||||||
|
@ -205,6 +205,10 @@ QString RDReplicator::typeString(RDReplicator::Type type)
|
|||||||
ret="Citadel X-Digital Portal";
|
ret="Citadel X-Digital Portal";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RDReplicator::TypeWw1Ipump:
|
||||||
|
ret="Westwood One Wegener Portal";
|
||||||
|
break;
|
||||||
|
|
||||||
case RDReplicator::TypeLast:
|
case RDReplicator::TypeLast:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -212,6 +216,22 @@ QString RDReplicator::typeString(RDReplicator::Type type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDate RDReplicator::roundDownToDow(const QDate &date,int dow)
|
||||||
|
{
|
||||||
|
return date.addDays(-(date.dayOfWeek()-dow));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDateTime RDReplicator::roundDownToDow(const QDateTime &dt,int dow)
|
||||||
|
{
|
||||||
|
QDateTime ret=dt;
|
||||||
|
|
||||||
|
ret.setDate(RDReplicator::roundDownToDow(dt.date(),dow));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant RDReplicator::GetValue(const QString &field) const
|
QVariant RDReplicator::GetValue(const QString &field) const
|
||||||
{
|
{
|
||||||
QVariant ret;
|
QVariant ret;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
class RDReplicator
|
class RDReplicator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type {TypeCitadelXds=0,TypeLast=1};
|
enum Type {TypeCitadelXds=0,TypeWw1Ipump=1,TypeLast=2};
|
||||||
RDReplicator(const QString &name);
|
RDReplicator(const QString &name);
|
||||||
QString name() const;
|
QString name() const;
|
||||||
RDReplicator::Type type() const;
|
RDReplicator::Type type() const;
|
||||||
@ -58,6 +58,8 @@ class RDReplicator
|
|||||||
int normalizeLevel() const;
|
int normalizeLevel() const;
|
||||||
void setNormalizeLevel(int lvl) const;
|
void setNormalizeLevel(int lvl) const;
|
||||||
QString typeString() const;
|
QString typeString() const;
|
||||||
|
static QDate roundDownToDow(const QDate &date,int dow);
|
||||||
|
static QDateTime roundDownToDow(const QDateTime &dt,int dow);
|
||||||
static QString typeString(RDReplicator::Type type);
|
static QString typeString(RDReplicator::Type type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## Makefile.am
|
## Makefile.am
|
||||||
##
|
##
|
||||||
## (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
|
## (C) Copyright 2010-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License version 2 as
|
## it under the terms of the GNU General Public License version 2 as
|
||||||
@ -15,7 +15,6 @@
|
|||||||
## License along with this program; if not, write to the Free Software
|
## License along with this program; if not, write to the Free Software
|
||||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
##
|
##
|
||||||
##
|
|
||||||
## Use automake to process this into a Makefile.in
|
## Use automake to process this into a Makefile.in
|
||||||
|
|
||||||
AM_CPPFLAGS = -Wall -I$(top_srcdir)/lib -Wno-strict-aliasing -std=c++11 -fPIC @QT5_CFLAGS@ @MUSICBRAINZ_CFLAGS@ @IMAGEMAGICK_CFLAGS@
|
AM_CPPFLAGS = -Wall -I$(top_srcdir)/lib -Wno-strict-aliasing -std=c++11 -fPIC @QT5_CFLAGS@ @MUSICBRAINZ_CFLAGS@ @IMAGEMAGICK_CFLAGS@
|
||||||
@ -30,7 +29,8 @@ sbin_PROGRAMS = rdrepld
|
|||||||
dist_rdrepld_SOURCES = rdrepld.cpp rdrepld.h \
|
dist_rdrepld_SOURCES = rdrepld.cpp rdrepld.h \
|
||||||
replconfig.cpp replconfig.h\
|
replconfig.cpp replconfig.h\
|
||||||
replfactory.cpp replfactory.h\
|
replfactory.cpp replfactory.h\
|
||||||
citadelxds.cpp citadelxds.h
|
citadelxds.cpp citadelxds.h\
|
||||||
|
ww1ipump.cpp ww1ipump.h
|
||||||
nodist_rdrepld_SOURCES = moc_rdrepld.cpp
|
nodist_rdrepld_SOURCES = moc_rdrepld.cpp
|
||||||
rdrepld_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT5_LIBS@ @MUSICBRAINZ_LIBS@ @IMAGEMAGICK_LIBS@
|
rdrepld_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT5_LIBS@ @MUSICBRAINZ_LIBS@ @IMAGEMAGICK_LIBS@
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// The Rivendell Replicator Daemon
|
// The Rivendell Replicator Daemon
|
||||||
//
|
//
|
||||||
// (C) Copyright 2010-2021 Fred Gleason <fredg@paravelsystems.com>
|
// (C) Copyright 2010-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License version 2 as
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "citadelxds.h"
|
#include "citadelxds.h"
|
||||||
#include "rdrepld.h"
|
#include "rdrepld.h"
|
||||||
|
#include "ww1ipump.h"
|
||||||
|
|
||||||
void SigHandler(int signum)
|
void SigHandler(int signum)
|
||||||
{
|
{
|
||||||
@ -149,47 +150,49 @@ void MainObject::ProcessCarts()
|
|||||||
RDEscapeString(q->value(0).toString())+"')||";
|
RDEscapeString(q->value(0).toString())+"')||";
|
||||||
}
|
}
|
||||||
delete q;
|
delete q;
|
||||||
where=where.left(where.length()-2);
|
where=where.left(where.length()-2).trimmed();
|
||||||
sql=QString("select ")+
|
if(!where.isEmpty()) {
|
||||||
"`NUMBER`,"+ // 00
|
|
||||||
"`TYPE`,"+ // 01
|
|
||||||
"`METADATA_DATETIME` "+ // 02
|
|
||||||
"from `CART` where "+
|
|
||||||
where;
|
|
||||||
q=new RDSqlQuery(sql);
|
|
||||||
while(q->next()) {
|
|
||||||
sql=QString("select ")+
|
sql=QString("select ")+
|
||||||
"`ID`,"+ // 00
|
"`NUMBER`,"+ // 00
|
||||||
"`ITEM_DATETIME` "+ // 01
|
"`TYPE`,"+ // 01
|
||||||
"from `REPL_CART_STATE` where "+
|
"`METADATA_DATETIME` "+ // 02
|
||||||
"(`REPLICATOR_NAME`='"+RDEscapeString(repl_name)+"')&&"+
|
"from `CART` where "+
|
||||||
QString::asprintf("(`CART_NUMBER`=%u)",q->value(0).toUInt());
|
where;
|
||||||
q1=new RDSqlQuery(sql);
|
q=new RDSqlQuery(sql);
|
||||||
if(q1->first()) {
|
while(q->next()) {
|
||||||
stale=q->value(2).toDateTime()>q1->value(1).toDateTime();
|
sql=QString("select ")+
|
||||||
}
|
"`ID`,"+ // 00
|
||||||
else {
|
"`ITEM_DATETIME` "+ // 01
|
||||||
stale=true;
|
"from `REPL_CART_STATE` where "+
|
||||||
}
|
"(`REPLICATOR_NAME`='"+RDEscapeString(repl_name)+"')&&"+
|
||||||
if(stale) {
|
QString::asprintf("(`CART_NUMBER`=%u)",q->value(0).toUInt());
|
||||||
if(repl_replicators[i]->processCart(q->value(0).toUInt())) {
|
q1=new RDSqlQuery(sql);
|
||||||
if(q1->isValid()) {
|
if(q1->first()) {
|
||||||
sql=QString("update `REPL_CART_STATE` set ")+
|
stale=q->value(2).toDateTime()>q1->value(1).toDateTime();
|
||||||
"`ITEM_DATETIME`=now() where "+
|
|
||||||
QString::asprintf("`ID`=%u",q1->value(0).toUInt());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sql=QString("insert into `REPL_CART_STATE` set ")+
|
|
||||||
"`REPLICATOR_NAME`='"+RDEscapeString(repl_name)+"',"+
|
|
||||||
QString::asprintf("`CART_NUMBER`=%u,",q->value(0).toUInt())+
|
|
||||||
"`ITEM_DATETIME`=now()";
|
|
||||||
}
|
|
||||||
RDSqlQuery::apply(sql);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
stale=true;
|
||||||
|
}
|
||||||
|
if(stale) {
|
||||||
|
if(repl_replicators[i]->processCart(q->value(0).toUInt())) {
|
||||||
|
if(q1->isValid()) {
|
||||||
|
sql=QString("update `REPL_CART_STATE` set ")+
|
||||||
|
"`ITEM_DATETIME`=now() where "+
|
||||||
|
QString::asprintf("`ID`=%u",q1->value(0).toUInt());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sql=QString("insert into `REPL_CART_STATE` set ")+
|
||||||
|
"`REPLICATOR_NAME`='"+RDEscapeString(repl_name)+"',"+
|
||||||
|
QString::asprintf("`CART_NUMBER`=%u,",q->value(0).toUInt())+
|
||||||
|
"`ITEM_DATETIME`=now()";
|
||||||
|
}
|
||||||
|
RDSqlQuery::apply(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete q1;
|
||||||
}
|
}
|
||||||
delete q1;
|
delete q;
|
||||||
}
|
}
|
||||||
delete q;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +239,10 @@ void MainObject::LoadReplicators()
|
|||||||
repl_replicators.push_back(new CitadelXds(config));
|
repl_replicators.push_back(new CitadelXds(config));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RDReplicator::TypeWw1Ipump:
|
||||||
|
repl_replicators.push_back(new Ww1Ipump(config));
|
||||||
|
break;
|
||||||
|
|
||||||
case RDReplicator::TypeLast:
|
case RDReplicator::TypeLast:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
462
rdrepld/ww1ipump.cpp
Normal file
462
rdrepld/ww1ipump.cpp
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
// ww1ipump.cpp
|
||||||
|
//
|
||||||
|
// Replicator implementation for the Westwood One iPump Replicator
|
||||||
|
//
|
||||||
|
// (C) Copyright 2010-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <rdapplication.h>
|
||||||
|
#include <rdaudioconvert.h>
|
||||||
|
#include <rdcart.h>
|
||||||
|
#include <rdcut.h>
|
||||||
|
#include <rdconf.h>
|
||||||
|
#include <rddb.h>
|
||||||
|
#include <rddelete.h>
|
||||||
|
#include <rdescape_string.h>
|
||||||
|
#include <rdstringlist.h>
|
||||||
|
#include <rdtempdirectory.h>
|
||||||
|
#include <rdupload.h>
|
||||||
|
|
||||||
|
#include "ww1ipump.h"
|
||||||
|
|
||||||
|
#define RD_MAX_CART_NUMBER 999999
|
||||||
|
|
||||||
|
Ww1Ipump::Ww1Ipump(ReplConfig *repl_config)
|
||||||
|
: ReplFactory(repl_config)
|
||||||
|
{
|
||||||
|
QString sql;
|
||||||
|
RDSqlQuery *q;
|
||||||
|
|
||||||
|
sql="select `LAST_ISCI_XREFERENCE` from `VERSION`";
|
||||||
|
q=new RDSqlQuery(sql);
|
||||||
|
if(q->first()) {
|
||||||
|
xds_isci_datetime=q->value(0).toDateTime();
|
||||||
|
}
|
||||||
|
delete q;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ww1Ipump::startProcess()
|
||||||
|
{
|
||||||
|
CheckIsciXreference();
|
||||||
|
CheckCarts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Ww1Ipump::processCart(const unsigned cartnum)
|
||||||
|
{
|
||||||
|
QString sql;
|
||||||
|
RDSqlQuery *q;
|
||||||
|
bool ret=false;
|
||||||
|
|
||||||
|
sql=QString::asprintf("select `FILENAME` from `ISCI_XREFERENCE` \
|
||||||
|
where (`CART_NUMBER`=%u)&&(`LATEST_DATE`>=now())&&\
|
||||||
|
((`TYPE`='R')||(`TYPE`='B'))",cartnum);
|
||||||
|
q=new RDSqlQuery(sql);
|
||||||
|
if(q->first()) {
|
||||||
|
ret=PostCut(RDCut::cutName(cartnum,1),q->value(0).toString());
|
||||||
|
}
|
||||||
|
delete q;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ww1Ipump::CheckIsciXreference()
|
||||||
|
{
|
||||||
|
QString sql;
|
||||||
|
|
||||||
|
QFileInfo *fi=new QFileInfo(rda->system()->isciXreferencePath());
|
||||||
|
if(fi->exists()) {
|
||||||
|
if(fi->lastModified()>xds_isci_datetime) {
|
||||||
|
if(LoadIsciXreference(rda->system()->isciXreferencePath())) {
|
||||||
|
sql="update `VERSION` set `LAST_ISCI_XREFERENCE`=now()";
|
||||||
|
RDSqlQuery::apply(sql);
|
||||||
|
xds_isci_datetime=QDateTime(QDate::currentDate(),QTime::currentTime());
|
||||||
|
PurgeCuts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,"unable to load ISCI cross reference file \"%s\"",
|
||||||
|
(const char *)rda->system()->isciXreferencePath().toUtf8());
|
||||||
|
}
|
||||||
|
delete fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Ww1Ipump::LoadIsciXreference(const QString &filename)
|
||||||
|
{
|
||||||
|
FILE *f=NULL;
|
||||||
|
char line[1024];
|
||||||
|
QString sql;
|
||||||
|
RDSqlQuery *q;
|
||||||
|
RDStringList fields;
|
||||||
|
unsigned cartnum;
|
||||||
|
QStringList datelist;
|
||||||
|
QDate date;
|
||||||
|
bool ok=false;
|
||||||
|
unsigned linenum=3;
|
||||||
|
|
||||||
|
if((f=fopen(filename.toUtf8(),"r"))==NULL) {
|
||||||
|
rda->syslog(LOG_WARNING,
|
||||||
|
"unable to load ISCI cross reference file \"%s\" [%s]",
|
||||||
|
(const char *)rda->system()->isciXreferencePath().toUtf8(),
|
||||||
|
strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Purge Old Data
|
||||||
|
//
|
||||||
|
sql="delete from `ISCI_XREFERENCE`";
|
||||||
|
q=new RDSqlQuery(sql);
|
||||||
|
delete q;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Skip Header
|
||||||
|
//
|
||||||
|
if(fgets(line,1024,f)==NULL) {
|
||||||
|
rda->syslog(LOG_WARNING,"fgets() error reading ISCI xreference data");
|
||||||
|
}
|
||||||
|
if(fgets(line,1024,f)==NULL) {
|
||||||
|
rda->syslog(LOG_WARNING,"fgets() error reading ISCI xreference data");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load Records
|
||||||
|
//
|
||||||
|
while(fgets(line,1024,f)!=NULL) {
|
||||||
|
fields=fields.split(',',line,"\"");
|
||||||
|
if(fields.size()==9) {
|
||||||
|
for(int i=0;i<fields.size();i++) {
|
||||||
|
fields[i]=fields[i].replace("\"","").trimmed();
|
||||||
|
}
|
||||||
|
cartnum=fields[3].right(fields[3].length()-1).toUInt(&ok);
|
||||||
|
if(ok&&(cartnum<=RD_MAX_CART_NUMBER)) {
|
||||||
|
datelist=fields[6].split("/");
|
||||||
|
if(datelist.size()==3) {
|
||||||
|
date.setDate(datelist[2].toInt()+2000,datelist[0].toInt(),
|
||||||
|
datelist[1].toInt());
|
||||||
|
if(ValidateFilename(fields[8])) {
|
||||||
|
if(date.isValid()) {
|
||||||
|
sql=QString("insert into `ISCI_XREFERENCE` set ")+
|
||||||
|
"`CART_NUMBER`="+QString::asprintf("%u",cartnum)+","+
|
||||||
|
"`ISCI`='"+RDEscapeString(fields[4])+"',"+
|
||||||
|
"`FILENAME`='"+RDEscapeString(fields[8])+"',"+
|
||||||
|
"`LATEST_DATE`='"+date.toString("yyyy/MM/dd")+"',"+
|
||||||
|
"`TYPE`='"+RDEscapeString(fields[0])+"',"+
|
||||||
|
"`ADVERTISER_NAME`='"+RDEscapeString(fields[1])+"',"+
|
||||||
|
"`PRODUCT_NAME`='"+RDEscapeString(fields[2])+"',"+
|
||||||
|
"`CREATIVE_TITLE`='"+RDEscapeString(fields[5])+"',"+
|
||||||
|
"`REGION_NAME`='"+RDEscapeString(fields[7])+"'";
|
||||||
|
RDSqlQuery::apply(sql);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,"invalid date in line %d of \"%s\"",
|
||||||
|
linenum,(const char *)filename.toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,
|
||||||
|
"invalid FILENAME field \"%s\" in line %d of \"%s\"",
|
||||||
|
(const char *)fields[8].toUtf8(),linenum,
|
||||||
|
(const char *)filename.toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,"invalid date in line %d of \"%s\"",
|
||||||
|
linenum,(const char *)filename.toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_DEBUG,
|
||||||
|
"missing/invalid cart number in line %d of \"%s\"",
|
||||||
|
linenum,(const char *)filename.toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,"line %d malformed in \"%s\"",
|
||||||
|
linenum,(const char *)filename.toUtf8());
|
||||||
|
}
|
||||||
|
linenum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean Up
|
||||||
|
//
|
||||||
|
rda->syslog(LOG_INFO,"loaded ISCI cross reference file \"%s\"",
|
||||||
|
(const char *)rda->system()->isciXreferencePath().toUtf8());
|
||||||
|
fclose(f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Ww1Ipump::ValidateFilename(const QString &filename)
|
||||||
|
{
|
||||||
|
bool ret=true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// List of illegal characters taken from 'Illegal Characters4.doc'
|
||||||
|
// from Citadel
|
||||||
|
//
|
||||||
|
ret=ret&&(filename.indexOf(" ")<0);
|
||||||
|
ret=ret&&(filename.indexOf("\"")<0);
|
||||||
|
ret=ret&&(filename.indexOf("%")<0);
|
||||||
|
ret=ret&&(filename.indexOf("*")<0);
|
||||||
|
ret=ret&&(filename.indexOf("+")<0);
|
||||||
|
ret=ret&&(filename.indexOf("/")<0);
|
||||||
|
ret=ret&&(filename.indexOf(":")<0);
|
||||||
|
ret=ret&&(filename.indexOf(";")<0);
|
||||||
|
ret=ret&&(filename.indexOf("<")<0);
|
||||||
|
ret=ret&&(filename.indexOf("=")<0);
|
||||||
|
ret=ret&&(filename.indexOf(">")<0);
|
||||||
|
ret=ret&&(filename.indexOf("?")<0);
|
||||||
|
ret=ret&&(filename.indexOf("@")<0);
|
||||||
|
ret=ret&&(filename.indexOf("[")<0);
|
||||||
|
ret=ret&&(filename.indexOf("\\")<0);
|
||||||
|
ret=ret&&(filename.indexOf("]")<0);
|
||||||
|
ret=ret&&(filename.indexOf("^")<0);
|
||||||
|
ret=ret&&(filename.indexOf("{")<0);
|
||||||
|
ret=ret&&(filename.indexOf("|")<0);
|
||||||
|
ret=ret&&(filename.indexOf("}")<0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ww1Ipump::CheckCarts()
|
||||||
|
{
|
||||||
|
QString sql;
|
||||||
|
RDSqlQuery *q;
|
||||||
|
RDSqlQuery *q1;
|
||||||
|
RDSqlQuery *q2;
|
||||||
|
QString now=QDateTime(QDate::currentDate(),QTime::currentTime()).addDays(-6).
|
||||||
|
toString("yyyy-MM-dd hh:mm:ss");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate Update List
|
||||||
|
//
|
||||||
|
sql=QString("select ")+
|
||||||
|
"`CART_NUMBER`,"+ // 00
|
||||||
|
"`FILENAME` "+ // 01
|
||||||
|
"from `ISCI_XREFERENCE` where "+
|
||||||
|
"(`LATEST_DATE`>=now())&&((`TYPE`='R')||(`TYPE`='B'))";
|
||||||
|
q=new RDSqlQuery(sql);
|
||||||
|
while(q->next()) {
|
||||||
|
sql=QString("select `REPL_CART_STATE`.`ID` from ")+
|
||||||
|
"`REPL_CART_STATE` left join `CUTS` "+
|
||||||
|
"on `REPL_CART_STATE`.`CART_NUMBER`=`CUTS`.`CART_NUMBER` where "+
|
||||||
|
"(`CUTS`.`ORIGIN_DATETIME`<`REPL_CART_STATE`.`ITEM_DATETIME`)&&"+
|
||||||
|
"(`REPL_CART_STATE`.`REPLICATOR_NAME`='"+
|
||||||
|
RDEscapeString(config()->name())+"')&&"+
|
||||||
|
QString::asprintf("(`REPL_CART_STATE`.`CART_NUMBER`=%u)&&",
|
||||||
|
q->value(0).toUInt())+
|
||||||
|
"(`REPL_CART_STATE`.`POSTED_FILENAME`='"+
|
||||||
|
RDEscapeString(q->value(1).toString())+"')&&"+
|
||||||
|
"(`REPL_CART_STATE`.`ITEM_DATETIME`>'"+RDEscapeString(now)+"')&&"+
|
||||||
|
"(`REPL_CART_STATE`.`REPOST`='N')";
|
||||||
|
q1=new RDSqlQuery(sql);
|
||||||
|
if(!q1->first()) {
|
||||||
|
if(PostCut(RDCut::cutName(q->value(0).toUInt(),1),
|
||||||
|
q->value(1).toString())) {
|
||||||
|
sql=QString("select `ID` from `REPL_CART_STATE` where ")+
|
||||||
|
"(`REPLICATOR_NAME`='"+RDEscapeString(config()->name())+"')&&"+
|
||||||
|
QString::asprintf("(`CART_NUMBER`=%u)&&",q->value(0).toUInt())+
|
||||||
|
"(`POSTED_FILENAME`='"+RDEscapeString(q->value(1).toString())+"')";
|
||||||
|
q2=new RDSqlQuery(sql);
|
||||||
|
if(q2->first()) {
|
||||||
|
sql=QString("update `REPL_CART_STATE` set ")+
|
||||||
|
"`ITEM_DATETIME`=now(),"+
|
||||||
|
"`REPOST`='N' where "+
|
||||||
|
"(`REPLICATOR_NAME`='"+RDEscapeString(config()->name())+"')&&"+
|
||||||
|
QString::asprintf("(`CART_NUMBER`=%u)&&",q->value(0).toUInt())+
|
||||||
|
"(`POSTED_FILENAME`='"+RDEscapeString(q->value(1).toString())+"')";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sql=QString("insert into `REPL_CART_STATE` set ")+
|
||||||
|
"`ITEM_DATETIME`=now(),"+
|
||||||
|
"`REPOST`='N',"+
|
||||||
|
"`REPLICATOR_NAME`='"+RDEscapeString(config()->name())+"',"+
|
||||||
|
QString::asprintf("`CART_NUMBER`=%u,",q->value(0).toUInt())+
|
||||||
|
"`POSTED_FILENAME`='"+RDEscapeString(q->value(1).toString())+"'";
|
||||||
|
}
|
||||||
|
delete q2;
|
||||||
|
RDSqlQuery::apply(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete q1;
|
||||||
|
}
|
||||||
|
delete q;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Ww1Ipump::PostCut(const QString &cutname,const QString &filename)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Export File
|
||||||
|
//
|
||||||
|
RDAudioConvert::ErrorCode conv_err;
|
||||||
|
RDUpload::ErrorCode upload_err;
|
||||||
|
float speed_ratio=1.0;
|
||||||
|
RDCut *cut=new RDCut(cutname);
|
||||||
|
if(!cut->exists()) {
|
||||||
|
delete cut;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(cut->length()==0) {
|
||||||
|
delete cut;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
RDCart *cart=new RDCart(cut->cartNumber());
|
||||||
|
if(cart->enforceLength()) {
|
||||||
|
speed_ratio=(float)cut->length()/(float)cart->forcedLength();
|
||||||
|
}
|
||||||
|
RDSettings *settings=new RDSettings();
|
||||||
|
QString tempfile=RDTempDirectory::basePath()+"/"+filename;
|
||||||
|
RDAudioConvert *conv=new RDAudioConvert();
|
||||||
|
conv->setSourceFile(RDCut::pathName(cutname));
|
||||||
|
conv->setDestinationFile(tempfile);
|
||||||
|
conv->setRange(cut->startPoint(),cut->endPoint());
|
||||||
|
conv->setSpeedRatio(speed_ratio);
|
||||||
|
settings->setFormat(config()->format());
|
||||||
|
settings->setChannels(config()->channels());
|
||||||
|
settings->setSampleRate(config()->sampleRate());
|
||||||
|
settings->setBitRate(config()->bitRate());
|
||||||
|
settings->setQuality(config()->quality());
|
||||||
|
settings->setNormalizationLevel(config()->normalizeLevel()/1000);
|
||||||
|
conv->setDestinationSettings(settings);
|
||||||
|
delete cart;
|
||||||
|
delete cut;
|
||||||
|
switch(conv_err=conv->convert()) {
|
||||||
|
case RDAudioConvert::ErrorOk:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rda->syslog(LOG_WARNING,
|
||||||
|
"Ww1Ipump: audio conversion failed: %s, cutname: %s",
|
||||||
|
(const char *)RDAudioConvert::errorText(conv_err).toUtf8(),
|
||||||
|
(const char *)cutname.toUtf8());
|
||||||
|
delete conv;
|
||||||
|
delete settings;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delete conv;
|
||||||
|
delete settings;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upload File
|
||||||
|
//
|
||||||
|
QDate monday=RDReplicator::roundDownToDow(QDate::currentDate(),1);
|
||||||
|
QString err_msg;
|
||||||
|
RDUpload *upload=new RDUpload(rda->config());
|
||||||
|
upload->setSourceFile(tempfile);
|
||||||
|
QString dest_url=config()->url();
|
||||||
|
if(dest_url.right(1)!="/") {
|
||||||
|
dest_url+="/";
|
||||||
|
}
|
||||||
|
dest_url+="Spots/"+
|
||||||
|
QString::asprintf("%d/WEEK OF ",monday.year())+
|
||||||
|
monday.toString("MMddyy")+"/"+filename;
|
||||||
|
upload->setDestinationUrl(dest_url);
|
||||||
|
upload->createDestinationDirs(true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: Finish implementing ssh(1) id keys!
|
||||||
|
//
|
||||||
|
switch(upload_err=upload->runUpload(config()->urlUsername(),
|
||||||
|
config()->urlPassword(),"",false,&err_msg,
|
||||||
|
rda->config()->logXloadDebugData())) {
|
||||||
|
case RDUpload::ErrorOk:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rda->syslog(LOG_WARNING,"Ww1Ipump: audio upload failed: %s",
|
||||||
|
err_msg.toUtf8().constData());
|
||||||
|
unlink(tempfile.toUtf8());
|
||||||
|
delete upload;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unlink(tempfile.toUtf8());
|
||||||
|
delete upload;
|
||||||
|
rda->syslog(LOG_INFO,"Ww1Ipump: uploaded cut %s to %s",
|
||||||
|
cutname.toUtf8().constData(),
|
||||||
|
dest_url.toUtf8().constData());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ww1Ipump::PurgeCuts()
|
||||||
|
{
|
||||||
|
QString sql;
|
||||||
|
RDSqlQuery *q;
|
||||||
|
RDSqlQuery *q1;
|
||||||
|
RDSqlQuery *q2;
|
||||||
|
RDDelete *conv;
|
||||||
|
RDDelete::ErrorCode conv_err;
|
||||||
|
|
||||||
|
sql=QString("select ")+
|
||||||
|
"`ID`,"+ // 00
|
||||||
|
"`POSTED_FILENAME` "+ // 01
|
||||||
|
"from `REPL_CART_STATE` where "+
|
||||||
|
"`REPLICATOR_NAME`='"+RDEscapeString(config()->name())+"'";
|
||||||
|
q=new RDSqlQuery(sql);
|
||||||
|
while(q->next()) {
|
||||||
|
sql=QString("select `ID` from `ISCI_XREFERENCE` where ")+
|
||||||
|
"`FILENAME`='"+RDEscapeString(q->value(1).toString())+"'";
|
||||||
|
q1=new RDSqlQuery(sql);
|
||||||
|
if(!q1->first()) {
|
||||||
|
QString path=config()->url();
|
||||||
|
if(path.right(1)!="/") {
|
||||||
|
path+="/";
|
||||||
|
}
|
||||||
|
QUrl url(path+q->value(1).toString());
|
||||||
|
conv=new RDDelete(rda->config());
|
||||||
|
conv->setTargetUrl(url.toString());
|
||||||
|
//
|
||||||
|
// FIXME: Finish implementing ssh(1) key support!
|
||||||
|
//
|
||||||
|
if((conv_err=conv->runDelete(config()->urlUsername(),
|
||||||
|
config()->urlPassword(),"",false,
|
||||||
|
rda->config()->logXloadDebugData()))==
|
||||||
|
RDDelete::ErrorOk) {
|
||||||
|
sql=QString::asprintf("delete from `REPL_CART_STATE` where `ID`=%d",
|
||||||
|
q->value(0).toInt());
|
||||||
|
q2=new RDSqlQuery(sql);
|
||||||
|
delete q2;
|
||||||
|
rda->syslog(LOG_INFO,"purged \"%s\" for replicator \"%s\"",
|
||||||
|
(const char *)url.toString().toUtf8(),
|
||||||
|
(const char *)config()->name().toUtf8());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rda->syslog(LOG_WARNING,
|
||||||
|
"unable to delete \"%s\" for replicator \"%s\" [%s]",
|
||||||
|
(const char *)url.toString().toUtf8(),
|
||||||
|
(const char *)config()->name().toUtf8(),
|
||||||
|
(const char *)RDDelete::errorText(conv_err).toUtf8());
|
||||||
|
}
|
||||||
|
delete conv;
|
||||||
|
}
|
||||||
|
delete q1;
|
||||||
|
}
|
||||||
|
delete q;
|
||||||
|
}
|
44
rdrepld/ww1ipump.h
Normal file
44
rdrepld/ww1ipump.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// ww1ipump.h
|
||||||
|
//
|
||||||
|
// Replicator implementation for the Westwood One iPump Replicator
|
||||||
|
//
|
||||||
|
// (C) Copyright 2010-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef WW1IPUMP_H
|
||||||
|
#define WW1IPUMP_H
|
||||||
|
|
||||||
|
#include "replfactory.h"
|
||||||
|
|
||||||
|
class Ww1Ipump : public ReplFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ww1Ipump(ReplConfig *repl_config);
|
||||||
|
void startProcess();
|
||||||
|
bool processCart(const unsigned cartnum);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CheckIsciXreference();
|
||||||
|
bool LoadIsciXreference(const QString &filename);
|
||||||
|
bool ValidateFilename(const QString &filename);
|
||||||
|
void CheckCarts();
|
||||||
|
bool PostCut(const QString &cutname,const QString &filename);
|
||||||
|
void PurgeCuts();
|
||||||
|
QDateTime xds_isci_datetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WW1IPUMP_H
|
Loading…
x
Reference in New Issue
Block a user