mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-10-10 16:43:35 +02:00
Initial import of CVS-v2_8_branch
This commit is contained in:
76
importers/Makefile.am
Normal file
76
importers/Makefile.am
Normal file
@@ -0,0 +1,76 @@
|
||||
## automake.am
|
||||
##
|
||||
## Automake.am for rivendell/importers
|
||||
##
|
||||
## (C) Copyright 2002-2006 Fred Gleason <fredg@paravelsystems.com>
|
||||
##
|
||||
## $Id: Makefile.am,v 1.18.8.2 2012/11/29 01:37:35 cvs Exp $
|
||||
## $Date: 2012/11/29 01:37:35 $
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
##
|
||||
## Use automake to process this into a Makefile.in
|
||||
|
||||
AM_CPPFLAGS = -Wall @QT_CXXFLAGS@
|
||||
INCLUDES = -I$(top_srcdir)/lib
|
||||
LIBS = @QT_LIBS@ -L$(top_srcdir)/lib
|
||||
MOC = @QT_MOC@
|
||||
|
||||
# The dependency for qt's Meta Object Compiler (moc)
|
||||
moc_%.cpp: %.h
|
||||
$(MOC) $< -o $@
|
||||
|
||||
bin_PROGRAMS = nexgen_filter\
|
||||
panel_copy\
|
||||
rdcatch_copy\
|
||||
rivendell_filter\
|
||||
sas_filter\
|
||||
wings_filter
|
||||
|
||||
dist_nexgen_filter_SOURCES = nexgen_filter.cpp nexgen_filter.h
|
||||
nodist_nexgen_filter_SOURCES = moc_nexgen_filter.cpp
|
||||
nexgen_filter_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
dist_panel_copy_SOURCES = panel_copy.cpp panel_copy.h
|
||||
nodist_panel_copy_SOURCES = moc_panel_copy.cpp
|
||||
panel_copy_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
dist_rdcatch_copy_SOURCES = rdcatch_copy.cpp rdcatch_copy.h
|
||||
nodist_rdcatch_copy_SOURCES = moc_rdcatch_copy.cpp
|
||||
rdcatch_copy_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
dist_rivendell_filter_SOURCES = rivendell_filter.cpp rivendell_filter.h
|
||||
nodist_rivendell_filter_SOURCES = moc_rivendell_filter.cpp
|
||||
rivendell_filter_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
dist_sas_filter_SOURCES = sas_filter.cpp sas_filter.h
|
||||
nodist_sas_filter_SOURCES = moc_sas_filter.cpp
|
||||
sas_filter_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
dist_wings_filter_SOURCES = wings_filter.cpp wings_filter.h
|
||||
nodist_wings_filter_SOURCES = moc_wings_filter.cpp
|
||||
wings_filter_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
|
||||
|
||||
EXTRA_DIST = export_slax
|
||||
|
||||
CLEANFILES = *~\
|
||||
moc_*
|
||||
|
||||
MAINTAINERCLEANFILES = *~\
|
||||
aclocal.m4\
|
||||
configure\
|
||||
Makefile.in\
|
||||
moc_*\
|
||||
*.tar.gz
|
74
importers/export_slax
Executable file
74
importers/export_slax
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
# export_slax
|
||||
#
|
||||
# Export the current Rivendell archive as a SLAX module.
|
||||
#
|
||||
# (C) Copyright 2006 Fred Gleason <fredg@paravelsystems.com>
|
||||
#
|
||||
# $Id: export_slax,v 1.4 2007/02/14 21:48:41 fredg Exp $
|
||||
# $Date: 2007/02/14 21:48:41 $
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# Check arguments
|
||||
#
|
||||
if test -z $1 ; then
|
||||
echo
|
||||
echo " export_slax <module-name> [<audio-owner>]"
|
||||
echo
|
||||
exit 256
|
||||
fi
|
||||
if test -z $2 ; then
|
||||
AUDIO_OWNER=500
|
||||
else
|
||||
AUDIO_OWNER=$2
|
||||
fi
|
||||
|
||||
#
|
||||
# Clean the build tree
|
||||
#
|
||||
BUILD_DIR=/var/tmp/export_slax
|
||||
rm -rf $BUILD_DIR
|
||||
|
||||
#
|
||||
# Build the package tree
|
||||
#
|
||||
mkdir -p $BUILD_DIR/var/lib/mysql/mysql
|
||||
mkdir -p $BUILD_DIR/var/lib/mysql/Rivendell
|
||||
chown -R mysql:users $BUILD_DIR/var/lib/mysql
|
||||
cp -a /var/lib/mysql/mysql $BUILD_DIR/var/lib/mysql/
|
||||
cp -a /var/lib/mysql/Rivendell $BUILD_DIR/var/lib/mysql/
|
||||
cp -a /var/snd $BUILD_DIR/var/
|
||||
chown -R $AUDIO_OWNER:root $BUILD_DIR/var/snd
|
||||
|
||||
#
|
||||
# Generate the package
|
||||
#
|
||||
SOURCE_DIR=`pwd`
|
||||
cd $BUILD_DIR
|
||||
makepkg --prepend --linkadd y --chown n export_slax.tgz
|
||||
tgz2mo export_slax.tgz $SOURCE_DIR/$1
|
||||
cd $SOURCE_DIR
|
||||
|
||||
#
|
||||
# Clean up and exit
|
||||
#
|
||||
#rm -r $BUILD_DIR
|
||||
|
||||
|
||||
# End of export_slax
|
713
importers/nexgen_filter.cpp
Normal file
713
importers/nexgen_filter.cpp
Normal file
@@ -0,0 +1,713 @@
|
||||
// nexgen_filter.cpp
|
||||
//
|
||||
// A Library import filter for the Prophet NexGen system
|
||||
//
|
||||
// (C) Copyright 2012 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: nexgen_filter.cpp,v 1.1.2.8 2013/06/20 20:24:45 cvs Exp $
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qfile.h>
|
||||
#include <qregexp.h>
|
||||
|
||||
#include <rddb.h>
|
||||
#include <rd.h>
|
||||
#include <rdconfig.h>
|
||||
#include <rdconf.h>
|
||||
#include <rdcmd_switch.h>
|
||||
#include <rdcut.h>
|
||||
#include <rdwavefile.h>
|
||||
#include <rdcart.h>
|
||||
#include <rdcut.h>
|
||||
#include <rdweb.h>
|
||||
|
||||
#include <nexgen_filter.h>
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
RDConfig *rdconfig;
|
||||
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
QString group_name;
|
||||
QString audio_dir;
|
||||
QString reject_dir="/dev/null";
|
||||
QStringList xml_files;
|
||||
bool ok=false;
|
||||
char tempdir[PATH_MAX];
|
||||
|
||||
filter_cart_offset=0;
|
||||
filter_delete_cuts=false;
|
||||
filter_normalization_level=0;
|
||||
filter_verbose=false;
|
||||
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"nexgen_filter",
|
||||
NEXGEN_FILTER_USAGE);
|
||||
bool options=true;
|
||||
for(unsigned i=0;i<cmd->keys();i++) {
|
||||
if(!options) {
|
||||
xml_files.push_back(cmd->key(i));
|
||||
}
|
||||
else {
|
||||
if(cmd->key(i)=="--verbose") {
|
||||
filter_verbose=true;
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--group") {
|
||||
group_name=cmd->value(i);
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--audio-dir") {
|
||||
audio_dir=cmd->value(i);
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--reject-dir") {
|
||||
reject_dir=cmd->value(i);
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--cart-offset") {
|
||||
filter_cart_offset=cmd->value(i).toInt(&ok);
|
||||
if(!ok) {
|
||||
fprintf(stderr,"nexgen_filter: --cart-offset must be an integer\n");
|
||||
exit(256);
|
||||
}
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--delete-cuts") {
|
||||
filter_delete_cuts=true;
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(cmd->key(i)=="--normalization-level") {
|
||||
filter_normalization_level=cmd->value(i).toInt(&ok);
|
||||
if(!ok) {
|
||||
fprintf(stderr,"nexgen_filter: --cart-offset must be an integer\n");
|
||||
exit(256);
|
||||
}
|
||||
if(filter_normalization_level>0) {
|
||||
fprintf(stderr,
|
||||
"nexgen_filter: positive --normalization-level is invalid\n");
|
||||
exit(256);
|
||||
}
|
||||
cmd->setProcessed(i,true);
|
||||
}
|
||||
if(!cmd->processed(i)) {
|
||||
options=false;
|
||||
xml_files.push_back(cmd->key(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete cmd;
|
||||
|
||||
//
|
||||
// Open Config
|
||||
//
|
||||
rdconfig=new RDConfig(RD_CONF_FILE);
|
||||
rdconfig->load();
|
||||
|
||||
//
|
||||
// Open Database
|
||||
//
|
||||
filter_db=QSqlDatabase::addDatabase(rdconfig->mysqlDriver());
|
||||
if(!filter_db) {
|
||||
fprintf(stderr,"nexgen_filter: can't open mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
filter_db->setDatabaseName(rdconfig->mysqlDbname());
|
||||
filter_db->setUserName(rdconfig->mysqlUsername());
|
||||
filter_db->setPassword(rdconfig->mysqlPassword());
|
||||
filter_db->setHostName(rdconfig->mysqlHostname());
|
||||
if(!filter_db->open()) {
|
||||
fprintf(stderr,"nexgen_filter: unable to connect to mySQL Server\n");
|
||||
filter_db->removeDatabase(rdconfig->mysqlDbname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
// RIPCD Connection
|
||||
//
|
||||
filter_ripc=new RDRipc("");
|
||||
filter_ripc->connectHost("localhost",RIPCD_TCP_PORT,rdconfig->password());
|
||||
|
||||
//
|
||||
// Station Configuration
|
||||
//
|
||||
filter_rdstation=new RDStation(rdconfig->stationName());
|
||||
|
||||
//
|
||||
// Validate Arguments
|
||||
//
|
||||
if(group_name.isEmpty()) {
|
||||
fprintf(stderr,"nexgen_filter: missing group name\n");
|
||||
exit(256);
|
||||
}
|
||||
filter_group=new RDGroup(group_name);
|
||||
if(!filter_group->exists()) {
|
||||
fprintf(stderr,"nexgen_filter: group \"%s\" does not exist\n",
|
||||
(const char *)group_name);
|
||||
exit(256);
|
||||
}
|
||||
filter_audio_dir=new QDir(audio_dir);
|
||||
if(!audio_dir.isEmpty()) {
|
||||
if(!filter_audio_dir->exists()) {
|
||||
fprintf(stderr,"nexgen_filter: audio directory \"%s\" does not exist\n",
|
||||
(const char *)audio_dir);
|
||||
exit(256);
|
||||
}
|
||||
if(!filter_audio_dir->isReadable()) {
|
||||
fprintf(stderr,"nexgen_filter: audio directory \"%s\" is not readable\n",
|
||||
(const char *)audio_dir);
|
||||
exit(256);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Configure Reject Directory
|
||||
//
|
||||
if(reject_dir=="/dev/null") {
|
||||
filter_reject_dir=NULL;
|
||||
}
|
||||
else {
|
||||
filter_reject_dir=new QDir(reject_dir);
|
||||
if(!filter_reject_dir->exists()) {
|
||||
fprintf(stderr,"nexgen_filter: reject directory \"%s\" does not exist\n",
|
||||
(const char *)reject_dir);
|
||||
exit(256);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Create Temp Directory
|
||||
//
|
||||
strncpy(tempdir,RDTempDir()+"/nexgen_filterXXXXXX",PATH_MAX);
|
||||
filter_temp_dir=new QDir(mkdtemp(tempdir));
|
||||
filter_temp_audiofile=filter_temp_dir->canonicalPath()+"/audio.dat";
|
||||
|
||||
//
|
||||
// Main Loop
|
||||
//
|
||||
for(unsigned i=0;i<xml_files.size();i++) {
|
||||
if(IsXmlFile(xml_files[i])) {
|
||||
if(audio_dir.isEmpty()) {
|
||||
fprintf(stderr,"unable to process \"%s\" [no --audio-dir specified]\n",
|
||||
(const char *)xml_files[i]);
|
||||
}
|
||||
else {
|
||||
ProcessXmlFile(xml_files[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ProcessArchive(xml_files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Clean Up
|
||||
//
|
||||
rmdir(filter_temp_dir->canonicalPath());
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void MainObject::ProcessArchive(const QString &filename)
|
||||
{
|
||||
int fd_in=-1;
|
||||
int fd_out=-1;
|
||||
char tempdir[PATH_MAX];
|
||||
char *data=NULL;
|
||||
QString dir;
|
||||
char header[105];
|
||||
uint32_t len;
|
||||
QString xmlfile;
|
||||
QString wavfile;
|
||||
QStringList files;
|
||||
struct stat stat;
|
||||
blksize_t blksize=1024;
|
||||
ssize_t n=0;
|
||||
|
||||
//
|
||||
// Allocate Default Buffer
|
||||
//
|
||||
data=(char *)malloc(1024);
|
||||
|
||||
//
|
||||
// Create temporary directory
|
||||
//
|
||||
snprintf(tempdir,PATH_MAX,"%s/XXXXXX",(const char *)RDTempDir());
|
||||
if(mkdtemp(tempdir)==NULL) {
|
||||
return;
|
||||
}
|
||||
dir=tempdir;
|
||||
|
||||
//
|
||||
// Open Archive
|
||||
//
|
||||
if((fd_in=open(filename,O_RDONLY))<0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Write Out File Components
|
||||
//
|
||||
while((read(fd_in,header,104)==104)&&(strncmp(header,"FR:",3)==0)) {
|
||||
files.push_back(dir+"/"+RDGetBasePart(QString(header+3).replace("\\","/")));
|
||||
if(files.back().right(4).lower()==".xml") {
|
||||
xmlfile=files.back();
|
||||
}
|
||||
if(files.back().right(4).lower()==".wav") {
|
||||
wavfile=files.back();
|
||||
}
|
||||
len=((0xFF&header[103])<<24)+((0xFF&header[102])<<16)+
|
||||
((0xFF&header[101])<<8)+(0xFF&header[100]);
|
||||
if((fd_out=open(files.back(),O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR))<0) {
|
||||
fprintf(stderr,"unable to write temporary file \"%s\" [%s].\n",
|
||||
(const char *)files.back(),strerror(errno));
|
||||
return;
|
||||
}
|
||||
if(fstat(fd_out,&stat)==0) {
|
||||
blksize=stat.st_blksize;
|
||||
data=(char *)realloc(data,blksize);
|
||||
}
|
||||
for(uint32_t i=blksize;i<len;i+=blksize) {
|
||||
n=read(fd_in,data,blksize);
|
||||
write(fd_out,data,n);
|
||||
}
|
||||
n=read(fd_in,data,len%blksize);
|
||||
write(fd_out,data,n);
|
||||
close(fd_out);
|
||||
}
|
||||
close(fd_in);
|
||||
|
||||
//
|
||||
// Run Import
|
||||
//
|
||||
if((!xmlfile.isEmpty())&&(!wavfile.isEmpty())) {
|
||||
ProcessXmlFile(xmlfile,wavfile,filename);
|
||||
}
|
||||
|
||||
//
|
||||
// Clean Up
|
||||
//
|
||||
for(unsigned i=0;i<files.size();i++) {
|
||||
unlink(files[i]);
|
||||
}
|
||||
rmdir(tempdir);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
||||
void MainObject::ProcessXmlFile(const QString &xml,const QString &wavname,
|
||||
const QString &arcname)
|
||||
{
|
||||
RDCart *cart=NULL;
|
||||
RDCut *cut=NULL;
|
||||
RDWaveData data;
|
||||
QString filename;
|
||||
int cartnum;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
QString delete_cuts_switch="";
|
||||
|
||||
//
|
||||
// Read Metadata
|
||||
//
|
||||
if(!OpenXmlFile(xml,&data,&cartnum,&filename)) {
|
||||
fprintf(stderr,"unable to parse XML file \"%s\"\n",(const char *)xml);
|
||||
WriteReject(xml);
|
||||
return;
|
||||
}
|
||||
if(!wavname.isEmpty()) {
|
||||
filename=wavname;
|
||||
}
|
||||
|
||||
//
|
||||
// Sanity Checks
|
||||
//
|
||||
if((cartnum<1)||(cartnum>999999)) {
|
||||
fprintf(stderr,"calculated cart number [%d] is invalid\n",cartnum);
|
||||
WriteReject(xml);
|
||||
return;
|
||||
}
|
||||
if(filter_group->enforceCartRange()) {
|
||||
if((cartnum<(int)filter_group->defaultLowCart())||
|
||||
(cartnum>(int)filter_group->defaultHighCart())) {
|
||||
fprintf(stderr,
|
||||
"calculated cart number [%d] is invalid for group \"%s\"\n",
|
||||
cartnum,(const char *)filter_group->name());
|
||||
WriteReject(xml);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Audio
|
||||
//
|
||||
if(!PreprocessAudio(filename)) {
|
||||
WriteReject(xml);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Import Audio
|
||||
//
|
||||
Print(QString().sprintf("Importing cart %06d",cartnum));
|
||||
if(!data.title().isEmpty()) {
|
||||
Print(QString().sprintf(" [%s",(const char *)data.title()));
|
||||
if(!data.artist().isEmpty()) {
|
||||
Print(QString().sprintf("/%s",(const char *)data.artist()));
|
||||
}
|
||||
Print(QString().sprintf("]"));
|
||||
}
|
||||
if(arcname.isEmpty()) {
|
||||
Print(QString().sprintf(" from %s ...",(const char *)filename));
|
||||
}
|
||||
else {
|
||||
Print(QString().sprintf(" from %s ...",(const char *)arcname));
|
||||
}
|
||||
if(filter_delete_cuts) {
|
||||
delete_cuts_switch="--delete-cuts ";
|
||||
}
|
||||
if(system(QString().sprintf("rdimport --autotrim-level=0 --normalization-level=%d --to-cart=%d ",
|
||||
filter_normalization_level,cartnum)+
|
||||
+delete_cuts_switch+filter_group->name()+" "+
|
||||
filter_temp_audiofile)!=0) {
|
||||
Print(QString().sprintf(" aborted.\n"));
|
||||
fprintf(stderr,"import of \"%s\" failed\n",(const char *)filename);
|
||||
WriteReject(xml);
|
||||
return;
|
||||
}
|
||||
Print(QString().sprintf(" done.\n"));
|
||||
unlink(filter_temp_audiofile);
|
||||
|
||||
//
|
||||
// Apply Metadata
|
||||
//
|
||||
cart=new RDCart(cartnum);
|
||||
cart->setMetadata(&data);
|
||||
delete cart;
|
||||
sql=
|
||||
QString().sprintf("select CUT_NAME from CUTS where CART_NUMBER=%d",cartnum)+
|
||||
" order by ORIGIN_DATETIME desc";
|
||||
q=new RDSqlQuery(sql);
|
||||
if(q->first()) {
|
||||
cut=new RDCut(q->value(0).toString());
|
||||
cut->setMetadata(&data);
|
||||
delete cut;
|
||||
}
|
||||
delete q;
|
||||
}
|
||||
|
||||
|
||||
bool MainObject::OpenXmlFile(const QString &xml,RDWaveData *data,
|
||||
int *cartnum,QString *filename)
|
||||
{
|
||||
FILE *f=NULL;
|
||||
char line[1024];
|
||||
int crossfade=-1;
|
||||
int fadeup_start=-1;
|
||||
int fadeup_len=-1;
|
||||
|
||||
if((f=fopen(xml,"r"))==NULL) {
|
||||
return false;
|
||||
}
|
||||
if(fgets(line,1024,f)==NULL) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
if(!QString(line).contains("XMLDAT")) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
while(fgets(line,1024,f)!=NULL) {
|
||||
ProcessXmlLine(line,data,cartnum,filename,&crossfade,&fadeup_start,
|
||||
&fadeup_len);
|
||||
}
|
||||
if((fadeup_start>=0)&&(fadeup_len>=0)) { // Calculate Start Marker
|
||||
data->setStartPos(fadeup_start);
|
||||
data->setEndPos(data->endPos()+fadeup_start);
|
||||
data->setFadeUpPos(fadeup_start+fadeup_len);
|
||||
}
|
||||
if((crossfade!=-1)&&(data->endPos()>0)) { // Calculate Segue
|
||||
data->setSegueStartPos(data->endPos()-crossfade);
|
||||
data->setSegueEndPos(data->endPos());
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MainObject::ProcessXmlLine(const QString &line,RDWaveData *data,
|
||||
int *cartnum,QString *filename,
|
||||
int *crossfade,int *fadeup_start,
|
||||
int *fadeup_len)
|
||||
{
|
||||
QString tag=
|
||||
line.mid(line.find("<")+1,line.find(">")-line.find("<")-1).lower();
|
||||
QString value=line.mid(line.find(">")+1,line.findRev("<")-line.find(">")-1);
|
||||
|
||||
// printf("%s: %s\n",(const char *)tag,(const char *)value);
|
||||
|
||||
if(tag=="file_name") {
|
||||
*filename=filter_audio_dir->canonicalPath()+"/"+
|
||||
value.right(value.length()-value.findRev('\\')-1);
|
||||
}
|
||||
if(tag=="cart") {
|
||||
*cartnum=value.toUInt()+filter_cart_offset;
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="title") {
|
||||
data->setTitle(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="artist") {
|
||||
data->setArtist(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="album") {
|
||||
data->setAlbum(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="label") {
|
||||
data->setLabel(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="composer") {
|
||||
data->setComposer(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="licensor") {
|
||||
data->setLicensingOrganization(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="user_define") {
|
||||
data->setUserDefined(RDXmlUnescape(value));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="isrc") {
|
||||
data->setIsrc(value.replace("-",""));
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="modified_time") {
|
||||
QDateTime dt=GetDateTime(value);
|
||||
data->setOriginationDate(dt.date());
|
||||
data->setOriginationTime(dt.time());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="start_time") {
|
||||
QDateTime dt=GetDateTime(value);
|
||||
data->setStartDate(dt.date());
|
||||
data->setStartTime(dt.time());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="end_time") {
|
||||
QDateTime dt=GetDateTime(value);
|
||||
data->setEndDate(dt.date());
|
||||
data->setEndTime(dt.time());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="intro_start") {
|
||||
data->setStartPos(value.toInt());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="intro_3") {
|
||||
if(value.toInt()>0) {
|
||||
data->setIntroStartPos(0);
|
||||
data->setIntroEndPos(value.toInt());
|
||||
}
|
||||
}
|
||||
if(tag=="hookstart") {
|
||||
if(value.toInt()>0) {
|
||||
data->setHookStartPos(value.toInt());
|
||||
}
|
||||
}
|
||||
if(tag=="hookend") {
|
||||
if(value.toInt()>0) {
|
||||
data->setHookEndPos(value.toInt());
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(tag=="length") {
|
||||
data->setEndPos(value.toInt());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
*/
|
||||
if(tag=="runtime") {
|
||||
data->setEndPos(value.toInt());
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
if(tag=="isci_code") {
|
||||
data->setIsci(value);
|
||||
data->setMetadataFound(true);
|
||||
}
|
||||
|
||||
//
|
||||
// Used for calculating segue markers later
|
||||
//
|
||||
if(tag=="cross_fade") {
|
||||
*crossfade=value.toInt();
|
||||
}
|
||||
if(tag=="fade_up_start") {
|
||||
*fadeup_start=value.toInt();
|
||||
}
|
||||
if(tag=="fade_up_length") {
|
||||
*fadeup_len=value.toInt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MainObject::PreprocessAudio(QString filename)
|
||||
{
|
||||
int fd=-1;
|
||||
char c;
|
||||
|
||||
if((fd=open(filename,O_RDONLY))<0) {
|
||||
filename=SwapCase(filename);
|
||||
if((fd=open(filename,O_RDONLY))<0) {
|
||||
fprintf(stderr,"unable to open audio file \"%s\"\n",
|
||||
(const char *)filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
lseek(fd,20,SEEK_SET);
|
||||
if(read(fd,&c,1)!=1) {
|
||||
close(fd);
|
||||
fprintf(stderr,"truncated audio file \"%s\"\n",(const char *)filename);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
if(c==80) { // MPEG Audio
|
||||
if(system(QString("madplay -Q -o wave:")+filter_temp_audiofile+" "+filename)!=0) {
|
||||
fprintf(stderr,"MPEG converter error with file \"%s\"\n",
|
||||
(const char *)filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else { // PCM Audio
|
||||
if(symlink(filename,filter_temp_audiofile)!=0) {
|
||||
fprintf(stderr,"unable to create symlink \"%s\"\n",
|
||||
(const char *)filter_temp_audiofile);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MainObject::WriteReject(const QString &filename)
|
||||
{
|
||||
if(filter_reject_dir!=NULL) {
|
||||
if(QFile::exists(filename)) {
|
||||
if(!RDCopy(filename,filter_reject_dir->canonicalPath()+"/"+
|
||||
RDGetBasePart(filename))) {
|
||||
fprintf(stderr,"Unable to write to \"%s\"\n",
|
||||
(const char *)filter_reject_dir->path());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QDateTime MainObject::GetDateTime(const QString &str) const
|
||||
{
|
||||
QStringList fields;
|
||||
QStringList dates;
|
||||
QStringList times;
|
||||
QDateTime ret;
|
||||
|
||||
fields=fields.split(" ",str);
|
||||
if(fields.size()==2) {
|
||||
dates=dates.split("/",fields[0]);
|
||||
if(dates.size()==3) {
|
||||
times=times.split(":",fields[1]);
|
||||
if(times.size()==3) {
|
||||
ret=
|
||||
QDateTime(QDate(dates[2].toInt(),dates[0].toInt(),dates[1].toInt()),
|
||||
QTime(times[0].toInt(),times[1].toInt(),times[2].toInt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QString MainObject::SwapCase(const QString &str) const
|
||||
{
|
||||
QStringList parts=parts.split(".",str);
|
||||
if(parts[parts.size()-1].contains(QRegExp("*[a-z]*",true,true))>0) {
|
||||
parts[parts.size()-1]=parts[parts.size()-1].upper();
|
||||
}
|
||||
else {
|
||||
parts[parts.size()-1]=parts[parts.size()-1].lower();
|
||||
}
|
||||
return parts.join(".");
|
||||
}
|
||||
|
||||
|
||||
bool MainObject::IsXmlFile(const QString &filename)
|
||||
{
|
||||
int fd=-1;
|
||||
char data[10];
|
||||
|
||||
if((fd=open(filename,O_RDONLY))<0) {
|
||||
return false;
|
||||
}
|
||||
if(read(fd,data,8)!=8) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
data[8]=0;
|
||||
return strncmp(data,"<XMLDAT>",8)==0;
|
||||
}
|
||||
|
||||
|
||||
void MainObject::Print(const QString &msg) const
|
||||
{
|
||||
if(filter_verbose) {
|
||||
printf("%s",(const char *)msg);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
77
importers/nexgen_filter.h
Normal file
77
importers/nexgen_filter.h
Normal file
@@ -0,0 +1,77 @@
|
||||
// nexgen_filter.h
|
||||
//
|
||||
// A Library import filter for the Prophet NexGen system
|
||||
//
|
||||
// (C) Copyright 2012 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: nexgen_filter.h,v 1.1.2.5 2013/06/20 20:24:45 cvs Exp $
|
||||
//
|
||||
// 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 NEXGEN_FILTER_H
|
||||
#define NEXGEN_FILTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qdir.h>
|
||||
|
||||
#include <rdstation.h>
|
||||
#include <rdripc.h>
|
||||
#include <rdgroup.h>
|
||||
#include <rdwavedata.h>
|
||||
|
||||
#define NEXGEN_FILTER_USAGE "[options] <xml-file>|<pkt-file> [...]\n\nImport audio from a Prophet NexGen system, using metadata contained in\none or more XML files. Options are:\n\n--group=<group-name>\n The Rivendell group to use. This option is mandatory and has no default.\n\n--audio-dir=<path>\n The full path to the directory containing the audio files. This option\n is ignored when importing PKT files, but mandatory for importing\n using XML data. It has no default.\n\n--reject-dir=<path>\n The full path to the directory in which to place copies of XML files\n which were unable to be processed. Default is '/dev/null'.\n\n--cart-offset=<offset>\n Apply integer <offset> to the NexGen cart number before importing.\n Default is '0'.\n\n--delete-cuts\n If the destination cart already exists, delete any existing cuts\n within it before importing.\n\n--normalization-level=<level>\n The level to use for normalizing the audio, in dBFS. Specifying '0'\n will turn off normalization. Default is '0'.\n\n--verbose\n Print status messages as files are processed.\n\n<xml-file> [..]\n Filespec for XML file(s) containing import metadata.\n\n"
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
|
||||
private:
|
||||
void ProcessArchive(const QString &filename);
|
||||
void ProcessXmlFile(const QString &xml,const QString &wavname="",
|
||||
const QString &arcname="");
|
||||
bool OpenXmlFile(const QString &xml,RDWaveData *data,int *cartnum,
|
||||
QString *filename);
|
||||
void ProcessXmlLine(const QString &line,RDWaveData *data,int *cartnum,
|
||||
QString *filename,int *crossfade,int *fadeup_start,
|
||||
int *fadeup_len);
|
||||
bool PreprocessAudio(QString filename);
|
||||
void WriteReject(const QString &filename);
|
||||
QDateTime GetDateTime(const QString &str) const;
|
||||
QString SwapCase(const QString &str) const;
|
||||
bool IsXmlFile(const QString &filename);
|
||||
void Print(const QString &msg) const;
|
||||
RDGroup *filter_group;
|
||||
QDir *filter_audio_dir;
|
||||
QDir *filter_reject_dir;
|
||||
QDir *filter_temp_dir;
|
||||
QString filter_temp_audiofile;
|
||||
int filter_cart_offset;
|
||||
bool filter_delete_cuts;
|
||||
int filter_normalization_level;
|
||||
RDStation *filter_rdstation;
|
||||
RDRipc *filter_ripc;
|
||||
QSqlDatabase *filter_db;
|
||||
bool filter_verbose;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
219
importers/panel_copy.cpp
Normal file
219
importers/panel_copy.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
// panel_copy.cpp
|
||||
//
|
||||
// An RDCatch event copier.
|
||||
//
|
||||
// (C) Copyright 2002-2005 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: panel_copy.cpp,v 1.7 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <rddb.h>
|
||||
#include <rd.h>
|
||||
#include <dbversion.h>
|
||||
#include <panel_copy.h>
|
||||
#include <rdcmd_switch.h>
|
||||
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
bool found=false;
|
||||
QString src_hostname;
|
||||
QString dest_hostname;
|
||||
QString src_station;
|
||||
QString dest_station;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
RDSqlQuery *q1;
|
||||
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"panel_copy",
|
||||
PANEL_COPY_USAGE);
|
||||
delete cmd;
|
||||
|
||||
rd_config=new RDConfig(RD_CONF_FILE);
|
||||
rd_config->load();
|
||||
|
||||
//
|
||||
// Read Switches
|
||||
//
|
||||
for(int i=1;i<qApp->argc();i+=2) {
|
||||
found=false;
|
||||
if(QString(qApp->argv()[i])=="-h") { // Source mySQL Hostname
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"panel_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
src_hostname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(QString(qApp->argv()[i])=="-H") { // Source mySQL Hostname
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"panel_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
dest_hostname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!found) {
|
||||
fprintf(stderr,"panel_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
}
|
||||
|
||||
if(src_hostname.isEmpty()) {
|
||||
fprintf(stderr,"panel_copy: invalid source mySQL hostname\n");
|
||||
exit(256);
|
||||
}
|
||||
if(dest_hostname.isEmpty()) {
|
||||
fprintf(stderr,"panel_copy: invalid destination mySQL hostname\n");
|
||||
exit(256);
|
||||
}
|
||||
if(src_hostname==dest_hostname) {
|
||||
fprintf(stderr,"panel_copy: cannot copy a database onto itself\n");
|
||||
exit(256);
|
||||
}
|
||||
|
||||
//
|
||||
// Open Databases
|
||||
//
|
||||
src_db=QSqlDatabase::addDatabase("QMYSQL3","SRCDB");
|
||||
if(!src_db) {
|
||||
fprintf(stderr,"panel_copy: can't open source mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
src_db->setDatabaseName(rd_config->mysqlDbname());
|
||||
src_db->setUserName(rd_config->mysqlUsername());
|
||||
src_db->setPassword(rd_config->mysqlPassword());
|
||||
src_db->setHostName(src_hostname);
|
||||
if(!src_db->open()) {
|
||||
fprintf(stderr,"panel_copy: unable to connect to source mySQL server\n");
|
||||
src_db->removeDatabase(rd_config->mysqlDbname());
|
||||
exit(256);
|
||||
}
|
||||
|
||||
dest_db=QSqlDatabase::addDatabase("QMYSQL3","DESTDB");
|
||||
if(!dest_db) {
|
||||
fprintf(stderr,"panel_copy: can't open destination mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
dest_db->setDatabaseName(rd_config->mysqlDbname());
|
||||
dest_db->setUserName(rd_config->mysqlUsername());
|
||||
dest_db->setPassword(rd_config->mysqlPassword());
|
||||
dest_db->setHostName(dest_hostname);
|
||||
if(!dest_db->open()) {
|
||||
fprintf(stderr,
|
||||
"panel_copy: unable to connect to destination mySQL server\n");
|
||||
dest_db->removeDatabase(rd_config->mysqlDbname());
|
||||
exit(256);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Database Versions
|
||||
//
|
||||
sql="select DB from VERSION";
|
||||
q=new RDSqlQuery(sql,src_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"panel_copy: unable to read source database version\n");
|
||||
exit(256);
|
||||
}
|
||||
if(q->value(0).toInt()!=RD_VERSION_DATABASE) {
|
||||
fprintf(stderr,"panel_copy: source database version mismatch\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
q=new RDSqlQuery(sql,dest_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"panel_copy: unable to read destination database version\n");
|
||||
exit(256);
|
||||
}
|
||||
if(q->value(0).toInt()!=RD_VERSION_DATABASE) {
|
||||
fprintf(stderr,"panel_copy: destination database version mismatch\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Confirmation Prompt
|
||||
//
|
||||
printf("\n");
|
||||
printf("****** WARNING ******\n");
|
||||
printf(" This operation will OVERWRITE ALL SOUNDPANEL BUTTON ASSIGNMENTS on the destination database!");
|
||||
printf(" Press RETURN to continue, or CNTL-C to abort.");
|
||||
printf("\n");
|
||||
while(getchar()!=10);
|
||||
printf("Copying button assignments...");
|
||||
fflush(stdout);
|
||||
|
||||
//
|
||||
// Delete current destination entries
|
||||
//
|
||||
sql="delete from PANELS";
|
||||
q=new RDSqlQuery(sql,dest_db);
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Copy Entries
|
||||
//
|
||||
sql="select TYPE,OWNER,PANEL_NO,ROW_NO,COLUMN_NO,LABEL,CART,DEFAULT_COLOR\
|
||||
from PANELS";
|
||||
q=new RDSqlQuery(sql,src_db);
|
||||
while(q->next()) {
|
||||
sql=QString().sprintf("insert into PANELS set \
|
||||
TYPE=%d,\
|
||||
OWNER=\"%s\",\
|
||||
PANEL_NO=%d,\
|
||||
ROW_NO=%d,\
|
||||
COLUMN_NO=%d,\
|
||||
LABEL=\"%s\",\
|
||||
CART=%d,\
|
||||
DEFAULT_COLOR=\"%s\"",
|
||||
q->value(0).toInt(),
|
||||
(const char *)q->value(1).toString(),
|
||||
q->value(2).toInt(),
|
||||
q->value(3).toInt(),
|
||||
q->value(4).toInt(),
|
||||
(const char *)q->value(5).toString(),
|
||||
q->value(6).toInt(),
|
||||
(const char *)q->value(7).toString());
|
||||
q1=new RDSqlQuery(sql,dest_db);
|
||||
delete q1;
|
||||
}
|
||||
delete q;
|
||||
|
||||
printf("done.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
48
importers/panel_copy.h
Normal file
48
importers/panel_copy.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// panel_copy.h
|
||||
//
|
||||
// A utility for copying SoundPanel assignments between databases.
|
||||
//
|
||||
// (C) Copyright 2002-2005 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: panel_copy.h,v 1.5 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 PANEL_COPY_H
|
||||
#define PANEL_COPY_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
|
||||
#include <rdconfig.h>
|
||||
|
||||
#define PANEL_COPY_USAGE "-h <src-mysql-host> -H <dest-mysql-host>\n"
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
|
||||
private:
|
||||
QSqlDatabase *src_db;
|
||||
QSqlDatabase *dest_db;
|
||||
RDConfig *rd_config;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
335
importers/rdcatch_copy.cpp
Normal file
335
importers/rdcatch_copy.cpp
Normal file
@@ -0,0 +1,335 @@
|
||||
// rdcatch_copy.cpp
|
||||
//
|
||||
// An RDCatch event copier.
|
||||
//
|
||||
// (C) Copyright 2002-2005 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: rdcatch_copy.cpp,v 1.8 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
|
||||
#include <rd.h>
|
||||
#include <dbversion.h>
|
||||
#include <rdcatch_copy.h>
|
||||
#include <rdcmd_switch.h>
|
||||
#include <rddb.h>
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
bool found=false;
|
||||
QString src_hostname;
|
||||
QString dest_hostname;
|
||||
QString src_station;
|
||||
QString dest_station;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
RDSqlQuery *q1;
|
||||
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"rdcatch_copy",
|
||||
RDCATCH_COPY_USAGE);
|
||||
delete cmd;
|
||||
|
||||
rd_config=new RDConfig(RD_CONF_FILE);
|
||||
rd_config->load();
|
||||
|
||||
//
|
||||
// Read Switches
|
||||
//
|
||||
for(int i=1;i<qApp->argc();i+=2) {
|
||||
found=false;
|
||||
if(QString(qApp->argv()[i])=="-h") { // Source mySQL Hostname
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
src_hostname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(QString(qApp->argv()[i])=="-s") { // Source Rivendell Host
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
src_station=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(QString(qApp->argv()[i])=="-H") { // Source mySQL Hostname
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
dest_hostname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(QString(qApp->argv()[i])=="-S") { // Source Rivendell Host
|
||||
if((i+1)==qApp->argc()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
dest_station=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!found) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid argument\n");
|
||||
exit(256);
|
||||
}
|
||||
}
|
||||
|
||||
if(src_hostname.isEmpty()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid source mySQL hostname\n");
|
||||
exit(256);
|
||||
}
|
||||
if(src_station.isEmpty()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid source Rivendell host\n");
|
||||
exit(256);
|
||||
}
|
||||
if(dest_hostname.isEmpty()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid destination mySQL hostname\n");
|
||||
exit(256);
|
||||
}
|
||||
if(dest_station.isEmpty()) {
|
||||
fprintf(stderr,"rdcatch_copy: invalid destination Rivendell host\n");
|
||||
exit(256);
|
||||
}
|
||||
|
||||
//
|
||||
// Open Databases
|
||||
//
|
||||
src_db=QSqlDatabase::addDatabase("QMYSQL3");
|
||||
if(!src_db) {
|
||||
fprintf(stderr,"rdcatch_copy: can't open source mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
src_db->setDatabaseName(rd_config->mysqlDbname());
|
||||
src_db->setUserName(rd_config->mysqlUsername());
|
||||
src_db->setPassword(rd_config->mysqlPassword());
|
||||
src_db->setHostName(src_hostname);
|
||||
if(!src_db->open()) {
|
||||
fprintf(stderr,"rdcatch_copy: unable to connect to source mySQL server\n");
|
||||
src_db->removeDatabase(rd_config->mysqlDbname());
|
||||
exit(256);
|
||||
}
|
||||
|
||||
if(src_hostname==dest_hostname) {
|
||||
if(src_station==dest_station) {
|
||||
fprintf(stderr,"rdcatch_copy: cannot copy a host configuration onto itself\n");
|
||||
exit(256);
|
||||
}
|
||||
else {
|
||||
dest_db=src_db;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dest_db=QSqlDatabase::addDatabase("QMYSQL3");
|
||||
if(!dest_db) {
|
||||
fprintf(stderr,"rdcatch_copy: can't open destination mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
dest_db->setDatabaseName(rd_config->mysqlDbname());
|
||||
dest_db->setUserName(rd_config->mysqlUsername());
|
||||
dest_db->setPassword(rd_config->mysqlPassword());
|
||||
dest_db->setHostName(dest_hostname);
|
||||
if(!dest_db->open()) {
|
||||
fprintf(stderr,
|
||||
"rdcatch_copy: unable to connect to destination mySQL server\n");
|
||||
dest_db->removeDatabase(rd_config->mysqlDbname());
|
||||
exit(256);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Database Versions
|
||||
//
|
||||
sql="select DB from VERSION";
|
||||
q=new RDSqlQuery(sql,src_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"rdcatch_copy: unable to read source database version\n");
|
||||
exit(256);
|
||||
}
|
||||
if(q->value(0).toInt()!=RD_VERSION_DATABASE) {
|
||||
fprintf(stderr,"rdcatch_copy: source database version mismatch\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
q=new RDSqlQuery(sql,dest_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"rdcatch_copy: unable to read destination database version\n");
|
||||
exit(256);
|
||||
}
|
||||
if(q->value(0).toInt()!=RD_VERSION_DATABASE) {
|
||||
fprintf(stderr,"rdcatch_copy: destination database version mismatch\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Check Rivendell Hosts
|
||||
//
|
||||
sql=QString().sprintf("select NAME from STATIONS where NAME=\"%s\"",
|
||||
(const char *)src_station);
|
||||
q=new RDSqlQuery(sql,src_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"rdcatch_copy: source Rivendell host doesn't exist\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
sql=QString().sprintf("select NAME from STATIONS where NAME=\"%s\"",
|
||||
(const char *)dest_station);
|
||||
q=new RDSqlQuery(sql,dest_db);
|
||||
if(!q->first()) {
|
||||
fprintf(stderr,
|
||||
"rdcatch_copy: destination Rivendell host doesn't exist\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Confirmation Prompt
|
||||
//
|
||||
printf("\n");
|
||||
printf("****** WARNING ******\n");
|
||||
printf(" This operation will OVERWRITE ALL RDCATCH EVENTS on the destination Host!");
|
||||
printf(" Press RETURN to continue, or CNTL-C to abort.");
|
||||
printf("\n");
|
||||
while(getchar()!=10);
|
||||
printf("Copying events...");
|
||||
fflush(stdout);
|
||||
|
||||
//
|
||||
// Delete current destination entries
|
||||
//
|
||||
sql=QString().sprintf("delete from RECORDINGS where STATION_NAME\"%s\"",
|
||||
(const char *)dest_station);
|
||||
q=new RDSqlQuery(sql,dest_db);
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Copy Entries
|
||||
//
|
||||
sql=QString().sprintf("select IS_ACTIVE,TYPE,CHANNEL,CUT_NAME,SUN,MON,TUE,\
|
||||
WED,THU,FRI,SAT,DESCRIPTION,START_TYPE,START_TIME,\
|
||||
START_LENGTH,START_MATRIX,START_LINE,START_OFFSET,\
|
||||
END_TYPE,END_TIME,END_LENGTH,END_MATRIX,END_LINE,\
|
||||
LENGTH,TRIM_THRESHOLD,NORMALIZE_LEVEL,\
|
||||
STARTDATE_OFFSET,ENDDATE_OFFSET,FORMAT,CHANNELS,\
|
||||
SAMPRATE,BITRATE,QUALITY,MACRO_CART,SWITCH_INPUT,\
|
||||
SWITCH_OUTPUT,EXIT_CODE,ONE_SHOT,URL,URL_USERNAME,\
|
||||
URL_PASSWORD from RECORDINGS\
|
||||
where STATION_NAME=\"%s\"",
|
||||
(const char *)src_station);
|
||||
q=new RDSqlQuery(sql,src_db);
|
||||
while(q->next()) {
|
||||
sql=QString().sprintf("insert into RECORDINGS set IS_ACTIVE=\"%s\",\
|
||||
TYPE=%d,CHANNEL=%u,CUT_NAME=\"%s\",SUN=\"%s\",\
|
||||
MON=\"%s\",TUE=\"%s\",WED=\"%s\",THU=\"%s\",\
|
||||
FRI=\"%s\",SAT=\"%s\",DESCRIPTION=\"%s\",\
|
||||
START_TYPE=%d,START_TIME=\"%s\",START_LENGTH=%d,\
|
||||
START_MATRIX=%d,START_LINE=%d,START_OFFSET=%d,\
|
||||
END_TYPE=%d,END_TIME=\"%s\",END_LENGTH=%d,\
|
||||
END_MATRIX=%d,END_LINE=%d,LENGTH=%u,\
|
||||
TRIM_THRESHOLD=%d,NORMALIZE_LEVEL=%d,\
|
||||
STARTDATE_OFFSET=%u,ENDDATE_OFFSET=%u,FORMAT=%d,\
|
||||
CHANNELS=%d,SAMPRATE=%d,BITRATE=%d,QUALITY=%d,\
|
||||
MACRO_CART=%d,SWITCH_INPUT=%d,SWITCH_OUTPUT=%d,\
|
||||
EXIT_CODE=%d,ONE_SHOT=\"%s\",URL=\"%s\",\
|
||||
URL_USERNAME=\"%s\",URL_PASSWORD=\"%s\",\
|
||||
STATION_NAME=\"%s\"",
|
||||
(const char *)q->value(0).toString(),
|
||||
|
||||
q->value(1).toInt(),q->value(2).toUInt(),
|
||||
(const char *)q->value(3).toString(),
|
||||
(const char *)q->value(4).toString(),
|
||||
|
||||
(const char *)q->value(5).toString(),
|
||||
(const char *)q->value(6).toString(),
|
||||
(const char *)q->value(7).toString(),
|
||||
(const char *)q->value(8).toString(),
|
||||
|
||||
(const char *)q->value(9).toString(),
|
||||
(const char *)q->value(10).toString(),
|
||||
(const char *)q->value(11).toString(),
|
||||
|
||||
q->value(12).toInt(),
|
||||
(const char *)q->value(13).toString(),
|
||||
q->value(14).toInt(),
|
||||
|
||||
q->value(15).toInt(),
|
||||
q->value(16).toInt(),
|
||||
q->value(17).toInt(),
|
||||
|
||||
q->value(18).toInt(),
|
||||
(const char *)q->value(19).toString(),
|
||||
q->value(20).toInt(),
|
||||
|
||||
q->value(21).toInt(),
|
||||
q->value(22).toInt(),
|
||||
q->value(23).toUInt(),
|
||||
|
||||
q->value(24).toInt(),
|
||||
q->value(25).toInt(),
|
||||
|
||||
q->value(26).toUInt(),
|
||||
q->value(27).toUInt(),
|
||||
q->value(28).toInt(),
|
||||
|
||||
q->value(29).toInt(),
|
||||
q->value(30).toInt(),
|
||||
q->value(31).toInt(),
|
||||
q->value(32).toInt(),
|
||||
|
||||
q->value(33).toInt(),
|
||||
q->value(34).toInt(),
|
||||
q->value(35).toInt(),
|
||||
|
||||
q->value(36).toInt(),
|
||||
(const char *)q->value(37).toString(),
|
||||
(const char *)q->value(38).toString(),
|
||||
|
||||
(const char *)q->value(39).toString(),
|
||||
(const char *)q->value(40).toString(),
|
||||
(const char *)dest_station);
|
||||
q1=new RDSqlQuery(sql,dest_db);
|
||||
delete q1;
|
||||
}
|
||||
delete q;
|
||||
|
||||
printf("done.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
52
importers/rdcatch_copy.h
Normal file
52
importers/rdcatch_copy.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// rdcatch_copy.h
|
||||
//
|
||||
// An RDCatch event copier.
|
||||
//
|
||||
// (C) Copyright 2002-2005 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: rdcatch_copy.h,v 1.6 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 RDCATCH_COPY_H
|
||||
#define RDCATCH_COPY_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
|
||||
#include <rdstation.h>
|
||||
#include <rdripc.h>
|
||||
#include <rdcatch_connect.h>
|
||||
#include <rdstation.h>
|
||||
#include <rdconfig.h>
|
||||
|
||||
#define RDCATCH_COPY_USAGE "-h <src-mysql-host> -s <src-rd-host> -H <dest-mysql-host> -S <dest-rd-host>\n"
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
|
||||
private:
|
||||
QSqlDatabase *src_db;
|
||||
QSqlDatabase *dest_db;
|
||||
RDConfig *rd_config;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
497
importers/rivendell_filter.cpp
Normal file
497
importers/rivendell_filter.cpp
Normal file
@@ -0,0 +1,497 @@
|
||||
// rivendell_filter.cpp
|
||||
//
|
||||
// A Library import filter for an external Rivendell system
|
||||
//
|
||||
// (C) Copyright 2002-2005,2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: rivendell_filter.cpp,v 1.3 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qdir.h>
|
||||
|
||||
#include <rddb.h>
|
||||
#include <rd.h>
|
||||
#include <rdconf.h>
|
||||
#include <rdconfig.h>
|
||||
#include <rdcmd_switch.h>
|
||||
#include <rdescape_string.h>
|
||||
#include <rdcut.h>
|
||||
#include <rivendell_filter.h>
|
||||
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
RDConfig *rdconfig;
|
||||
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
QString ext_dbname;
|
||||
QString ext_hostname;
|
||||
QString ext_username;
|
||||
QString ext_password;
|
||||
QString ext_audiodir;
|
||||
QString default_group;
|
||||
unsigned start_cartnum=0;
|
||||
unsigned end_cartnum=0;
|
||||
QSqlDatabase *filter_db;
|
||||
QSqlDatabase *ext_db;
|
||||
bool ok=false;
|
||||
bool found;
|
||||
QString start_datetime;
|
||||
QString end_datetime;
|
||||
QString start_daypart;
|
||||
QString end_daypart;
|
||||
QString owner;
|
||||
QString group;
|
||||
QString sql;
|
||||
QSqlQuery *q;
|
||||
QSqlQuery *q1;
|
||||
QSqlQuery *q2;
|
||||
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"rivendell_filter",
|
||||
RIVENDELL_FILTER_USAGE);
|
||||
delete cmd;
|
||||
|
||||
rdconfig=new RDConfig(RD_CONF_FILE);
|
||||
rdconfig->load();
|
||||
|
||||
//
|
||||
// Open Local Database
|
||||
//
|
||||
filter_db=QSqlDatabase::addDatabase(rdconfig->mysqlDriver(),"LOCAL_DB");
|
||||
if(!filter_db) {
|
||||
fprintf(stderr,"rivendell_filter: can't open local mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
filter_db->setDatabaseName(rdconfig->mysqlDbname());
|
||||
filter_db->setUserName(rdconfig->mysqlUsername());
|
||||
filter_db->setPassword(rdconfig->mysqlPassword());
|
||||
filter_db->setHostName(rdconfig->mysqlHostname());
|
||||
if(!filter_db->open()) {
|
||||
fprintf(stderr,
|
||||
"rivendell_filter: unable to connect to local mySQL Server\n");
|
||||
filter_db->removeDatabase(rdconfig->mysqlDbname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
// Read Arguments
|
||||
//
|
||||
for(int i=1;i<(qApp->argc()-1);i+=2) {
|
||||
found=false;
|
||||
if(!strcmp("-h",qApp->argv()[i])) {
|
||||
ext_hostname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-u",qApp->argv()[i])) {
|
||||
ext_username=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-p",qApp->argv()[i])) {
|
||||
ext_password=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-A",qApp->argv()[i])) {
|
||||
ext_audiodir=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-g",qApp->argv()[i])) {
|
||||
default_group=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-s",qApp->argv()[i])) {
|
||||
start_cartnum=QString(qApp->argv()[i+1]).toUInt(&ok);
|
||||
if(!ok) {
|
||||
fprintf(stderr,"\nrivendell_filter: invalid group number\n");
|
||||
exit(256);
|
||||
}
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-e",qApp->argv()[i])) {
|
||||
end_cartnum=QString(qApp->argv()[i+1]).toUInt(&ok);
|
||||
if(!ok) {
|
||||
fprintf(stderr,"\nrivendell_filter: invalid group number\n");
|
||||
exit(256);
|
||||
}
|
||||
found=true;
|
||||
}
|
||||
if(!found) {
|
||||
fprintf(stderr,"\nrivendell_filter %s\n",RIVENDELL_FILTER_USAGE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if((start_cartnum==0)||(start_cartnum>999999)) {
|
||||
fprintf(stderr,"\nrivendell_filter: invalid start cart value\n");
|
||||
exit(256);
|
||||
}
|
||||
if((end_cartnum==0)||(end_cartnum>999999)) {
|
||||
fprintf(stderr,"\nrivendell_filter: invalid end cart value\n");
|
||||
exit(256);
|
||||
}
|
||||
if(start_cartnum>end_cartnum) {
|
||||
fprintf(stderr,"\nrivendell_filter: invalid cart values\n");
|
||||
exit(256);
|
||||
}
|
||||
if(ext_audiodir.isEmpty()) {
|
||||
fprintf(stderr,"rivendell_filter: invalid source audio directory\n");
|
||||
exit(256);
|
||||
}
|
||||
QDir dir=QDir(ext_audiodir);
|
||||
if(!dir.exists()) {
|
||||
fprintf(stderr,"rivendell_filter: invalid source audio directory\n");
|
||||
exit(256);
|
||||
}
|
||||
if(!dir.isReadable()) {
|
||||
fprintf(stderr,
|
||||
"rivendell_filter: source audio directory is not readable\n");
|
||||
exit(256);
|
||||
}
|
||||
if(ext_audiodir.right(1)!="/") {
|
||||
ext_audiodir+="/";
|
||||
}
|
||||
|
||||
//
|
||||
// Open Remote Database
|
||||
//
|
||||
ext_db=QSqlDatabase::addDatabase(rdconfig->mysqlDriver(),"REMOTE_DB");
|
||||
if(!ext_db) {
|
||||
fprintf(stderr,"rivendell_filter: can't open remote mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
ext_db->setDatabaseName(rdconfig->mysqlDbname());
|
||||
ext_db->setUserName(ext_username);
|
||||
ext_db->setPassword(ext_password);
|
||||
ext_db->setHostName(ext_hostname);
|
||||
if(!ext_db->open()) {
|
||||
fprintf(stderr,
|
||||
"rivendell_filter: unable to connect to remote mySQL Server\n");
|
||||
ext_db->removeDatabase(rdconfig->mysqlDbname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
// Verify that default group exists
|
||||
//
|
||||
sql=QString().sprintf("select NAME from GROUPS where NAME=\"%s\"",
|
||||
(const char *)default_group);
|
||||
q=new QSqlQuery(sql,filter_db);
|
||||
if(!q->next()) {
|
||||
fprintf(stderr,"rivendell_filter: default group does not exist\n");
|
||||
exit(256);
|
||||
}
|
||||
delete q;
|
||||
|
||||
//
|
||||
// Transfer Loop
|
||||
//
|
||||
sql=QString().sprintf("select NUMBER,TYPE,GROUP_NAME,TITLE,ARTIST,ALBUM,\
|
||||
YEAR,ISRC,LABEL,CLIENT,AGENCY,PUBLISHER,COMPOSER,\
|
||||
USER_DEFINED,USAGE_CODE,FORCED_LENGTH,AVERAGE_LENGTH,\
|
||||
LENGTH_DEVIATION,AVERAGE_SEGUE_LENGTH,\
|
||||
AVERAGE_HOOK_LENGTH,CUT_QUANTITY,LAST_CUT_PLAYED,\
|
||||
PLAY_ORDER,VALIDITY,\
|
||||
ENFORCE_LENGTH,PRESERVE_PITCH,ASYNCRONOUS,\
|
||||
OWNER,MACROS,SCHED_CODES from CART \
|
||||
where (NUMBER>=%u)&&(NUMBER<=%u)",
|
||||
start_cartnum,end_cartnum);
|
||||
q=new QSqlQuery(sql,ext_db);
|
||||
while(q->next()) {
|
||||
printf("Transferring cart %06u [%s]...",q->value(0).toUInt(),
|
||||
(const char *)q->value(3).toString());
|
||||
fflush(stdout);
|
||||
|
||||
//
|
||||
// Validate Group
|
||||
//
|
||||
sql=QString().sprintf("select NAME from GROUPS where NAME=\"%s\"",
|
||||
(const char *)RDEscapeString(q->value(2).toString()));
|
||||
q1=new QSqlQuery(sql,filter_db);
|
||||
if(q1->first()) {
|
||||
group=q->value(2).toString();
|
||||
}
|
||||
else {
|
||||
group=default_group;
|
||||
}
|
||||
delete q1;
|
||||
|
||||
//
|
||||
// Purge old entries
|
||||
//
|
||||
sql=QString().sprintf("select CUT_NAME from CUTS where CART_NUMBER=%u",
|
||||
q->value(0).toUInt());
|
||||
q1=new QSqlQuery(sql,filter_db);
|
||||
while(q1->next()) {
|
||||
unlink(RDCut::pathName(q1->value(0).toString()));
|
||||
}
|
||||
delete q1;
|
||||
sql=QString().sprintf("delete from CUTS where CART_NUMBER=%u",
|
||||
q->value(0).toUInt());
|
||||
q1=new QSqlQuery(sql,filter_db);
|
||||
delete q1;
|
||||
sql=QString().sprintf("delete from CART where NUMBER=%u",
|
||||
q->value(0).toUInt());
|
||||
q1=new QSqlQuery(sql,filter_db);
|
||||
delete q1;
|
||||
|
||||
//
|
||||
// Create new entries
|
||||
//
|
||||
if(q->value(27).isNull()) {
|
||||
owner="null";
|
||||
}
|
||||
else {
|
||||
owner=QString().sprintf("\"%s\"",
|
||||
(const char *)RDEscapeString(q->value(27).toString()));
|
||||
}
|
||||
sql=QString().sprintf("insert into CART set NUMBER=%u,\
|
||||
TYPE=%u,\
|
||||
GROUP_NAME=\"%s\",\
|
||||
TITLE=\"%s\",\
|
||||
ARTIST=\"%s\",\
|
||||
ALBUM=\"%s\",\
|
||||
YEAR=\"%s\",\
|
||||
ISRC=\"%s\",\
|
||||
LABEL=\"%s\",\
|
||||
CLIENT=\"%s\",\
|
||||
AGENCY=\"%s\",\
|
||||
PUBLISHER=\"%s\",\
|
||||
COMPOSER=\"%s\",\
|
||||
USER_DEFINED=\"%s\",\
|
||||
USAGE_CODE=\"%s\",\
|
||||
FORCED_LENGTH=%u,\
|
||||
AVERAGE_LENGTH=%u,\
|
||||
LENGTH_DEVIATION=%u,\
|
||||
AVERAGE_SEGUE_LENGTH=%u,\
|
||||
AVERAGE_HOOK_LENGTH=%u,\
|
||||
CUT_QUANTITY=%u,\
|
||||
LAST_CUT_PLAYED=%u,\
|
||||
PLAY_ORDER=%u,\
|
||||
VALIDITY=%u,\
|
||||
ENFORCE_LENGTH=\"%s\",\
|
||||
PRESERVE_PITCH=\"%s\",\
|
||||
ASYNCRONOUS=\"%s\",\
|
||||
OWNER=%s,\
|
||||
MACROS=\"%s\",\
|
||||
SCHED_CODES=\"%s\"",
|
||||
q->value(0).toUInt(),
|
||||
q->value(1).toUInt(),
|
||||
(const char *)RDEscapeString(group),
|
||||
(const char *)RDEscapeString(q->value(3).toString()),
|
||||
(const char *)RDEscapeString(q->value(4).toString()),
|
||||
(const char *)RDEscapeString(q->value(5).toString()),
|
||||
(const char *)q->value(6).toDate().
|
||||
toString("yyyy-MM-dd"),
|
||||
(const char *)RDEscapeString(q->value(7).toString()),
|
||||
(const char *)RDEscapeString(q->value(8).toString()),
|
||||
(const char *)RDEscapeString(q->value(9).toString()),
|
||||
(const char *)RDEscapeString(q->value(10).toString()),
|
||||
(const char *)RDEscapeString(q->value(11).toString()),
|
||||
(const char *)RDEscapeString(q->value(12).toString()),
|
||||
(const char *)RDEscapeString(q->value(13).toString()),
|
||||
(const char *)RDEscapeString(q->value(14).toString()),
|
||||
q->value(15).toUInt(),
|
||||
q->value(16).toUInt(),
|
||||
q->value(17).toUInt(),
|
||||
q->value(18).toUInt(),
|
||||
q->value(19).toUInt(),
|
||||
q->value(20).toUInt(),
|
||||
q->value(21).toUInt(),
|
||||
q->value(22).toUInt(),
|
||||
q->value(23).toUInt(),
|
||||
(const char *)RDEscapeString(q->value(24).toString()),
|
||||
(const char *)RDEscapeString(q->value(25).toString()),
|
||||
(const char *)RDEscapeString(q->value(26).toString()),
|
||||
(const char *)owner,
|
||||
(const char *)RDEscapeString(q->value(28).toString()),
|
||||
(const char *)RDEscapeString(q->value(29).
|
||||
toString()));
|
||||
q1=new QSqlQuery(sql,filter_db);
|
||||
delete q1;
|
||||
sql=QString().sprintf("select CUT_NAME,EVERGREEN,DESCRIPTION,OUTCUE,ISRC,\
|
||||
LENGTH,ORIGIN_DATETIME,START_DATETIME,END_DATETIME,\
|
||||
SUN,MON,TUE,WED,THU,FRI,SAT,START_DAYPART,\
|
||||
END_DAYPART,ORIGIN_NAME,WEIGHT,VALIDITY,\
|
||||
CODING_FORMAT,SAMPLE_RATE,BIT_RATE,CHANNELS,\
|
||||
PLAY_GAIN,START_POINT,END_POINT,FADEUP_POINT,\
|
||||
FADEDOWN_POINT,SEGUE_START_POINT,SEGUE_END_POINT,\
|
||||
SEGUE_GAIN,HOOK_START_POINT,HOOK_END_POINT,\
|
||||
TALK_START_POINT,TALK_END_POINT from CUTS \
|
||||
where CART_NUMBER=%u",q->value(0).toUInt());
|
||||
q1=new QSqlQuery(sql,ext_db);
|
||||
while(q1->next()) {
|
||||
if(q1->value(7).isNull()) {
|
||||
start_datetime="null";
|
||||
}
|
||||
else {
|
||||
start_datetime=QString().sprintf("\"%s\"",
|
||||
(const char *)q1->value(7).
|
||||
toDateTime().toString("yyyy-MM-dd hh:mm:ss"));
|
||||
}
|
||||
if(q1->value(8).isNull()) {
|
||||
end_datetime="null";
|
||||
}
|
||||
else {
|
||||
end_datetime=QString().sprintf("\"%s\"",
|
||||
(const char *)q1->value(8).
|
||||
toDateTime().toString("yyyy-MM-dd hh:mm:ss"));
|
||||
}
|
||||
if(q1->value(16).isNull()) {
|
||||
start_daypart="null";
|
||||
}
|
||||
else {
|
||||
start_daypart=QString().sprintf("\"%s\"",
|
||||
(const char *)q1->value(16).
|
||||
toTime().toString("hh:mm:ss"));
|
||||
}
|
||||
if(q1->value(17).isNull()) {
|
||||
end_daypart="null";
|
||||
}
|
||||
else {
|
||||
end_daypart=QString().sprintf("\"%s\"",
|
||||
(const char *)q1->value(17).
|
||||
toTime().toString("hh:mm:ss"));
|
||||
}
|
||||
sql=QString().sprintf("insert into CUTS set CART_NUMBER=%u,\
|
||||
CUT_NAME=\"%s\",\
|
||||
EVERGREEN=\"%s\",\
|
||||
DESCRIPTION=\"%s\",\
|
||||
OUTCUE=\"%s\",\
|
||||
ISRC=\"%s\",\
|
||||
LENGTH=%u,\
|
||||
ORIGIN_DATETIME=\"%s\",\
|
||||
START_DATETIME=%s,\
|
||||
END_DATETIME=%s,\
|
||||
SUN=\"%s\",\
|
||||
MON=\"%s\",\
|
||||
TUE=\"%s\",\
|
||||
WED=\"%s\",\
|
||||
THU=\"%s\",\
|
||||
FRI=\"%s\",\
|
||||
SAT=\"%s\",\
|
||||
START_DAYPART=%s,\
|
||||
END_DAYPART=%s,\
|
||||
ORIGIN_NAME=\"%s\",\
|
||||
WEIGHT=%u,\
|
||||
VALIDITY=%u,\
|
||||
CODING_FORMAT=%u,\
|
||||
SAMPLE_RATE=%u,\
|
||||
BIT_RATE=%u,\
|
||||
CHANNELS=%u,\
|
||||
PLAY_GAIN=%d,\
|
||||
START_POINT=%d,\
|
||||
END_POINT=%d,\
|
||||
FADEUP_POINT=%d,\
|
||||
FADEDOWN_POINT=%d,\
|
||||
SEGUE_START_POINT=%d,\
|
||||
SEGUE_END_POINT=%d,\
|
||||
SEGUE_GAIN=%d,\
|
||||
HOOK_START_POINT=%d,\
|
||||
HOOK_END_POINT=%d,\
|
||||
TALK_START_POINT=%d,\
|
||||
TALK_END_POINT=%d",
|
||||
q->value(0).toUInt(),
|
||||
(const char *)RDEscapeString(q1->value(0).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(1).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(2).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(3).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(4).
|
||||
toString()),
|
||||
q1->value(5).toUInt(),
|
||||
(const char *)RDEscapeString(q1->value(6).
|
||||
toString()),
|
||||
(const char *)start_datetime,
|
||||
(const char *)end_datetime,
|
||||
(const char *)RDEscapeString(q1->value(9).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(10).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(11).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(12).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(13).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(14).
|
||||
toString()),
|
||||
(const char *)RDEscapeString(q1->value(15).
|
||||
toString()),
|
||||
(const char *)start_daypart,
|
||||
(const char *)end_daypart,
|
||||
(const char *)RDEscapeString(q1->value(18).
|
||||
toString()),
|
||||
q1->value(19).toUInt(),
|
||||
q1->value(20).toUInt(),
|
||||
q1->value(21).toUInt(),
|
||||
q1->value(22).toUInt(),
|
||||
q1->value(23).toUInt(),
|
||||
q1->value(24).toUInt(),
|
||||
q1->value(25).toInt(),
|
||||
q1->value(26).toInt(),
|
||||
q1->value(27).toInt(),
|
||||
q1->value(28).toInt(),
|
||||
q1->value(29).toInt(),
|
||||
q1->value(30).toInt(),
|
||||
q1->value(31).toInt(),
|
||||
q1->value(32).toInt(),
|
||||
q1->value(33).toInt(),
|
||||
q1->value(34).toInt(),
|
||||
q1->value(35).toInt(),
|
||||
q1->value(36).toInt());
|
||||
q2=new QSqlQuery(sql,filter_db);
|
||||
delete q2;
|
||||
ok=RDCopy(QString().sprintf("%s%s.%s",(const char *)ext_audiodir,
|
||||
(const char *)q1->value(0).toString(),
|
||||
RD_AUDIO_EXTENSION),
|
||||
RDCut::pathName(q1->value(0).toString()));
|
||||
if(!ok) {
|
||||
printf("[WARNING -- NO AUDIO FOUND]...");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
delete q1;
|
||||
printf("done.\n");
|
||||
}
|
||||
delete q;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
43
importers/rivendell_filter.h
Normal file
43
importers/rivendell_filter.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// rivendell_filter.h
|
||||
//
|
||||
// A Library import filter for an external Rivendell system
|
||||
//
|
||||
// (C) Copyright 2002-2005, 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: rivendell_filter.h,v 1.3 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 RIVENDELL_FILTER_H
|
||||
#define RIVENDELL_FILTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
|
||||
#define RIVENDELL_FILTER_USAGE " -h <hostname> -u <username> -p <password> -A <audio-dir> -g <default-group> -s <start-cartnum> -e <end-cartnum>"
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
};
|
||||
|
||||
|
||||
#endif // RIVENDELL_FILTER_H
|
283
importers/sas_filter.cpp
Normal file
283
importers/sas_filter.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
// sas_filter.cpp
|
||||
//
|
||||
// An RDCatch event import filter for the SAS64000
|
||||
//
|
||||
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: sas_filter.cpp,v 1.11 2011/06/21 22:20:43 cvs Exp $
|
||||
// $Date: 2011/06/21 22:20:43 $
|
||||
//
|
||||
// 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <rddb.h>
|
||||
#include <rd.h>
|
||||
#include <rdcmd_switch.h>
|
||||
#include <dbversion.h>
|
||||
|
||||
#include <sas_filter.h>
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
bool skip_db_check=false;
|
||||
unsigned schema=0;
|
||||
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"sas_filter",SAS_FILTER_USAGE);
|
||||
for(unsigned i=0;i<cmd->keys();i++) {
|
||||
if(cmd->key(i)=="--skip-db-check") {
|
||||
skip_db_check=true;
|
||||
}
|
||||
}
|
||||
delete cmd;
|
||||
|
||||
rd_config=new RDConfig(RD_CONF_FILE);
|
||||
rd_config->load();
|
||||
filter_switch_count=0;
|
||||
filter_macro_count=0;
|
||||
|
||||
//
|
||||
// Open Database
|
||||
//
|
||||
QString err(tr("sas_filter: "));
|
||||
filter_db=RDInitDb(&schema,&err);
|
||||
if(!filter_db) {
|
||||
fprintf(stderr,"%s\n",err.ascii());
|
||||
exit(1);
|
||||
}
|
||||
if((schema!=RD_VERSION_DATABASE)&&(!skip_db_check)) {
|
||||
fprintf(stderr,
|
||||
"sas_filter: database version mismatch, should be %u, is %u\n",
|
||||
RD_VERSION_DATABASE,schema);
|
||||
exit(256);
|
||||
}
|
||||
|
||||
//
|
||||
// RIPCD Connection
|
||||
//
|
||||
filter_ripc=new RDRipc("");
|
||||
filter_ripc->connectHost("localhost",RIPCD_TCP_PORT,rd_config->password());
|
||||
|
||||
//
|
||||
// Station Configuration
|
||||
//
|
||||
filter_rdstation=new RDStation(rd_config->stationName());
|
||||
|
||||
//
|
||||
// RDCatchd Connection
|
||||
//
|
||||
filter_connect=new RDCatchConnect(0,this,"filter_connect");
|
||||
filter_connect->connectHost("localhost",RDCATCHD_TCP_PORT,
|
||||
rd_config->password());
|
||||
|
||||
//
|
||||
// Read Switches
|
||||
//
|
||||
if((qApp->argc()==2)&&(!strcmp(qApp->argv()[1],"-d"))) { // Delete List
|
||||
DeleteList();
|
||||
filter_connect->reset();
|
||||
exit(0);
|
||||
}
|
||||
if((qApp->argc()==3)&&(!strcmp(qApp->argv()[1],"-i"))) { // Insert List
|
||||
InsertList();
|
||||
filter_connect->reset();
|
||||
exit(0);
|
||||
}
|
||||
fprintf(stderr,"\nsas_filter %s\n",SAS_FILTER_USAGE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void MainObject::InsertList()
|
||||
{
|
||||
char line[256];
|
||||
int count=0;
|
||||
|
||||
FILE *fh=fopen(qApp->argv()[2],"r");
|
||||
if(fh==NULL) {
|
||||
perror("sas_filter");
|
||||
exit(1);
|
||||
}
|
||||
printf("Importing events from %s...",qApp->argv()[2]);
|
||||
fflush(0);
|
||||
while(fgets(line,256,fh)!=NULL) {
|
||||
if(strlen(line)==79) {
|
||||
InjectLine(line);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
printf("done.\n");
|
||||
fclose(fh);
|
||||
printf("Imported %d switch events, %d macro events, %d total.\n",
|
||||
filter_switch_count,filter_macro_count,
|
||||
filter_switch_count+filter_macro_count);
|
||||
}
|
||||
|
||||
|
||||
void MainObject::DeleteList()
|
||||
{
|
||||
QString sql="delete from RECORDINGS";
|
||||
RDSqlQuery *q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
filter_connect->reset();
|
||||
printf("RDCatch events list deleted!\n");
|
||||
}
|
||||
|
||||
|
||||
void MainObject::InjectLine(char *line)
|
||||
{
|
||||
QString temp;
|
||||
int input=0;
|
||||
int output=0;
|
||||
int gpo=0;
|
||||
|
||||
//
|
||||
// Initialize the SQL clause
|
||||
//
|
||||
QString base_sql=QString().sprintf("insert into RECORDINGS set\
|
||||
STATION_NAME=\"%s\",CHANNEL=%d,",
|
||||
(const char *)rd_config->sasStation(),
|
||||
rd_config->sasMatrix());
|
||||
|
||||
//
|
||||
// Day of the week fields
|
||||
//
|
||||
if(line[0]=='X') {
|
||||
base_sql+="MON=\"Y\",";
|
||||
}
|
||||
if(line[1]=='X') {
|
||||
base_sql+="TUE=\"Y\",";
|
||||
}
|
||||
if(line[2]=='X') {
|
||||
base_sql+="WED=\"Y\",";
|
||||
}
|
||||
if(line[3]=='X') {
|
||||
base_sql+="THU=\"Y\",";
|
||||
}
|
||||
if(line[4]=='X') {
|
||||
base_sql+="FRI=\"Y\",";
|
||||
}
|
||||
if(line[5]=='X') {
|
||||
base_sql+="SAT=\"Y\",";
|
||||
}
|
||||
if(line[6]=='X') {
|
||||
base_sql+="SUN=\"Y\",";
|
||||
}
|
||||
|
||||
//
|
||||
// Time
|
||||
//
|
||||
line[17]=0;
|
||||
base_sql+=QString().sprintf("START_TIME=\"%s\",",line+9);
|
||||
|
||||
//
|
||||
// Title
|
||||
//
|
||||
line[60]=0;
|
||||
temp=QString(line+19).stripWhiteSpace();
|
||||
base_sql+=QString().sprintf("DESCRIPTION=\"%s\",",(const char *)temp);
|
||||
|
||||
//
|
||||
// Active Flag
|
||||
//
|
||||
if(line[77]=='I') {
|
||||
base_sql+="IS_ACTIVE=\"N\",";
|
||||
}
|
||||
|
||||
//
|
||||
// Output
|
||||
//
|
||||
line[65]=0;
|
||||
sscanf(line+62,"%d",&output);
|
||||
|
||||
//
|
||||
// Input
|
||||
//
|
||||
line[70]=0;
|
||||
sscanf(line+67,"%d",&input);
|
||||
|
||||
//
|
||||
// GPO
|
||||
//
|
||||
line[75]=0;
|
||||
sscanf(line+73,"%d",&gpo);
|
||||
|
||||
if((input>0)&&(output>0)) {
|
||||
InjectSwitchEvent(base_sql,input,output);
|
||||
}
|
||||
if(gpo>0) {
|
||||
InjectCartEvent(base_sql,gpo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainObject::InjectSwitchEvent(QString sql,int input,int output)
|
||||
{
|
||||
//
|
||||
// Event Type
|
||||
//
|
||||
sql+="TYPE=2,";
|
||||
|
||||
//
|
||||
// Input and Output
|
||||
//
|
||||
sql+=QString().sprintf("SWITCH_INPUT=%d,SWITCH_OUTPUT=%d",input,output);
|
||||
RDSqlQuery *q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
filter_switch_count++;
|
||||
}
|
||||
|
||||
|
||||
void MainObject::InjectCartEvent(QString sql,int gpo)
|
||||
{
|
||||
//
|
||||
// Event Type
|
||||
//
|
||||
sql+="TYPE=1,";
|
||||
|
||||
//
|
||||
// Macro Cart
|
||||
//
|
||||
sql+=QString().sprintf("MACRO_CART=%d",gpo+rd_config->sasBaseCart());
|
||||
filter_macro_count++;
|
||||
RDSqlQuery *q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
// printf("SQL: %s\n",(const char *)sql);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
61
importers/sas_filter.h
Normal file
61
importers/sas_filter.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// sas_filter.h
|
||||
//
|
||||
// An RDCatch event import filter for the SAS64000
|
||||
//
|
||||
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: sas_filter.h,v 1.7 2010/07/29 19:32:32 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:32 $
|
||||
//
|
||||
// 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 SAS_FILTER_H
|
||||
#define SAS_FILTER_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
|
||||
#include <rdstation.h>
|
||||
#include <rdripc.h>
|
||||
#include <rdcatch_connect.h>
|
||||
#include <rdstation.h>
|
||||
#include <rdconfig.h>
|
||||
|
||||
#define SAS_FILTER_USAGE "-d|-i <insert-list>\n"
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
|
||||
private:
|
||||
void InsertList();
|
||||
void DeleteList();
|
||||
void InjectLine(char *line);
|
||||
void InjectSwitchEvent(QString sql,int input,int output);
|
||||
void InjectCartEvent(QString sql,int gpo);
|
||||
RDStation *filter_rdstation;
|
||||
RDRipc *filter_ripc;
|
||||
RDCatchConnect *filter_connect;
|
||||
QSqlDatabase *filter_db;
|
||||
int filter_switch_count;
|
||||
int filter_macro_count;
|
||||
RDConfig *rd_config;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
329
importers/wings_filter.cpp
Normal file
329
importers/wings_filter.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
// wings_filter.cpp
|
||||
//
|
||||
// A Library import filter for the Airforce Wings system
|
||||
//
|
||||
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: wings_filter.cpp,v 1.13 2010/07/29 19:32:33 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:33 $
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
|
||||
#include <rddb.h>
|
||||
#include <rd.h>
|
||||
#include <rdconfig.h>
|
||||
#include <rdcmd_switch.h>
|
||||
#include <rdcut.h>
|
||||
#include <wings_filter.h>
|
||||
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
RDConfig *rdconfig;
|
||||
|
||||
|
||||
MainObject::MainObject(QObject *parent,const char *name)
|
||||
: QObject(parent,name)
|
||||
{
|
||||
//
|
||||
// Read Command Options
|
||||
//
|
||||
RDCmdSwitch *cmd=
|
||||
new RDCmdSwitch(qApp->argc(),qApp->argv(),"wings_filter",
|
||||
WINGS_FILTER_USAGE);
|
||||
delete cmd;
|
||||
|
||||
WingsRecord wr;
|
||||
QString audioname;
|
||||
bool found;
|
||||
QString dbname;
|
||||
QString audiodir;
|
||||
QString audio_extension=WINGS_DEFAULT_AUDIO_EXT;
|
||||
QString groupname;
|
||||
RDWaveFile *wavefile=NULL;
|
||||
|
||||
rdconfig=new RDConfig(RD_CONF_FILE);
|
||||
rdconfig->load();
|
||||
|
||||
//
|
||||
// Open Database
|
||||
//
|
||||
|
||||
|
||||
filter_db=QSqlDatabase::addDatabase(rdconfig->mysqlDriver());
|
||||
if(!filter_db) {
|
||||
fprintf(stderr,"wings_filter: can't open mySQL database\n");
|
||||
exit(1);
|
||||
}
|
||||
filter_db->setDatabaseName(rdconfig->mysqlDbname());
|
||||
filter_db->setUserName(rdconfig->mysqlUsername());
|
||||
filter_db->setPassword(rdconfig->mysqlPassword());
|
||||
filter_db->setHostName(rdconfig->mysqlHostname());
|
||||
if(!filter_db->open()) {
|
||||
fprintf(stderr,"wings_filter: unable to connect to mySQL Server\n");
|
||||
filter_db->removeDatabase(rdconfig->mysqlDbname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
// RIPCD Connection
|
||||
//
|
||||
filter_ripc=new RDRipc("");
|
||||
filter_ripc->connectHost("localhost",RIPCD_TCP_PORT,rdconfig->password());
|
||||
|
||||
//
|
||||
// Station Configuration
|
||||
//
|
||||
filter_rdstation=new RDStation(rdconfig->stationName());
|
||||
|
||||
//
|
||||
// Read Arguments
|
||||
//
|
||||
for(int i=1;i<(qApp->argc()-1);i+=2) {
|
||||
found=false;
|
||||
if(!strcmp("-d",qApp->argv()[i])) {
|
||||
dbname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-A",qApp->argv()[i])) {
|
||||
audiodir=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-g",qApp->argv()[i])) {
|
||||
groupname=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!strcmp("-e",qApp->argv()[i])) {
|
||||
audio_extension=qApp->argv()[i+1];
|
||||
found=true;
|
||||
}
|
||||
if(!found) {
|
||||
fprintf(stderr,"\nwings_filter %s\n",WINGS_FILTER_USAGE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
FILE *file=fopen((const char *)dbname,"r");
|
||||
if(file==NULL) {
|
||||
perror("wings_filter");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
RDGroup *default_group=new RDGroup(groupname);
|
||||
if(!default_group->exists()) {
|
||||
fprintf(stderr,"wings_filter: no such default group\n");
|
||||
delete default_group;
|
||||
exit(256);
|
||||
}
|
||||
while(ReadLine(file,&wr)) {
|
||||
strcpy(wr.extension,audio_extension);
|
||||
audioname=QString().sprintf("%s/%s.%s",(const char *)audiodir,
|
||||
wr.filename,(const char *)audio_extension);
|
||||
wavefile=new RDWaveFile(audioname);
|
||||
if(!wavefile->openWave()) {
|
||||
fprintf(stderr,"Unable to open %s, skipping...\n",
|
||||
(const char *)audioname);
|
||||
}
|
||||
else {
|
||||
if(wavefile->type()!=RDWaveFile::Atx) {
|
||||
fprintf(stderr,"ATX header in %s appears corrupt, skipping...\n",
|
||||
(const char *)audioname);
|
||||
}
|
||||
else {
|
||||
RDGroup *group=new RDGroup(wr.group);
|
||||
if(group->exists()) {
|
||||
ImportCut(group,&wr,wavefile);
|
||||
}
|
||||
else {
|
||||
ImportCut(default_group,&wr,wavefile);
|
||||
}
|
||||
delete group;
|
||||
}
|
||||
wavefile->closeWave();
|
||||
}
|
||||
delete wavefile;
|
||||
}
|
||||
|
||||
delete default_group;
|
||||
fclose(file);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
bool MainObject::ImportCut(RDGroup *group,struct WingsRecord *rec,
|
||||
RDWaveFile *wavefile)
|
||||
{
|
||||
unsigned cartnum=0;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
int format=0;
|
||||
RDWaveFile *destfile;
|
||||
int n;
|
||||
char buffer[WINGS_XFER_BUFFER_SIZE];
|
||||
|
||||
if((cartnum=group->nextFreeCart())==0) {
|
||||
fprintf(stderr,"No more available carts in group %s, skipping %s...\n",
|
||||
rec->group,rec->filename);
|
||||
delete group;
|
||||
return false;
|
||||
}
|
||||
destfile=new RDWaveFile(RDCut::pathName(QString().sprintf
|
||||
("%06u_001",cartnum)));
|
||||
switch(wavefile->getFormatTag()) {
|
||||
case WAVE_FORMAT_PCM:
|
||||
format=0;
|
||||
destfile->setBextChunk(true);
|
||||
destfile->setFormatTag(WAVE_FORMAT_PCM);
|
||||
break;
|
||||
|
||||
case WAVE_FORMAT_MPEG:
|
||||
if(wavefile->getHeadLayer()==2) {
|
||||
format=1;
|
||||
destfile->setFormatTag(WAVE_FORMAT_MPEG);
|
||||
destfile->setHeadLayer(2);
|
||||
destfile->setHeadBitRate(wavefile->getHeadBitRate());
|
||||
destfile->setHeadMode(wavefile->getHeadMode());
|
||||
destfile->setMextChunk(true);
|
||||
destfile->setMextHomogenous(true);
|
||||
destfile->setMextAncillaryLength(3);
|
||||
destfile->setMextLeftEnergyPresent(true);
|
||||
if(wavefile->getChannels()>1) {
|
||||
destfile->setMextRightEnergyPresent(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
destfile->setSamplesPerSec(wavefile->getSamplesPerSec());
|
||||
destfile->setBitsPerSample(wavefile->getBitsPerSample());
|
||||
destfile->setChannels(wavefile->getChannels());
|
||||
destfile->setBextChunk(true);
|
||||
destfile->setBextDescription(rec->title);
|
||||
if(!destfile->createWave()) {
|
||||
fprintf(stderr,"wings_filter: unable to write to audio directory\n");
|
||||
exit(256);
|
||||
}
|
||||
while((n=wavefile->readWave(buffer,WINGS_XFER_BUFFER_SIZE))>0) {
|
||||
destfile->writeWave(buffer,n);
|
||||
}
|
||||
destfile->closeWave();
|
||||
|
||||
printf("Importing %s - %s to cart %u, group %s\n",
|
||||
rec->filename,rec->title,cartnum,(const char *)group->name());
|
||||
|
||||
sql=QString().sprintf("insert into CART set NUMBER=%u,GROUP_NAME=\"%s\",\
|
||||
TITLE=\"%s\",ARTIST=\"%s\",ALBUM=\"%s\",\
|
||||
CUT_QUANTITY=1,TYPE=%d,FORCED_LENGTH=%u,\
|
||||
AVERAGE_LENGTH=%u,USER_DEFINED=\"%s.%s\"",
|
||||
cartnum,(const char *)group->name(),
|
||||
rec->title,rec->artist,rec->album,
|
||||
RDCart::Audio,wavefile->getExtTimeLength(),
|
||||
wavefile->getExtTimeLength(),
|
||||
rec->filename,rec->extension);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
sql=QString().sprintf("insert into CUTS set CUT_NAME=\"%06u_001\",\
|
||||
CART_NUMBER=%u,DESCRIPTION=\"%s\",\
|
||||
ORIGIN_DATETIME=\"%s\",ORIGIN_NAME=\"%s\",\
|
||||
CODING_FORMAT=%d,SAMPLE_RATE=%u,CHANNELS=%d,\
|
||||
BIT_RATE=%d,LENGTH=%u,START_POINT=0,\
|
||||
END_POINT=%d",
|
||||
cartnum,cartnum,(const char *)rec->title,
|
||||
(const char *)QDateTime::currentDateTime().
|
||||
toString("yyyy-MM-dd hh:mm:ss"),
|
||||
(const char *)rdconfig->stationName(),format,
|
||||
wavefile->getSamplesPerSec(),
|
||||
wavefile->getChannels(),wavefile->getHeadBitRate(),
|
||||
wavefile->getExtTimeLength(),
|
||||
wavefile->getExtTimeLength());
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MainObject::ReadLine(FILE *fp,struct WingsRecord *rec)
|
||||
{
|
||||
char buffer[WINGS_RECORD_LENGTH+1];
|
||||
|
||||
memset(rec,0,sizeof(struct WingsRecord));
|
||||
if(fgets(buffer,WINGS_RECORD_LENGTH+1,fp)==NULL) {
|
||||
return false;
|
||||
}
|
||||
if(strlen(buffer)<WINGS_RECORD_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
buffer[8]=0; // Fielname
|
||||
strcpy(rec->filename,buffer);
|
||||
TrimSpaces(rec->filename);
|
||||
|
||||
rec->group[0]=buffer[9]; // Group
|
||||
rec->group[1]=0;
|
||||
|
||||
buffer[17]=0; // Length
|
||||
sscanf(buffer+14,"%d",&rec->length);
|
||||
rec->length*=1000;
|
||||
|
||||
buffer[47]=0; // Title
|
||||
strcpy(rec->title,buffer+24);
|
||||
TrimSpaces(rec->title);
|
||||
|
||||
buffer[77]=0; // Artist
|
||||
strcpy(rec->artist,buffer+55);
|
||||
TrimSpaces(rec->artist);
|
||||
|
||||
buffer[105]=0;
|
||||
strcpy(rec->album,buffer+78);
|
||||
TrimSpaces(rec->album);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MainObject::TrimSpaces(char *str)
|
||||
{
|
||||
for(int i=strlen(str)-1;i>=0;i--) {
|
||||
if(isspace(str[i])) {
|
||||
str[i]=0;
|
||||
}
|
||||
else {
|
||||
i=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
QApplication a(argc,argv,false);
|
||||
new MainObject(NULL,"main");
|
||||
return a.exec();
|
||||
}
|
71
importers/wings_filter.h
Normal file
71
importers/wings_filter.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// wings_filter.h
|
||||
//
|
||||
// A Library import filter for the Crown Wings system
|
||||
//
|
||||
// (C) Copyright 2002-2005 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// $Id: wings_filter.h,v 1.9 2010/07/29 19:32:33 cvs Exp $
|
||||
// $Date: 2010/07/29 19:32:33 $
|
||||
//
|
||||
// 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 WINGS_FILTER_H
|
||||
#define WINGS_FILTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qapplication.h>
|
||||
#include <qsqldatabase.h>
|
||||
|
||||
#include <rdwavefile.h>
|
||||
#include <rdstation.h>
|
||||
#include <rdripc.h>
|
||||
#include <rdcatch_connect.h>
|
||||
#include <rdcae.h>
|
||||
#include <rdgroup.h>
|
||||
|
||||
#define WINGS_RECORD_LENGTH 613
|
||||
#define WINGS_FILTER_USAGE "-g <default-group> -d <db-file> -A <audio-dir> [-e <audio-ext>]\n"
|
||||
#define WINGS_DEFAULT_AUDIO_EXT "ATX"
|
||||
#define WINGS_XFER_BUFFER_SIZE 4096
|
||||
|
||||
struct WingsRecord {
|
||||
char filename[9];
|
||||
char extension[4];
|
||||
char title[32];
|
||||
char artist[32];
|
||||
char album[32];
|
||||
char group[2];
|
||||
unsigned length;
|
||||
};
|
||||
|
||||
class MainObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainObject(QObject *parent=0,const char *name=0);
|
||||
|
||||
private:
|
||||
bool ImportCut(RDGroup *group,struct WingsRecord *rec,RDWaveFile *wavefile);
|
||||
bool ReadLine(FILE *fp,struct WingsRecord *rec);
|
||||
void TrimSpaces(char *str);
|
||||
RDStation *filter_rdstation;
|
||||
RDRipc *filter_ripc;
|
||||
QSqlDatabase *filter_db;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user