mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-11-29 08:40:12 +01:00
2023-04-27 Fred Gleason <fredg@paravelsystems.com>
* Removed a 'RDFeed::generateReport()' methods. * Added a 'DownloadRss()' method to the WebAPI. * Added a 'RDXsltEngine' class. * Added a 'Generate Front Report' item to the right-click menu in the 'Podcast Feeds' list in the 'Rivendell Feed List' dialog in rdadmin(1). * Added a 'Generate Back Report' item to the right-click menu in the 'Podcast Feeds' list in the 'Rivendell Feed List' dialog in rdadmin(1). Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -24046,3 +24046,13 @@
|
||||
threw a segfault when reposting a feed.
|
||||
2023-04-25 Fred Gleason <fredg@paravelsystems.com>
|
||||
* Added a 'RDFeed::generateReport()' method.
|
||||
2023-04-27 Fred Gleason <fredg@paravelsystems.com>
|
||||
* Removed a 'RDFeed::generateReport()' methods.
|
||||
* Added a 'DownloadRss()' method to the WebAPI.
|
||||
* Added a 'RDXsltEngine' class.
|
||||
* Added a 'Generate Front Report' item to the right-click menu in
|
||||
the 'Podcast Feeds' list in the 'Rivendell Feed List' dialog in
|
||||
rdadmin(1).
|
||||
* Added a 'Generate Back Report' item to the right-click menu in
|
||||
the 'Podcast Feeds' list in the 'Rivendell Feed List' dialog in
|
||||
rdadmin(1).
|
||||
|
||||
@@ -894,6 +894,73 @@
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>DownloadRss</title>
|
||||
<subtitle>Download podcast RSS XML from the remote archive</subtitle>
|
||||
<note>
|
||||
The download is attempted using the <emphasis>upload</emphasis>
|
||||
URL and credentials!
|
||||
</note>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_DOWNLOAD_RSS</code>
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Edit Podcast</code>, Feed Permission
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
A <computeroutput>404</computeroutput> error will be returned if the
|
||||
requested feed is not authorized for the specified
|
||||
Rivendell user in RDAdmin->ManageUsers->PodcastFeedPermissions.
|
||||
</para>
|
||||
<table xml:id="ex.download_rss
|
||||
" frame="all">
|
||||
<title>DownloadRss Call Fields</title>
|
||||
<tgroup cols="3" align="left" colsep="1" rowsep="1">
|
||||
<colspec colname="FIELD NAME" />
|
||||
<colspec colname="MEANING" />
|
||||
<colspec colname="REMARKS" />
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
FIELD NAME
|
||||
</entry>
|
||||
<entry>
|
||||
MEANING
|
||||
</entry>
|
||||
<entry>
|
||||
REMARKS
|
||||
</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
COMMAND
|
||||
</entry>
|
||||
<entry>
|
||||
46
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
ID
|
||||
</entry>
|
||||
<entry>
|
||||
ID of podcast feed (integer)
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>EditCart</title>
|
||||
<subtitle>
|
||||
@@ -2863,7 +2930,7 @@
|
||||
</para>
|
||||
<table xml:id="ex.post_image
|
||||
" frame="all">
|
||||
<title>PostRss Call Fields</title>
|
||||
<title>PostImage Call Fields</title>
|
||||
<tgroup cols="3" align="left" colsep="1" rowsep="1">
|
||||
<colspec colname="FIELD NAME" />
|
||||
<colspec colname="MEANING" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
##
|
||||
## Automake.am for rivendell/lib
|
||||
##
|
||||
## (C) Copyright 2002-2022 Fred Gleason <fredg@paravelsystems.com>
|
||||
## (C) Copyright 2002-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License version 2 as
|
||||
@@ -136,6 +136,7 @@ dist_librd_la_SOURCES = dbversion.h\
|
||||
rdexport_settings_dialog.cpp rdexport_settings_dialog.h\
|
||||
rdfeed.cpp rdfeed.h\
|
||||
rdfeedlistmodel.cpp rdfeedlistmodel.h\
|
||||
rdfeedlistview.cpp rdfeedlistview.h\
|
||||
rdfontengine.cpp rdfontengine.h\
|
||||
rdformpost.cpp rdformpost.h\
|
||||
rdflacdecode.cpp rdflacdecode.h\
|
||||
@@ -295,7 +296,8 @@ dist_librd_la_SOURCES = dbversion.h\
|
||||
rdweb.cpp rdweb.h\
|
||||
rdwebresult.cpp rdwebresult.h\
|
||||
rdwidget.cpp rdwidget.h\
|
||||
rdxport_interface.h
|
||||
rdxport_interface.h\
|
||||
rdxsltengine.cpp rdxsltengine.h
|
||||
|
||||
|
||||
nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
|
||||
@@ -346,6 +348,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
|
||||
moc_rdexport_settings_dialog.cpp\
|
||||
moc_rdfeed.cpp\
|
||||
moc_rdfeedlistmodel.cpp\
|
||||
moc_rdfeedlistview.cpp\
|
||||
moc_rdframe.cpp\
|
||||
moc_rdget_ath.cpp\
|
||||
moc_rdgetpasswd.cpp\
|
||||
@@ -440,7 +443,8 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
|
||||
moc_rdwavedata_dialog.cpp\
|
||||
moc_rdwavescene.cpp\
|
||||
moc_rdwavewidget.cpp\
|
||||
moc_rdwidget.cpp
|
||||
moc_rdwidget.cpp\
|
||||
moc_rdxsltengine.cpp
|
||||
|
||||
librd_la_LDFLAGS = -release $(VERSION)
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@ SOURCES += rdwavescene.cpp
|
||||
SOURCES += rdwavewidget.cpp
|
||||
SOURCES += rdweb.cpp
|
||||
SOURCES += rdwidget.cpp
|
||||
SOURCES += rdxsltengine.cpp
|
||||
|
||||
HEADERS += rd.h
|
||||
HEADERS += rdadd_cart.h
|
||||
@@ -417,6 +418,7 @@ HEADERS += rdwavescene.h
|
||||
HEADERS += rdwavewidget.h
|
||||
HEADERS += rdweb.h
|
||||
HEADERS += rdwidget.h
|
||||
HEADERS += rdxsltengine.h
|
||||
|
||||
TRANSLATIONS += librd_cs.ts
|
||||
TRANSLATIONS += librd_de.ts
|
||||
|
||||
124
lib/rdfeed.cpp
124
lib/rdfeed.cpp
@@ -22,6 +22,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
|
||||
#include "rdapplication.h"
|
||||
#include "rdaudioconvert.h"
|
||||
@@ -57,7 +58,7 @@ int __RDFeed_Debug_Callback(CURL *handle,curl_infotype type,char *data,
|
||||
}
|
||||
|
||||
|
||||
size_t __RDFeed_Write_Callback(char *ptr,size_t size,size_t nmemb,
|
||||
size_t __RDFeed_Download_Callback(char *ptr,size_t size,size_t nmemb,
|
||||
void *userdata)
|
||||
{
|
||||
QByteArray *buffer=(QByteArray *)userdata;
|
||||
@@ -868,7 +869,7 @@ bool RDFeed::postPodcast(unsigned cast_id,QString *err_msg)
|
||||
}
|
||||
QStringList *err_msgs=SetupCurlLogging(curl);
|
||||
QByteArray write_buffer;
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDFeed_Write_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDFeed_Download_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,&write_buffer);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
@@ -955,6 +956,90 @@ QString RDFeed::imageUrl(int img_id) const
|
||||
}
|
||||
|
||||
|
||||
bool RDFeed::downloadXml(QByteArray *xml,QString *err_msg)
|
||||
{
|
||||
long response_code;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
char curl_errorbuffer[CURL_ERROR_SIZE];
|
||||
struct curl_httppost *first=NULL;
|
||||
struct curl_httppost *last=NULL;
|
||||
|
||||
//
|
||||
// Generate POST Data
|
||||
//
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"COMMAND",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
QString::asprintf("%u",RDXPORT_COMMAND_DOWNLOAD_RSS).toUtf8().
|
||||
constData(),
|
||||
CURLFORM_END);
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"LOGIN_NAME",
|
||||
CURLFORM_COPYCONTENTS,rda->user()->name().toUtf8().constData(),
|
||||
CURLFORM_END);
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"PASSWORD",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
rda->user()->password().toUtf8().constData(),CURLFORM_END);
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"ID",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
QString::asprintf("%u",feed_id).toUtf8().constData(),
|
||||
CURLFORM_END);
|
||||
|
||||
//
|
||||
// Set up the transfer
|
||||
//
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
QStringList *err_msgs=SetupCurlLogging(curl);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDFeed_Download_Callback);
|
||||
feed_xml.clear();
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,xml);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,curl_errorbuffer);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
rda->config()->userAgent().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
curl_easy_setopt(curl,CURLOPT_URL,
|
||||
rda->station()->webServiceUrl(rda->config()).toUtf8().constData());
|
||||
rda->syslog(LOG_DEBUG,"using web service URL: %s",
|
||||
rda->station()->webServiceUrl(rda->config()).toUtf8().constData());
|
||||
|
||||
//
|
||||
// Send it
|
||||
//
|
||||
if((curl_err=curl_easy_perform(curl))!=CURLE_OK) {
|
||||
*err_msg=QString::fromUtf8(curl_errorbuffer);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
ProcessCurlLogging("RDFeed::postPodcast()",err_msgs);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Clean up
|
||||
//
|
||||
curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
|
||||
//
|
||||
// Process the results
|
||||
//
|
||||
if((response_code<200)||(response_code>299)) {
|
||||
*err_msg=tr("remote server returned unexpected response code")+
|
||||
QString::asprintf(" %ld",response_code);
|
||||
ProcessCurlLogging("RDFeed::postPodcast()",err_msgs);
|
||||
return false;
|
||||
}
|
||||
delete err_msgs;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RDFeed::postXml(QString *err_msg)
|
||||
{
|
||||
long response_code;
|
||||
@@ -1873,39 +1958,6 @@ QString RDFeed::itunesCategoryXml(const QString &category,
|
||||
}
|
||||
|
||||
|
||||
bool RDFeed::generateReport(const QString &feed_url,
|
||||
const QString &stylesheet_pathname,
|
||||
const QString &report_filename,
|
||||
RDTempDirectory *tempdir,
|
||||
QString *err_msg)
|
||||
{
|
||||
QString err_msg2;
|
||||
int result;
|
||||
bool ret=false;
|
||||
|
||||
ret=tempdir->create(&err_msg2);
|
||||
if(ret) {
|
||||
*err_msg=QObject::tr("Unable to create temporary directory.")+
|
||||
"["+err_msg2+"]";
|
||||
QString tmpfile=tempdir->path()+"/"+report_filename;
|
||||
QString cmd="curl -f -s "+feed_url+" | xsltproc --encoding utf-8 "+
|
||||
stylesheet_pathname+" - > "+tmpfile;
|
||||
result=system(cmd.toUtf8());
|
||||
if(result==-1) {
|
||||
*err_msg=tr("unable to fork process")+" ["+strerror(errno)+"].";
|
||||
return false;
|
||||
}
|
||||
if(WEXITSTATUS(result)!=0) {
|
||||
*err_msg=tr("converter returned non-zero exit code.");
|
||||
return false;
|
||||
}
|
||||
RDWebBrowser("file://"+tmpfile);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void RDFeed::renderMessage(const QString &msg)
|
||||
{
|
||||
fprintf(stderr,"RENDERER: %s\n",msg.toUtf8().constData());
|
||||
@@ -1962,7 +2014,7 @@ bool RDFeed::SavePodcast(unsigned cast_id,const QString &src_filename,
|
||||
}
|
||||
QStringList *err_msgs=SetupCurlLogging(curl);
|
||||
QByteArray write_buffer;
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDFeed_Write_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDFeed_Download_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,&write_buffer);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
|
||||
23
lib/rdfeed.h
23
lib/rdfeed.h
@@ -136,11 +136,12 @@ class RDFeed : public QObject
|
||||
bool postPodcast(unsigned cast_id,QString *err_msg);
|
||||
QString audioUrl(unsigned cast_id);
|
||||
QString imageUrl(int img_id) const;
|
||||
bool postXml(QString *err_msg);
|
||||
bool downloadXml(QByteArray *xml,QString *err_msg); // WebAPI Call
|
||||
bool postXml(QString *err_msg); // WebAPI Call
|
||||
bool postXmlConditional(const QString &caption,QWidget *widget);
|
||||
bool removeRss();
|
||||
bool postImage(int img_id) const;
|
||||
bool removeImage(int img_id) const;
|
||||
bool removeRss(); // WebAPI Call
|
||||
bool postImage(int img_id) const; // WebAPI Call
|
||||
bool removeImage(int img_id) const; // WebAPI Call
|
||||
void removeAllImages();
|
||||
unsigned postCut(const QString &cutname,QString *err_msg);
|
||||
unsigned postFile(const QString &srcfile,QString *err_msg);
|
||||
@@ -154,10 +155,24 @@ class RDFeed : public QObject
|
||||
static QString publicUrl(const QString &base_url,const QString &keyname);
|
||||
static QString itunesCategoryXml(const QString &category,
|
||||
const QString &sub_category,int padding=0);
|
||||
/*
|
||||
static bool generateReport(const QString &feed_url,
|
||||
const QString &stylesheet_pathname,
|
||||
const QString &report_filename,
|
||||
RDTempDirectory *tempdir,QString *err_msg);
|
||||
*/
|
||||
/*
|
||||
static bool generateReport(const QByteArray &src_xml,
|
||||
const QString &stylesheet_pathname,
|
||||
const QString &report_filename,
|
||||
RDTempDirectory *tempdir,QString *err_msg);
|
||||
*/
|
||||
/*
|
||||
static bool generateReport(QString *output,
|
||||
const QString &src_xml,
|
||||
const QString &stylesheet_pathname,
|
||||
QString *err_msg);
|
||||
*/
|
||||
|
||||
signals:
|
||||
void postProgressChanged(int step);
|
||||
|
||||
@@ -258,6 +258,12 @@ bool RDFeedListModel::isCast(const QModelIndex &index) const
|
||||
}
|
||||
|
||||
|
||||
QString RDFeedListModel::keyName(int row) const
|
||||
{
|
||||
return d_key_names.at(row);
|
||||
}
|
||||
|
||||
|
||||
QString RDFeedListModel::keyName(const QModelIndex &index) const
|
||||
{
|
||||
if(index.isValid()) {
|
||||
|
||||
@@ -54,6 +54,7 @@ class RDFeedListModel : public QAbstractItemModel
|
||||
bool isFeed(const QModelIndex &index) const;
|
||||
bool isCast(const QModelIndex &index) const;
|
||||
QString keyName(const QModelIndex &index) const;
|
||||
QString keyName(int row) const;
|
||||
unsigned feedId(const QModelIndex &index) const;
|
||||
QString publicUrl(const QModelIndex &index) const;
|
||||
QModelIndex feedRow(const QString &keyname) const;
|
||||
|
||||
131
lib/rdfeedlistview.cpp
Normal file
131
lib/rdfeedlistview.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// rdfeedlistview.cpp
|
||||
//
|
||||
// RDTableView widget for RSS feeds
|
||||
//
|
||||
// (C) Copyright 2021 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#include <QDragEnterEvent>
|
||||
#include <QHeaderView>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "rdfeed.h"
|
||||
#include "rdfeedlistmodel.h"
|
||||
#include "rdfeedlistview.h"
|
||||
#include "rdtextfile.h"
|
||||
|
||||
RDFeedListView::RDFeedListView(QWidget *parent)
|
||||
:RDTableView(parent)
|
||||
{
|
||||
d_mouse_row=-1;
|
||||
|
||||
//
|
||||
// Mouse menu
|
||||
//
|
||||
d_mouse_menu=new QMenu(this);
|
||||
|
||||
d_front_report_action=d_mouse_menu->
|
||||
addAction(tr("Generate Front Report"),this,SLOT(generateFrontReportData()));
|
||||
d_front_report_action->setCheckable(false);
|
||||
|
||||
d_back_report_action=d_mouse_menu->
|
||||
addAction(tr("Generate Back Report"),this,SLOT(generateBackReportData()));
|
||||
d_back_report_action->setCheckable(false);
|
||||
|
||||
connect(d_mouse_menu,SIGNAL(aboutToShow()),
|
||||
this,SLOT(aboutToShowMenuData()));
|
||||
|
||||
//
|
||||
// XSLT Engine (for feed reports)
|
||||
//
|
||||
d_xslt_engine=
|
||||
new RDXsltEngine("/usr/share/rivendell/rdcastmanager-report.xsl",this);
|
||||
}
|
||||
|
||||
|
||||
RDFeedListView::~RDFeedListView()
|
||||
{
|
||||
delete d_xslt_engine;
|
||||
}
|
||||
|
||||
|
||||
void RDFeedListView::aboutToShowMenuData()
|
||||
{
|
||||
RDFeedListModel *mod=(RDFeedListModel *)model();
|
||||
|
||||
if((d_mouse_row<0)||(d_mouse_row>=mod->rowCount())) {
|
||||
d_front_report_action->setEnabled(false);
|
||||
d_back_report_action->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
d_front_report_action->setEnabled(true);
|
||||
d_back_report_action->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RDFeedListView::generateFrontReportData()
|
||||
{
|
||||
QString err_msg;
|
||||
RDFeedListModel *m=(RDFeedListModel *)model();
|
||||
QString keyname=m->data(m->index(d_mouse_row,0)).toString();
|
||||
RDFeed *feed=new RDFeed(keyname,rda->config(),this);
|
||||
QByteArray xml;
|
||||
if(feed->downloadXml(&xml,&err_msg)) {
|
||||
QString output_filename="report.html";
|
||||
if(d_xslt_engine->transformXml(&output_filename,xml,&err_msg)) {
|
||||
RDWebBrowser("file://"+output_filename);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this,"RDAdmin - "+tr("Error"),err_msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this,"RDAdmin - "+tr("Error"),err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RDFeedListView::generateBackReportData()
|
||||
{
|
||||
QString err_msg;
|
||||
RDFeedListModel *m=(RDFeedListModel *)model();
|
||||
QString url=m->data(m->index(d_mouse_row,6)).toString();
|
||||
|
||||
QString output_filename="report.html";
|
||||
if(d_xslt_engine->transformUrl(&output_filename,url,&err_msg)) {
|
||||
RDWebBrowser("file://"+output_filename);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this,"RDAdmin - "+tr("Error"),err_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RDFeedListView::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
if(e->button()==Qt::RightButton) {
|
||||
d_mouse_row=indexAt(e->pos()).row();
|
||||
if((d_mouse_row>=0)&&(d_mouse_row<model()->rowCount())) {
|
||||
d_mouse_menu->popup(e->globalPos());
|
||||
}
|
||||
else {
|
||||
d_mouse_row=-1;
|
||||
}
|
||||
}
|
||||
QTableView::mousePressEvent(e);
|
||||
}
|
||||
56
lib/rdfeedlistview.h
Normal file
56
lib/rdfeedlistview.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// rdfeedlistview.h
|
||||
//
|
||||
// RDTableView widget for RSS feeds
|
||||
//
|
||||
// (C) Copyright 2023 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#ifndef RDFEEDLISTVIEW_H
|
||||
#define RDFEEDLISTVIEW_H
|
||||
|
||||
#include <QAction>
|
||||
#include <QList>
|
||||
#include <QMenu>
|
||||
|
||||
#include <rdtableview.h>
|
||||
#include <rdtempdirectory.h>
|
||||
#include "rdxsltengine.h"
|
||||
|
||||
class RDFeedListView : public RDTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RDFeedListView(QWidget *parent=0);
|
||||
~RDFeedListView();
|
||||
|
||||
private slots:
|
||||
void aboutToShowMenuData();
|
||||
void generateFrontReportData();
|
||||
void generateBackReportData();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
int d_mouse_row;
|
||||
QMenu *d_mouse_menu;
|
||||
QAction *d_front_report_action;
|
||||
QAction *d_back_report_action;
|
||||
RDXsltEngine *d_xslt_engine;
|
||||
};
|
||||
|
||||
|
||||
#endif // RDFEEDLISTVIEW_H
|
||||
@@ -66,6 +66,7 @@
|
||||
#define RDXPORT_COMMAND_REMOVE_RSS 43
|
||||
#define RDXPORT_COMMAND_POST_IMAGE 44
|
||||
#define RDXPORT_COMMAND_REMOVE_IMAGE 45
|
||||
#define RDXPORT_COMMAND_DOWNLOAD_RSS 46
|
||||
|
||||
|
||||
#endif // RDXPORT_INTERFACE_H
|
||||
|
||||
199
lib/rdxsltengine.cpp
Normal file
199
lib/rdxsltengine.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
// rdxsltengine.cpp
|
||||
//
|
||||
// Engine for performing XSLT transformations
|
||||
//
|
||||
// (C) Copyright 2023 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QStringList>
|
||||
|
||||
#include "rdapplication.h"
|
||||
#include "rdxsltengine.h"
|
||||
|
||||
size_t __RDXsltEngine_Download_Callback(char *ptr,size_t size,size_t nmemb,
|
||||
void *userdata)
|
||||
{
|
||||
QByteArray *buffer=(QByteArray *)userdata;
|
||||
|
||||
buffer->append(QByteArray(ptr,size*nmemb));
|
||||
|
||||
return size*nmemb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
RDXsltEngine::RDXsltEngine(const QString stylesheet_pathname,QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
d_stylesheet_pathname=stylesheet_pathname;
|
||||
}
|
||||
|
||||
|
||||
RDXsltEngine::~RDXsltEngine()
|
||||
{
|
||||
for(int i=0;i<d_temp_directories.size();i++) {
|
||||
delete d_temp_directories.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString RDXsltEngine::stylesheetPathname() const
|
||||
{
|
||||
return d_stylesheet_pathname;
|
||||
}
|
||||
|
||||
|
||||
bool RDXsltEngine::transformUrl(QString *output_filename,const QString &url,
|
||||
QString *err_msg)
|
||||
{
|
||||
QString err_msg2;
|
||||
bool ret=false;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
long response_code;
|
||||
FILE *f=NULL;
|
||||
|
||||
d_temp_directories.push_back(new RDTempDirectory("rivendell-rdxslt"));
|
||||
ret=d_temp_directories.back()->create(&err_msg2);
|
||||
if(ret) {
|
||||
// Download the source
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
*err_msg=tr("Unable to initialize CURL");
|
||||
return false;
|
||||
}
|
||||
QByteArray src_xml;
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__RDXsltEngine_Download_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,&src_xml);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
rda->config()->userAgent().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
curl_easy_setopt(curl,CURLOPT_URL,url.toUtf8().constData());
|
||||
|
||||
curl_err=curl_easy_perform(curl);
|
||||
if((ret=(curl_err==CURLE_OK))) {
|
||||
curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
|
||||
if((ret=(response_code>=200)&&(response_code<300))) {
|
||||
// Generate the report
|
||||
QString output;
|
||||
RDXsltEngine *xslt=new RDXsltEngine(d_stylesheet_pathname);
|
||||
// ret=RDFeed::generateReport(&output,src_xml,stylesheet_pathname,err_msg);
|
||||
ret=xslt->transform(&output,src_xml,err_msg);
|
||||
if(ret) {
|
||||
*output_filename=
|
||||
d_temp_directories.last()->path()+"/"+*output_filename;
|
||||
if((f=fopen((*output_filename).toUtf8(),"w"))!=NULL) {
|
||||
fprintf(f,"%s",output.toUtf8().constData());
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
*err_msg=tr("Unable to create output file")+" ["+
|
||||
strerror(errno)+"].";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
*err_msg=QObject::tr("Curl error")+" ["+curl_easy_strerror(curl_err)+"].";
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
else {
|
||||
*err_msg=QObject::tr("Unable to create temporary directory.")+
|
||||
" ["+err_msg2+"]";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool RDXsltEngine::transformXml(QString *output_filename,const QString &src_xml,
|
||||
QString *err_msg)
|
||||
{
|
||||
QString err_msg2;
|
||||
FILE *f=NULL;
|
||||
bool ret=false;
|
||||
QString output;
|
||||
|
||||
d_temp_directories.push_back(new RDTempDirectory("rivendell-rdxslt"));
|
||||
ret=d_temp_directories.back()->create(&err_msg2);
|
||||
if(ret) {
|
||||
*output_filename=d_temp_directories.last()->path()+"/"+*output_filename;
|
||||
ret=transform(&output,src_xml,err_msg);
|
||||
if(ret) {
|
||||
if((f=fopen((*output_filename).toUtf8(),"w"))!=NULL) {
|
||||
fprintf(f,"%s",output.toUtf8().constData());
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
*err_msg=tr("Unable to create output file")+" ["+strerror(errno)+"].";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
*err_msg=QObject::tr("Unable to create temporary directory.")+
|
||||
"["+err_msg2+"]";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool RDXsltEngine::transform(QString *output,const QString &src_xml,QString *err_msg)
|
||||
{
|
||||
QStringList args;
|
||||
QProcess *proc=NULL;
|
||||
|
||||
args.push_back("--encoding");
|
||||
args.push_back("utf-8");
|
||||
args.push_back(d_stylesheet_pathname);
|
||||
args.push_back("-");
|
||||
proc=new QProcess(this);
|
||||
proc->start("xsltproc",args);
|
||||
if(!proc->waitForStarted()) {
|
||||
*err_msg=tr("unable to start xsltproc(1)");
|
||||
delete proc;
|
||||
return false;
|
||||
}
|
||||
proc->write(src_xml.toUtf8());
|
||||
proc->closeWriteChannel();
|
||||
if(!proc->waitForFinished()) {
|
||||
*err_msg=tr("xsltproc(1) is apparently hung!");
|
||||
proc->kill();
|
||||
delete proc;
|
||||
return false;
|
||||
}
|
||||
if(proc->exitStatus()!=QProcess::NormalExit) {
|
||||
*err_msg=tr("xsltproc(1) crashed!");
|
||||
delete proc;
|
||||
return false;
|
||||
}
|
||||
if(proc->exitCode()!=0) {
|
||||
*err_msg=tr("xsltproc(1) returned an error")+" ["+
|
||||
proc->readAllStandardError()+"].";
|
||||
delete proc;
|
||||
return false;
|
||||
}
|
||||
*output=QString::fromUtf8(proc->readAllStandardOutput());
|
||||
delete proc;
|
||||
|
||||
return true;
|
||||
}
|
||||
48
lib/rdxsltengine.h
Normal file
48
lib/rdxsltengine.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// rdxsltengine.h
|
||||
//
|
||||
// Engine for performing XSLT transformations
|
||||
//
|
||||
// (C) Copyright 2023 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
|
||||
#ifndef RDXSLTENGINE_H
|
||||
#define RDXSLTENGINE_H
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
||||
#include <rdtempdirectory.h>
|
||||
|
||||
class RDXsltEngine : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
RDXsltEngine(const QString stylesheet_pathname,QObject *parent=0);
|
||||
~RDXsltEngine();
|
||||
QString stylesheetPathname() const;
|
||||
bool transformUrl(QString *output_filename,const QString &url,
|
||||
QString *err_msg);
|
||||
bool transformXml(QString *output_filename,const QString &src_xml,
|
||||
QString *err_msg);
|
||||
bool transform(QString *output,const QString &src_xml,QString *err_msg);
|
||||
|
||||
private:
|
||||
QList<RDTempDirectory *> d_temp_directories;
|
||||
QString d_stylesheet_pathname;
|
||||
};
|
||||
|
||||
|
||||
#endif // RDXSLTENGINE_H
|
||||
@@ -98,7 +98,7 @@ ListFeeds::ListFeeds(QWidget *parent)
|
||||
//
|
||||
// Feed List
|
||||
//
|
||||
list_feeds_view=new RDTableView(this);
|
||||
list_feeds_view=new RDFeedListView(this);
|
||||
list_feeds_model=new RDFeedListModel(true,false,this);
|
||||
list_feeds_model->setFont(font());
|
||||
list_feeds_model->setPalette(palette());
|
||||
@@ -115,6 +115,7 @@ ListFeeds::ListFeeds(QWidget *parent)
|
||||
|
||||
ListFeeds::~ListFeeds()
|
||||
{
|
||||
delete list_feeds_view;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <rddialog.h>
|
||||
#include <rdfeedlistmodel.h>
|
||||
#include <rdfeedlistview.h>
|
||||
#include <rdtableview.h>
|
||||
|
||||
class ListFeeds : public RDDialog
|
||||
@@ -51,7 +52,7 @@ class ListFeeds : public RDDialog
|
||||
|
||||
private:
|
||||
QLabel *list_box_label;
|
||||
RDTableView *list_feeds_view;
|
||||
RDFeedListView *list_feeds_view;
|
||||
RDFeedListModel *list_feeds_model;
|
||||
QPushButton *list_add_button;
|
||||
QPushButton *list_edit_button;
|
||||
|
||||
@@ -89,6 +89,12 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
|
||||
rda->ripc()->
|
||||
connectHost("localhost",RIPCD_TCP_PORT,rda->config()->password());
|
||||
|
||||
//
|
||||
// XSLT Engine (for feed reports)
|
||||
//
|
||||
cast_xslt_engine=
|
||||
new RDXsltEngine("/usr/share/rivendell/rdcastmanager-report.xsl",this);
|
||||
|
||||
//
|
||||
// Feed List
|
||||
//
|
||||
@@ -239,20 +245,18 @@ void MainWidget::copyData()
|
||||
void MainWidget::reportData()
|
||||
{
|
||||
QModelIndexList rows=cast_feed_view->selectionModel()->selectedRows();
|
||||
|
||||
if(rows.size()!=1) {
|
||||
return;
|
||||
}
|
||||
QString err_msg;
|
||||
QString url=cast_feed_model->
|
||||
data(cast_feed_model->index(rows.at(0).row(),6)).toString();
|
||||
cast_temp_directories.push_back(new RDTempDirectory("rdcastmanager-report"));
|
||||
if(!RDFeed::generateReport(url,
|
||||
"/usr/share/rivendell/rdcastmanager-report.xsl",
|
||||
"report.html",cast_temp_directories.back(),
|
||||
&err_msg)) {
|
||||
QString output_filename="report.html";
|
||||
if(cast_xslt_engine->transformUrl(&output_filename,url,&err_msg)) {
|
||||
RDWebBrowser("file://"+output_filename);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this,"RDCastManager - "+tr("Error"),err_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,9 +269,7 @@ void MainWidget::feedDoubleClickedData(const QModelIndex &index)
|
||||
|
||||
void MainWidget::quitMainWidget()
|
||||
{
|
||||
for(int i=0;i<cast_temp_directories.size();i++) {
|
||||
delete cast_temp_directories.at(i);
|
||||
}
|
||||
delete cast_xslt_engine;
|
||||
saveSettings();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <rdtreeview.h>
|
||||
#include <rdtempdirectory.h>
|
||||
#include <rdwidget.h>
|
||||
#include <rdxsltengine.h>
|
||||
|
||||
#define RDCASTMANAGER_USAGE "\n"
|
||||
|
||||
@@ -65,7 +66,7 @@ class MainWidget : public RDMainWindow
|
||||
QPushButton *cast_report_button;
|
||||
QPushButton *cast_close_button;
|
||||
bool cast_resize;
|
||||
QList<RDTempDirectory *> cast_temp_directories;
|
||||
RDXsltEngine *cast_xslt_engine;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
|
||||
#include "rdxport.h"
|
||||
|
||||
size_t __PostRss_Readfunction_Callback(char *buffer,size_t size,size_t nitems,
|
||||
void *userdata)
|
||||
size_t __PostRss_UploadFunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,void *userdata)
|
||||
{
|
||||
Xport *xport=(Xport *)userdata;
|
||||
|
||||
@@ -57,6 +57,17 @@ size_t __PostRss_Readfunction_Callback(char *buffer,size_t size,size_t nitems,
|
||||
}
|
||||
|
||||
|
||||
size_t __PostRss_DownloadFunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,void *userdata)
|
||||
{
|
||||
Xport *xport=(Xport *)userdata;
|
||||
|
||||
(xport->xport_curl_data)+=QByteArray(buffer,size*nitems);
|
||||
|
||||
return size*nitems;
|
||||
}
|
||||
|
||||
|
||||
void Xport::SavePodcast()
|
||||
{
|
||||
int cast_id=0;
|
||||
@@ -401,7 +412,7 @@ bool Xport::PostRssElemental(RDFeed *feed,const QDateTime &now,QString *err_msg)
|
||||
//
|
||||
curl_easy_setopt(curl,CURLOPT_URL,feed->feedUrl().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_UPLOAD,1);
|
||||
curl_easy_setopt(curl,CURLOPT_READFUNCTION, __PostRss_Readfunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_READFUNCTION, __PostRss_UploadFunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_READDATA,this);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
@@ -436,6 +447,117 @@ bool Xport::PostRssElemental(RDFeed *feed,const QDateTime &now,QString *err_msg)
|
||||
}
|
||||
|
||||
|
||||
void Xport::DownloadRss()
|
||||
{
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
char errstr[CURL_ERROR_SIZE];
|
||||
int feed_id=0;
|
||||
QString keyname;
|
||||
QString destpath;
|
||||
QString err_msg;
|
||||
RDFeed *feed=NULL;
|
||||
QString msg="OK";
|
||||
|
||||
QDateTime now=QDateTime::currentDateTime();
|
||||
|
||||
if(!xport_post->getValue("ID",&feed_id)) {
|
||||
XmlExit("Missing ID",400,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
feed=new RDFeed(feed_id,rda->config(),this);
|
||||
if(!feed->exists()) {
|
||||
XmlExit("No such feed",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=feed->keyName();
|
||||
|
||||
if(((!rda->user()->editPodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete feed;
|
||||
XmlExit("No such feed",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
XmlExit("unable to get CURL handle",500,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
// xport_curl_data=feed->rssXml(err_msg,now).toUtf8();
|
||||
// xport_curl_data_ptr=0;
|
||||
|
||||
//
|
||||
// Authentication Parameters
|
||||
//
|
||||
if((QUrl(feed->feedUrl()).scheme().toLower()=="sftp")&&
|
||||
(!rda->station()->sshIdentityFile().isEmpty())&&feed->purgeUseIdFile()) {
|
||||
//
|
||||
// Enable host key verification
|
||||
//
|
||||
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,0);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_USERNAME,
|
||||
feed->purgeUsername().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_SSH_PRIVATE_KEYFILE,
|
||||
rda->station()->sshIdentityFile().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_KEYPASSWD,
|
||||
feed->purgePassword().toUtf8().constData());
|
||||
rda->syslog(LOG_DEBUG,"using ssh key at \"%s\"",
|
||||
rda->station()->sshIdentityFile().toUtf8().constData());
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Disable host key verification
|
||||
//
|
||||
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,0);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_USERNAME,
|
||||
feed->purgeUsername().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_PASSWORD,
|
||||
feed->purgePassword().toUtf8().constData());
|
||||
}
|
||||
|
||||
//
|
||||
// Transfer Parameters
|
||||
//
|
||||
curl_easy_setopt(curl,CURLOPT_URL,feed->feedUrl().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_UPLOAD,0);
|
||||
xport_curl_data.clear();
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,
|
||||
__PostRss_DownloadFunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,this);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
rda->config()->userAgent().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errstr);
|
||||
|
||||
//
|
||||
// Execute it
|
||||
//
|
||||
switch((curl_err=curl_easy_perform(curl))) {
|
||||
case CURLE_OK:
|
||||
case CURLE_PARTIAL_FILE:
|
||||
feed->setLastBuildDateTime(now);
|
||||
rda->syslog(LOG_DEBUG,
|
||||
"posted RSS XML to \"%s\"",
|
||||
feed->feedUrl().toUtf8().constData());
|
||||
break;
|
||||
|
||||
default:
|
||||
rda->syslog(LOG_ERR,"RSS XML upload failed: curl error %d [%s]",
|
||||
curl_err,curl_easy_strerror(curl_err));
|
||||
err_msg+=errstr;
|
||||
break;
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
printf("Content-type: application/rss+xml; charset: UTF-8\n");
|
||||
printf("Status: 200\n\n");
|
||||
printf("%s",xport_curl_data.constData());
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
||||
|
||||
void Xport::PostRss()
|
||||
{
|
||||
int feed_id=0;
|
||||
@@ -622,7 +744,7 @@ void Xport::PostImage()
|
||||
//
|
||||
curl_easy_setopt(curl,CURLOPT_URL,desturl.toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_UPLOAD,1);
|
||||
curl_easy_setopt(curl,CURLOPT_READFUNCTION, __PostRss_Readfunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_READFUNCTION, __PostRss_UploadFunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_READDATA,this);
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
|
||||
@@ -353,6 +353,11 @@ void Xport::ripcConnectedData(bool state)
|
||||
RemovePodcast();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_DOWNLOAD_RSS:
|
||||
rda->syslog(LOG_DEBUG,"processing RDXPORT_COMMAND_DOWNLOAD_RSS");
|
||||
DownloadRss();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_POST_RSS:
|
||||
rda->syslog(LOG_DEBUG,"processing RDXPORT_COMMAND_POST_RSS");
|
||||
PostRss();
|
||||
|
||||
@@ -89,6 +89,7 @@ class Xport : public QObject
|
||||
void PostPodcast();
|
||||
void RemovePodcast();
|
||||
bool PostRssElemental(RDFeed *feed,const QDateTime &now,QString *err_msg);
|
||||
void DownloadRss();
|
||||
void PostRss();
|
||||
void RemoveRss();
|
||||
void PostImage();
|
||||
@@ -110,8 +111,11 @@ class Xport : public QObject
|
||||
QHostAddress xport_remote_address;
|
||||
QByteArray xport_curl_data;
|
||||
int xport_curl_data_ptr;
|
||||
friend size_t __PostRss_Readfunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,void *userdata);
|
||||
friend size_t __PostRss_UploadFunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,void *userdata);
|
||||
friend size_t __PostRss_DownloadFunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,
|
||||
void *userdata);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
##
|
||||
## Automake.am for rivendell/web/tests
|
||||
##
|
||||
## (C) Copyright 2010-2020 Fred Gleason <fredg@paravelsystems.com>
|
||||
## (C) Copyright 2010-2023 Fred Gleason <fredg@paravelsystems.com>
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License version 2 as
|
||||
@@ -32,6 +32,7 @@ install-exec-am:
|
||||
cp delete_audio.html $(DESTDIR)@libexecdir@
|
||||
cp deletelog.html $(DESTDIR)@libexecdir@
|
||||
cp deletepodcast.html $(DESTDIR)@libexecdir@
|
||||
cp downloadrss.html $(DESTDIR)@libexecdir@
|
||||
cp editcart.html $(DESTDIR)@libexecdir@
|
||||
cp editcut.js $(DESTDIR)@libexecdir@
|
||||
cp editcut.html $(DESTDIR)@libexecdir@
|
||||
@@ -81,6 +82,7 @@ uninstall-local:
|
||||
rm -f $(DESTDIR)@libexecdir@/delete_audio.html
|
||||
rm -f $(DESTDIR)@libexecdir@/deletelog.html
|
||||
rm -f $(DESTDIR)@libexecdir@/deletepodcast.html
|
||||
rm -f $(DESTDIR)@libexecdir@/downloadrss.html
|
||||
rm -f $(DESTDIR)@libexecdir@/editcart.html
|
||||
rm -f $(DESTDIR)@libexecdir@/editcart.js
|
||||
rm -f $(DESTDIR)@libexecdir@/editcut.html
|
||||
@@ -130,6 +132,7 @@ EXTRA_DIST = addcart.html\
|
||||
delete_audio.html\
|
||||
deletelog.html\
|
||||
deletepodcast.html\
|
||||
downloadrss.html\
|
||||
editcart.html\
|
||||
editcart.js\
|
||||
editcut.html\
|
||||
|
||||
33
web/tests/downloadrss.html
Normal file
33
web/tests/downloadrss.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rivendell DOWNLOADRSS Service Test Harness</title>
|
||||
<body>
|
||||
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="COMMAND" value="46">
|
||||
<table cellpadding="0" cellspacing="2" border="0">
|
||||
<tr>
|
||||
<td align="right">LOGIN NAME:</td>
|
||||
<td><input type="text" name="LOGIN_NAME" size="20" maxlength="255"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">PASSWORD:</td>
|
||||
<td><input type="password" name="PASSWORD" size="20" maxlength="32"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">TICKET:</td>
|
||||
<td><input type="text" name="TICKET" size="40" maxlength="40"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">ID:</td>
|
||||
<td><input type="text" name="ID" size="12" maxlength="12"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" align="right"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" align="right"><input type="submit" value="OK"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user