2017-06-19 Fred Gleason <fredg@paravelsystems.com>

* Added a 'SYSTEM.FIX_DUP_CART_TITLES' field to the database.
	* Incremented the database version to 264.
	* Added 'RDSystem::fixDuplicateCartTitles()' and
	'RDSystem::setFixDuplicateCartTitles()' methods in 'lib/rdsystem.cpp'
	and 'lib/rdsystem.h'.
	* Added an 'Auto-Correct Duplicate Cart Titles' checkbox to the
	'System Settings' dialog in 'rdadmin/edit_settings.cpp' and
	'rdadmin/edit_settings.h'.
	* Modified the 'EditCart' web call to enforce the 'Auto-Correct
	Duplicate Cart Titles' setting.
This commit is contained in:
Fred Gleason 2017-06-19 13:16:33 -04:00
parent 78fabe827d
commit 108fd8c40c
20 changed files with 160 additions and 14 deletions

View File

@ -15838,3 +15838,14 @@
2017-06-15 Fred Gleason <fredg@paravelsystems.com> 2017-06-15 Fred Gleason <fredg@paravelsystems.com>
* Added code so that the --enable-rdxport-debug' switch to 'configure' * Added code so that the --enable-rdxport-debug' switch to 'configure'
is carried through to the 'make rpm' target. is carried through to the 'make rpm' target.
2017-06-19 Fred Gleason <fredg@paravelsystems.com>
* Added a 'SYSTEM.FIX_DUP_CART_TITLES' field to the database.
* Incremented the database version to 264.
* Added 'RDSystem::fixDuplicateCartTitles()' and
'RDSystem::setFixDuplicateCartTitles()' methods in 'lib/rdsystem.cpp'
and 'lib/rdsystem.h'.
* Added an 'Auto-Correct Duplicate Cart Titles' checkbox to the
'System Settings' dialog in 'rdadmin/edit_settings.cpp' and
'rdadmin/edit_settings.h'.
* Modified the 'EditCart' web call to enforce the 'Auto-Correct
Duplicate Cart Titles' setting.

View File

@ -70,6 +70,7 @@ EXTRA_DIST = audio_perms.txt\
sources.txt\ sources.txt\
stations.txt\ stations.txt\
svc_rec_format.txt\ svc_rec_format.txt\
system.txt\
triggers.txt\ triggers.txt\
ttys.txt\ ttys.txt\
user_perms.txt\ user_perms.txt\

13
docs/tables/system.txt Normal file
View File

@ -0,0 +1,13 @@
SYSTEM Table Layout for Rivendell
The STATIONS table contains system-wide settings.
FIELD NAME TYPE REMARKS
---------------------------------------------------------------
ID int(11) Auto increment, primary key
SAMPLE_RATE int(10) unsigned
DUP_CART_TITLE enum('N','Y')
FIX_DUP_CART_TITLES enum('N','Y')
MAX_POST_LENGTH int(10) unsigned
ISCI_XREFERENCE_PATH char(255)
TEMP_CART_GROUP char(10) From 'GROUPS.NAME'

View File

@ -24,7 +24,7 @@
/* /*
* Current Database Version * Current Database Version
*/ */
#define RD_VERSION_DATABASE 263 #define RD_VERSION_DATABASE 264
#endif // DBVERSION_H #endif // DBVERSION_H

View File

@ -2011,6 +2011,20 @@ QString RDCart::uniqueCartTitle(unsigned cartnum)
} }
bool RDCart::titleIsUnique(const QString &str)
{
bool ret=false;
QString sql=QString("select NUMBER from CART where ")+
"TITLE=\""+RDEscapeString(str)+"\"";
RDSqlQuery *q=new RDSqlQuery(sql);
ret=!q->first();
delete q;
return ret;
}
QVariant RDCart::GetXmlValue(const QString &tag,const QString &line) QVariant RDCart::GetXmlValue(const QString &tag,const QString &line)
{ {
bool ok=false; bool ok=false;

View File

@ -167,6 +167,7 @@ class RDCart
static void removePending(RDStation *station,RDUser *user,RDConfig *config); static void removePending(RDStation *station,RDUser *user,RDConfig *config);
static unsigned readXml(std::vector<RDWaveData> *data,const QString &xml); static unsigned readXml(std::vector<RDWaveData> *data,const QString &xml);
static QString uniqueCartTitle(unsigned cartnum=0); static QString uniqueCartTitle(unsigned cartnum=0);
static bool titleIsUnique(const QString &str);
private: private:
static QVariant GetXmlValue(const QString &tag,const QString &line); static QVariant GetXmlValue(const QString &tag,const QString &line);

View File

@ -69,6 +69,34 @@ void RDSystem::setAllowDuplicateCartTitles(bool state) const
} }
bool RDSystem::fixDuplicateCartTitles() const
{
bool ret=false;
QString sql;
RDSqlQuery *q;
sql="select FIX_DUP_CART_TITLES from SYSTEM";
q=new RDSqlQuery(sql);
if(q->first()) {
ret=RDBool(q->value(0).toString());
}
delete q;
return ret;
}
void RDSystem::setFixDuplicateCartTitles(bool state) const
{
QString sql;
RDSqlQuery *q;
sql=QString().sprintf("update SYSTEM set FIX_DUP_CART_TITLES=\"%s\"",
(const char *)RDYesNo(state));
q=new RDSqlQuery(sql);
delete q;
}
unsigned RDSystem::maxPostLength() const unsigned RDSystem::maxPostLength() const
{ {
unsigned ret; unsigned ret;
@ -123,6 +151,7 @@ QString RDSystem::xml() const
QString xml="<systemSettings>\n"; QString xml="<systemSettings>\n";
xml+=RDXmlField("sampleRate",sampleRate()); xml+=RDXmlField("sampleRate",sampleRate());
xml+=RDXmlField("duplicateTitles",allowDuplicateCartTitles()); xml+=RDXmlField("duplicateTitles",allowDuplicateCartTitles());
xml+=RDXmlField("fixDuplicateTitles",fixDuplicateCartTitles());
xml+=RDXmlField("maxPostLength",maxPostLength()); xml+=RDXmlField("maxPostLength",maxPostLength());
xml+=RDXmlField("isciXreferencePath",isciXreferencePath()); xml+=RDXmlField("isciXreferencePath",isciXreferencePath());
xml+=RDXmlField("tempCartGroup",tempCartGroup()); xml+=RDXmlField("tempCartGroup",tempCartGroup());

View File

@ -31,6 +31,8 @@ class RDSystem
void setSampleRate(unsigned rate) const; void setSampleRate(unsigned rate) const;
bool allowDuplicateCartTitles() const; bool allowDuplicateCartTitles() const;
void setAllowDuplicateCartTitles(bool state) const; void setAllowDuplicateCartTitles(bool state) const;
bool fixDuplicateCartTitles() const;
void setFixDuplicateCartTitles(bool state) const;
unsigned maxPostLength() const; unsigned maxPostLength() const;
void setMaxPostLength(unsigned bytes) const; void setMaxPostLength(unsigned bytes) const;
QString isciXreferencePath() const; QString isciXreferencePath() const;

View File

@ -2088,6 +2088,7 @@ bool CreateDb(QString name,QString pwd)
ID int auto_increment not null primary key,\ ID int auto_increment not null primary key,\
SAMPLE_RATE int unsigned default %d,\ SAMPLE_RATE int unsigned default %d,\
DUP_CART_TITLES enum('N','Y') not null default 'Y',\ DUP_CART_TITLES enum('N','Y') not null default 'Y',\
FIX_DUP_CART_TITLES enum('N','Y') not null default 'Y',\
MAX_POST_LENGTH int unsigned default %u,\ MAX_POST_LENGTH int unsigned default %u,\
ISCI_XREFERENCE_PATH char(255),\ ISCI_XREFERENCE_PATH char(255),\
TEMP_CART_GROUP char(10))", TEMP_CART_GROUP char(10))",
@ -8404,6 +8405,13 @@ int UpdateDb(int ver)
delete q; delete q;
} }
if(ver<264) {
sql=QString("alter table SYSTEM add column ")+
"FIX_DUP_CART_TITLES enum('N','Y') not null default 'Y' after "+
"DUP_CART_TITLES";
q=new QSqlQuery(sql);
delete q;
}
// //
// Update Version Field // Update Version Field

View File

@ -90,19 +90,30 @@ EditSettings::EditSettings(QWidget *parent)
// //
edit_duplicate_carts_box=new QCheckBox(this); edit_duplicate_carts_box=new QCheckBox(this);
edit_duplicate_carts_box->setGeometry(20,32,15,15); edit_duplicate_carts_box->setGeometry(20,32,15,15);
connect(edit_duplicate_carts_box,SIGNAL(toggled(bool)),
this,SLOT(duplicatesCheckedData(bool)));
label= label=
new QLabel(edit_duplicate_carts_box,tr("Allow Duplicate Cart Titles"),this); new QLabel(edit_duplicate_carts_box,tr("Allow Duplicate Cart Titles"),this);
label->setGeometry(40,30,sizeHint().width()-50,20); label->setGeometry(40,30,sizeHint().width()-50,20);
label->setFont(font); label->setFont(font);
label->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); label->setAlignment(AlignLeft|AlignVCenter|ShowPrefix);
edit_fix_duplicate_carts_box=new QCheckBox(this);
edit_fix_duplicate_carts_box->setGeometry(30,52,15,15);
edit_fix_duplicate_carts_label=new QLabel(edit_fix_duplicate_carts_box,
tr("Auto-Correct Duplicate Cart Titles"),this);
edit_fix_duplicate_carts_label->setGeometry(50,50,sizeHint().width()-60,20);
edit_fix_duplicate_carts_label->setFont(font);
edit_fix_duplicate_carts_label->
setAlignment(AlignLeft|AlignVCenter|ShowPrefix);
// //
// ISCI Cross Reference Path // ISCI Cross Reference Path
// //
edit_isci_path_edit=new QLineEdit(this); edit_isci_path_edit=new QLineEdit(this);
edit_isci_path_edit->setGeometry(200,54,sizeHint().width()-210,20); edit_isci_path_edit->setGeometry(200,76,sizeHint().width()-210,20);
label=new QLabel(edit_isci_path_edit,tr("ISCI Cross Reference Path:"),this); label=new QLabel(edit_isci_path_edit,tr("ISCI Cross Reference Path:"),this);
label->setGeometry(10,54,185,20); label->setGeometry(10,76,185,20);
label->setFont(font); label->setFont(font);
label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); label->setAlignment(AlignRight|AlignVCenter|ShowPrefix);
@ -110,14 +121,14 @@ EditSettings::EditSettings(QWidget *parent)
// Maximum POST Size // Maximum POST Size
// //
edit_maxpost_spin=new QSpinBox(this); edit_maxpost_spin=new QSpinBox(this);
edit_maxpost_spin->setGeometry(200,76,60,20); edit_maxpost_spin->setGeometry(200,98,60,20);
edit_maxpost_spin->setRange(1,1000); edit_maxpost_spin->setRange(1,1000);
label=new QLabel(edit_maxpost_spin,tr("Maximum Remote Post Length:"),this); label=new QLabel(edit_maxpost_spin,tr("Maximum Remote Post Length:"),this);
label->setGeometry(10,76,185,20); label->setGeometry(10,98,185,20);
label->setFont(font); label->setFont(font);
label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); label->setAlignment(AlignRight|AlignVCenter|ShowPrefix);
label=new QLabel(tr("Mbytes"),this); label=new QLabel(tr("Mbytes"),this);
label->setGeometry(265,76,60,20); label->setGeometry(265,98,60,20);
label->setFont(font); label->setFont(font);
label->setAlignment(AlignLeft|AlignVCenter|ShowPrefix); label->setAlignment(AlignLeft|AlignVCenter|ShowPrefix);
@ -125,7 +136,7 @@ EditSettings::EditSettings(QWidget *parent)
// Temporary Cart Group // Temporary Cart Group
// //
edit_temp_cart_group_box=new QComboBox(this); edit_temp_cart_group_box=new QComboBox(this);
edit_temp_cart_group_box->setGeometry(200,97,100,20); edit_temp_cart_group_box->setGeometry(200,119,100,20);
sql="select NAME from GROUPS order by NAME"; sql="select NAME from GROUPS order by NAME";
q=new RDSqlQuery(sql); q=new RDSqlQuery(sql);
while(q->next()) { while(q->next()) {
@ -133,7 +144,7 @@ EditSettings::EditSettings(QWidget *parent)
} }
delete q; delete q;
label=new QLabel(edit_temp_cart_group_box,tr("Temporary Cart Group:"),this); label=new QLabel(edit_temp_cart_group_box,tr("Temporary Cart Group:"),this);
label->setGeometry(10,97,185,20); label->setGeometry(10,119,185,20);
label->setFont(font); label->setFont(font);
label->setAlignment(AlignRight|AlignVCenter|ShowPrefix); label->setAlignment(AlignRight|AlignVCenter|ShowPrefix);
@ -143,11 +154,11 @@ EditSettings::EditSettings(QWidget *parent)
edit_duplicate_label=new RDLabel(this); edit_duplicate_label=new RDLabel(this);
edit_duplicate_label->setText(tr("The following duplicate titles must be corrected before \"Allow Duplicate Values\" can be turned off.")); edit_duplicate_label->setText(tr("The following duplicate titles must be corrected before \"Allow Duplicate Values\" can be turned off."));
edit_duplicate_label->setWordWrapEnabled(true); edit_duplicate_label->setWordWrapEnabled(true);
edit_duplicate_label->setGeometry(15,120,sizeHint().width()-30,50); edit_duplicate_label->setGeometry(15,142,sizeHint().width()-30,50);
edit_duplicate_label->setFont(normal_font); edit_duplicate_label->setFont(normal_font);
edit_duplicate_label->hide(); edit_duplicate_label->hide();
edit_duplicate_list=new QListView(this); edit_duplicate_list=new QListView(this);
edit_duplicate_list->setGeometry(10,165,sizeHint().width()-20,200); edit_duplicate_list->setGeometry(10,187,sizeHint().width()-20,200);
edit_duplicate_list->setItemMargin(5); edit_duplicate_list->setItemMargin(5);
edit_duplicate_list->setAllColumnsShowFocus(true); edit_duplicate_list->setAllColumnsShowFocus(true);
edit_duplicate_list->addColumn(tr("CART")); edit_duplicate_list->addColumn(tr("CART"));
@ -157,7 +168,7 @@ EditSettings::EditSettings(QWidget *parent)
edit_duplicate_list->hide(); edit_duplicate_list->hide();
edit_save_button=new QPushButton(this); edit_save_button=new QPushButton(this);
edit_save_button-> edit_save_button->
setGeometry(sizeHint().width()-85,370,70,25); setGeometry(sizeHint().width()-85,392,70,25);
edit_save_button->setFont(normal_font); edit_save_button->setFont(normal_font);
edit_save_button->setText(tr("&Save List")); edit_save_button->setText(tr("&Save List"));
connect(edit_save_button,SIGNAL(clicked()),this,SLOT(saveData())); connect(edit_save_button,SIGNAL(clicked()),this,SLOT(saveData()));
@ -184,6 +195,9 @@ EditSettings::EditSettings(QWidget *parent)
connect(edit_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData())); connect(edit_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData()));
edit_duplicate_carts_box->setChecked(edit_system->allowDuplicateCartTitles()); edit_duplicate_carts_box->setChecked(edit_system->allowDuplicateCartTitles());
edit_fix_duplicate_carts_box->
setChecked(edit_system->fixDuplicateCartTitles());
duplicatesCheckedData(edit_system->allowDuplicateCartTitles());
edit_maxpost_spin->setValue(edit_system->maxPostLength()/1000000); edit_maxpost_spin->setValue(edit_system->maxPostLength()/1000000);
edit_isci_path_edit->setText(edit_system->isciXreferencePath()); edit_isci_path_edit->setText(edit_system->isciXreferencePath());
@ -211,7 +225,7 @@ EditSettings::~EditSettings()
QSize EditSettings::sizeHint() const QSize EditSettings::sizeHint() const
{ {
return QSize(500,196+y_pos); return QSize(500,218+y_pos);
} }
@ -221,6 +235,13 @@ QSizePolicy EditSettings::sizePolicy() const
} }
void EditSettings::duplicatesCheckedData(bool state)
{
edit_fix_duplicate_carts_box->setDisabled(state);
edit_fix_duplicate_carts_label->setDisabled(state);
}
void EditSettings::saveData() void EditSettings::saveData()
{ {
QString filename=RDGetHomeDir(); QString filename=RDGetHomeDir();
@ -358,6 +379,8 @@ void EditSettings::okData()
} }
delete pd; delete pd;
} }
edit_system->
setFixDuplicateCartTitles(edit_fix_duplicate_carts_box->isChecked());
edit_system->setSampleRate(edit_sample_rate_box->currentText().toUInt()); edit_system->setSampleRate(edit_sample_rate_box->currentText().toUInt());
edit_system->setMaxPostLength(edit_maxpost_spin->value()*1000000); edit_system->setMaxPostLength(edit_maxpost_spin->value()*1000000);
edit_system->setIsciXreferencePath(edit_isci_path_edit->text()); edit_system->setIsciXreferencePath(edit_isci_path_edit->text());

View File

@ -46,6 +46,7 @@ class EditSettings : public QDialog
private slots: private slots:
void BuildDuplicatesList(std::map<unsigned,QString> *dups); void BuildDuplicatesList(std::map<unsigned,QString> *dups);
void duplicatesCheckedData(bool state);
void saveData(); void saveData();
void okData(); void okData();
void cancelData(); void cancelData();
@ -53,8 +54,10 @@ class EditSettings : public QDialog
private: private:
QComboBox *edit_sample_rate_box; QComboBox *edit_sample_rate_box;
QCheckBox *edit_duplicate_carts_box; QCheckBox *edit_duplicate_carts_box;
QSpinBox *edit_maxpost_spin;
RDLabel *edit_duplicate_label; RDLabel *edit_duplicate_label;
QCheckBox *edit_fix_duplicate_carts_box;
QLabel *edit_fix_duplicate_carts_label;
QSpinBox *edit_maxpost_spin;
QLineEdit *edit_isci_path_edit; QLineEdit *edit_isci_path_edit;
QComboBox *edit_temp_cart_group_box; QComboBox *edit_temp_cart_group_box;
QListView *edit_duplicate_list; QListView *edit_duplicate_list;

View File

@ -3455,6 +3455,10 @@ Přepsat?</translation>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3415,6 +3415,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3454,6 +3454,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3107,6 +3107,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3414,6 +3414,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3414,6 +3414,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -3407,6 +3407,10 @@ Overwrite?</source>
<source>Temporary Cart Group:</source> <source>Temporary Cart Group:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Auto-Correct Duplicate Cart Titles</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditStation</name> <name>EditStation</name>

View File

@ -313,6 +313,11 @@ void Xport::EditCart()
cart->setGroupName(group_name); cart->setGroupName(group_name);
} }
if(xport_post->getValue("TITLE",&value)) { if(xport_post->getValue("TITLE",&value)) {
if((!xport_system->allowDuplicateCartTitles())&&
(!xport_system->fixDuplicateCartTitles())&&
(!RDCart::titleIsUnique(value))) {
XmlExit("Duplicate Cart Title Not Allowed",404,"carts.cpp",LINE_NUMBER);
}
cart->setTitle(value); cart->setTitle(value);
} }
if(xport_post->getValue("ARTIST",&value)) { if(xport_post->getValue("ARTIST",&value)) {

View File

@ -155,12 +155,20 @@ void Xport::Import()
settings->setSampleRate(xport_system->sampleRate()); settings->setSampleRate(xport_system->sampleRate());
settings->setBitRate(channels*conf->defaultBitrate()); settings->setBitRate(channels*conf->defaultBitrate());
settings->setNormalizationLevel(normalization_level); settings->setNormalizationLevel(normalization_level);
RDWaveData wavedata;
RDWaveFile *wave=new RDWaveFile(filename); RDWaveFile *wave=new RDWaveFile(filename);
if(!wave->openWave()) { if(!wave->openWave(&wavedata)) {
delete wave; delete wave;
XmlExit("Format Not Supported",415,"import.cpp",LINE_NUMBER); XmlExit("Format Not Supported",415,"import.cpp",LINE_NUMBER);
} }
delete wave; delete wave;
if(use_metadata) {
if((!xport_system->allowDuplicateCartTitles())&&
(!xport_system->fixDuplicateCartTitles())&&
(!RDCart::titleIsUnique(wavedata.title()))) {
XmlExit("Duplicate Cart Title Not Allowed",404,"import.cpp",LINE_NUMBER);
}
}
RDAudioConvert *conv=new RDAudioConvert(xport_config->stationName()); RDAudioConvert *conv=new RDAudioConvert(xport_config->stationName());
conv->setSourceFile(filename); conv->setSourceFile(filename);
conv->setDestinationFile(RDCut::pathName(cartnum,cutnum)); conv->setDestinationFile(RDCut::pathName(cartnum,cutnum));