2020-08-07 Fred Gleason <fredg@paravelsystems.com>

* Added a 'SYSTEM.RSS_PROCESSOR_STATION' field to the database.
	* Added a 'PODCASTS.EXPIRATION_DATETIME' field to the database.
	* Dropped the 'PODCASTS.SHELF_LIFE' field from the database.
	* Incremented the database version to 329.
	* Modified convention to use local system time for all podcast
	components.
	* Added 'RDPodcast::expirationDateTime()' and
	'RDPodcast::setExpirationDateTime()' methods.
	* Removed 'RDPodcast::shelfLife()' and 'RDPodcast::setShelfLife()'
	methods.
	* Added an rdrssd(8) daemon.
	* Removed the rdpurgecasts(8) utility.
	* Added 'RDSystem::rssProcessorStation()' and
	'RDSystem::setRssProcessorStation()' methods.
	* Added a 'Process RSS Updates' control to the 'System-Wide Settings'
	dialog in rdadmin(1).

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason
2020-08-07 17:06:50 -04:00
parent 7d62e200ba
commit e0af63d3e1
45 changed files with 818 additions and 438 deletions

View File

@@ -32,7 +32,6 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
cast_cast=new RDPodcast(rda->config(),cast_id);
cast_feed=new RDFeed(cast_cast->feedId(),rda->config());
cast_status=cast_cast->status();
setWindowTitle("RDCastManager - "+tr("Editing PodCast"));
//
// Active Checkbox
@@ -43,6 +42,17 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
cast_active_label->setFont(labelFont());
cast_active_label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
//
// Item Origin
//
cast_item_origin_edit=new QLineEdit(this);
cast_item_origin_edit->setReadOnly(true);
cast_item_origin_edit->setMaxLength(64);
cast_item_origin_label=
new QLabel(cast_item_origin_edit,tr("Posted At:"),this);
cast_item_origin_label->setFont(labelFont());
cast_item_origin_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
//
// Item Title
//
@@ -127,18 +137,13 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
new QLabel(cast_item_effective_edit,tr("Air Date/Time:"),this);
cast_item_effective_label->setFont(labelFont());
cast_item_effective_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
//
// Item Origin
//
cast_item_origin_edit=new QLineEdit(this);
cast_item_origin_edit->setReadOnly(true);
cast_item_origin_edit->setMaxLength(64);
cast_item_origin_label=
new QLabel(cast_item_origin_edit,tr("Posted At:"),this);
cast_item_origin_label->setFont(labelFont());
cast_item_origin_label->
cast_item_effective_label->
setAlignment(Qt::AlignRight|Qt::AlignVCenter);
cast_item_effective_button=new QPushButton(this);
cast_item_effective_button->setFont(subButtonFont());
cast_item_effective_button->setText(tr("&Select Date"));
connect(cast_item_effective_button,SIGNAL(clicked()),
this,SLOT(effectiveSelectData()));
//
// Item Expiration
@@ -157,15 +162,15 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
cast_item_expiration_box_label->
setEnabled(cast_status!=RDPodcast::StatusExpired);
cast_item_expiration_edit=new QDateEdit(this);
cast_item_expiration_edit=new QDateTimeEdit(this);
cast_item_expiration_edit->setDisplayFormat("MM/dd/yyyy hh:mm:ss");
cast_item_expiration_label=
new QLabel(cast_item_expiration_edit,tr("Expires On")+":",this);
new QLabel(cast_item_expiration_edit,tr("at"),this);
cast_item_expiration_label->setFont(labelFont());
cast_item_expiration_label->
setAlignment(Qt::AlignRight|Qt::AlignVCenter);
cast_item_expiration_label->setAlignment(Qt::AlignCenter);
cast_item_expiration_button=new QPushButton(this);
cast_item_expiration_button->setFont(subButtonFont());
cast_item_expiration_button->setText(tr("&Select"));
cast_item_expiration_button->setText(tr("&Select Date"));
connect(cast_item_expiration_button,SIGNAL(clicked()),
this,SLOT(expirationSelectData()));
cast_item_expiration_edit->setEnabled(cast_status!=RDPodcast::StatusExpired);
@@ -195,9 +200,11 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
//
// Populate Values
//
setWindowTitle("RDCastManager - "+tr("Editing PodCast")+
+" [ID: "+QString().sprintf("%u",cast_cast->id())+"]");
cast_item_title_edit->setText(cast_cast->itemTitle());
cast_item_author_edit->setText(cast_cast->itemAuthor());
cast_item_origin_edit->setText(RDUtcToLocal(cast_cast->originDateTime()).
cast_item_origin_edit->setText(cast_cast->originDateTime().
toString("MM/dd/yyyy - hh:mm:ss"));
cast_item_category_edit->setText(cast_cast->itemCategory());
cast_item_category_label->
@@ -212,15 +219,18 @@ EditCast::EditCast(unsigned cast_id,QWidget *parent)
cast_item_image_box->setCategoryId(cast_feed->id());
cast_item_image_box->setCurrentImageId(cast_cast->itemImageId());
cast_item_comments_edit->setText(cast_cast->itemComments());
cast_item_effective_edit->
setDateTime(RDUtcToLocal(cast_cast->effectiveDateTime()));
if(cast_cast->shelfLife()>0) {
cast_item_effective_edit->setDateTime(cast_cast->effectiveDateTime());
if(!cast_cast->expirationDateTime().isNull()) {
cast_item_expiration_box->setCurrentItem(1);
}
cast_item_expiration_edit->setDateTime(cast_cast->expirationDateTime());
cast_item_expiration_edit->
setDate(RDUtcToLocal(cast_cast->originDateTime()).date().
addDays(cast_cast->shelfLife()));
expirationSelectedData(cast_item_expiration_box->currentItem());
setEnabled(cast_item_expiration_box->currentItem());
cast_item_expiration_button->
setEnabled(cast_item_expiration_box->currentItem());
cast_item_expiration_label->
setEnabled(cast_item_expiration_box->currentItem());
switch(cast_status) {
case RDPodcast::StatusActive:
cast_active_check->setChecked(true);
@@ -252,7 +262,7 @@ EditCast::~EditCast()
QSize EditCast::sizeHint() const
{
return QSize(640,480);
return QSize(640,440);
}
@@ -262,12 +272,29 @@ QSizePolicy EditCast::sizePolicy() const
}
void EditCast::effectiveSelectData()
{
QDate current_date=QDate::currentDate();
QDate date=cast_item_effective_edit->date();
RDDateDialog *dd=
new RDDateDialog(current_date.year(),current_date.year()+10,this);
if(dd->exec(&date)==0) {
cast_item_effective_edit->setDate(date);
}
delete dd;
}
void EditCast::expirationSelectedData(int state)
{
state=state&&(cast_status!=RDPodcast::StatusExpired);
cast_item_expiration_edit->setEnabled(state);
cast_item_expiration_button->setEnabled(state);
cast_item_expiration_label->setEnabled(state);
if(state) {
cast_item_expiration_edit->setDate(QDate::currentDate().addDays(1));
}
}
@@ -275,9 +302,9 @@ void EditCast::expirationSelectData()
{
QDate current_date=QDate::currentDate();
QDate date=cast_item_expiration_edit->date();
RDDateDialog *dd=
new RDDateDialog(current_date.year(),current_date.year()+10,this);
new RDDateDialog(1970,current_date.year()+10,this);
if(dd->exec(&date)==0) {
cast_item_expiration_edit->setDate(date);
}
@@ -297,19 +324,18 @@ void EditCast::okData()
cast_cast->setItemExplicit(cast_item_explicit_check->isChecked());
cast_cast->setItemImageId(cast_item_image_box->currentImageId());
cast_cast->setItemComments(cast_item_comments_edit->text());
cast_cast->
setEffectiveDateTime(RDLocalToUtc(cast_item_effective_edit->dateTime()));
cast_cast->setEffectiveDateTime(cast_item_effective_edit->dateTime());
if(cast_active_check->isEnabled()) {
if(cast_item_expiration_box->currentItem()) {
int shelf_life=RDUtcToLocal(cast_cast->originDateTime()).date().
int shelf_life=cast_cast->originDateTime().date().
daysTo(cast_item_expiration_edit->date());
if(shelf_life<1) {
shelf_life=1;
}
cast_cast->setShelfLife(shelf_life);
cast_cast->setExpirationDateTime(cast_item_expiration_edit->dateTime());
}
else {
cast_cast->setShelfLife(0);
cast_cast->setExpirationDateTime(QDateTime());
}
if(cast_active_check->isChecked()) {
cast_cast->setStatus(RDPodcast::StatusActive);
@@ -319,10 +345,6 @@ void EditCast::okData()
}
}
cast_feed->
setLastBuildDateTime(RDLocalToUtc(QDateTime(QDate::currentDate(),
QTime::currentTime())));
if(!cast_feed->postXmlConditional("RDCastManager",this)) {
return;
}
@@ -418,21 +440,19 @@ void EditCast::resizeEvent(QResizeEvent *e)
//
// Air Date/Time
//
cast_item_effective_edit->setGeometry(135,h-157,150,20);
cast_item_effective_label->setGeometry(20,h-157,110,20);
cast_item_effective_label->setGeometry(20,h-154,110,20);
cast_item_effective_edit->setGeometry(135,h-154,150,20);
cast_item_effective_button->setGeometry(295,h-156,75,24);
//
// Cast Expires
// Cast Expiration
//
cast_item_expiration_box->setGeometry(135,h-135,50,20);
cast_item_expiration_box_label->setGeometry(20,h-135,110,20);
cast_item_expiration_box_label->setGeometry(20,h-126,110,20);
cast_item_expiration_box->setGeometry(135,h-126,50,20);
//
// Expires On
//
cast_item_expiration_edit->setGeometry(135,h-113,95,20);
cast_item_expiration_label->setGeometry(20,h-113,110,20);
cast_item_expiration_button->setGeometry(240,h-113,50,20);
cast_item_expiration_label->setGeometry(190,h-126,20,20);
cast_item_expiration_edit->setGeometry(215,h-126,150,20);
cast_item_expiration_button->setGeometry(375,h-128,75,24);
//
// Buttons

View File

@@ -46,6 +46,7 @@ class EditCast : public RDDialog
QSizePolicy sizePolicy() const;
private slots:
void effectiveSelectData();
void expirationSelectedData(int state);
void expirationSelectData();
void okData();
@@ -57,6 +58,8 @@ class EditCast : public RDDialog
private:
RDFeed *cast_feed;
RDPodcast *cast_cast;
QLabel *cast_item_origin_label;
QLineEdit *cast_item_origin_edit;
QLabel *cast_item_title_label;
QLineEdit *cast_item_title_edit;
QLabel *cast_item_author_label;
@@ -73,17 +76,16 @@ class EditCast : public RDDialog
RDImagePickerBox *cast_item_image_box;
QLabel *cast_item_comments_label;
QLineEdit *cast_item_comments_edit;
QLabel *cast_item_origin_label;
QLineEdit *cast_item_origin_edit;
QLabel *cast_item_expiration_box_label;
QComboBox *cast_item_expiration_box;
QLabel *cast_item_expiration_label;
QCheckBox *cast_active_check;
QLabel *cast_active_label;
QPushButton *cast_item_expiration_button;
QDateEdit *cast_item_expiration_edit;
QDateTimeEdit *cast_item_expiration_edit;
QLabel *cast_item_effective_label;
QDateTimeEdit *cast_item_effective_edit;
QPushButton *cast_item_effective_button;
QPushButton *cast_ok_button;
QPushButton *cast_cancel_button;
RDPodcast::Status cast_status;

View File

@@ -45,13 +45,14 @@ ListCasts::ListCasts(unsigned feed_id,bool is_super,QWidget *parent)
list_feed_id=feed_id;
list_is_superfeed=is_super;
setWindowTitle("RDCastManager - "+tr("Podcast List")+
" [ID: "+QString().sprintf("%u",feed_id)+"]");
//
// Fix the Window Size
//
setMinimumSize(sizeHint());
setWindowTitle("RDCastManager - "+tr("Podcast List"));
//
// Create Icons
//
@@ -500,15 +501,15 @@ void ListCasts::RefreshItem(RDListViewItem *item)
RDSqlQuery *q;
sql=QString("select ")+
"PODCASTS.STATUS,"+ // 00
"PODCASTS.ITEM_TITLE,"+ // 01
"PODCASTS.ORIGIN_DATETIME,"+ // 02
"PODCASTS.SHELF_LIFE,"+ // 03
"PODCASTS.AUDIO_TIME,"+ // 04
"PODCASTS.ITEM_DESCRIPTION,"+ // 05
"FEEDS.KEY_NAME,"+ // 06
"PODCASTS.ITEM_CATEGORY,"+ // 07
"PODCASTS.ITEM_LINK "+ // 08
"PODCASTS.STATUS,"+ // 00
"PODCASTS.ITEM_TITLE,"+ // 01
"PODCASTS.ORIGIN_DATETIME,"+ // 02
"PODCASTS.EXPIRATION_DATETIME,"+ // 03
"PODCASTS.AUDIO_TIME,"+ // 04
"PODCASTS.ITEM_DESCRIPTION,"+ // 05
"FEEDS.KEY_NAME,"+ // 06
"PODCASTS.ITEM_CATEGORY,"+ // 07
"PODCASTS.ITEM_LINK "+ // 08
"from PODCASTS left join FEEDS "+
"on PODCASTS.FEED_ID=FEEDS.ID where "+
QString().sprintf("PODCASTS.ID=%d",item->id());
@@ -528,14 +529,12 @@ void ListCasts::RefreshItem(RDListViewItem *item)
break;
}
item->setText(1,q->value(1).toString());
item->setText(2,RDUtcToLocal(q->value(2).toDateTime()).
toString("MM/dd/yyyy hh:mm:ss"));
if(q->value(3).toInt()==0) {
item->setText(2,q->value(2).toDateTime().toString("MM/dd/yyyy hh:mm:ss"));
if(q->value(3).isNull()) {
item->setText(3,tr("Never"));
}
else {
item->setText(3,RDUtcToLocal(q->value(2).toDateTime()).
addDays(q->value(3).toInt()).toString("MM/dd/yyyy"));
item->setText(3,q->value(3).toDateTime().toString("MM/dd/yyyy hh:mm:ss"));
}
item->setText(4,RDGetTimeLength(q->value(4).toInt(),false,false));
item->setText(5,q->value(5).toString());

View File

@@ -61,7 +61,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Vybrat</translation>
<translation type="obsolete">&amp;Vybrat</translation>
</message>
<message>
<source>Hold</source>
@@ -114,7 +114,11 @@ dílu</translation>
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -61,7 +61,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Auswählen</translation>
<translation type="obsolete">&amp;Auswählen</translation>
</message>
<message>
<source>Hold</source>
@@ -110,7 +110,11 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -37,7 +37,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Elegir</translation>
<translation type="obsolete">&amp;Elegir</translation>
</message>
<message>
<source>Hold</source>
@@ -110,7 +110,11 @@ Episodios</translation>
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -47,10 +47,6 @@
<source>Cast Expires:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;OK</source>
<translation type="unfinished"></translation>
@@ -76,7 +72,11 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -61,7 +61,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Vel</translation>
<translation type="obsolete">&amp;Vel</translation>
</message>
<message>
<source>Hold</source>
@@ -106,7 +106,11 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -61,7 +61,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Vel</translation>
<translation type="obsolete">&amp;Vel</translation>
</message>
<message>
<source>Hold</source>
@@ -106,7 +106,11 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -49,7 +49,7 @@
</message>
<message>
<source>&amp;Select</source>
<translation>&amp;Selecionar</translation>
<translation type="obsolete">&amp;Selecionar</translation>
</message>
<message>
<source>Posted At:</source>
@@ -110,7 +110,11 @@ Episódio</translation>
<translation type="unfinished"></translation>
</message>
<message>
<source>Expires On</source>
<source>at</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Select Date</source>
<translation type="unfinished"></translation>
</message>
</context>