mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-05-29 07:02:34 +02:00
2020-09-21 Fred Gleason <fredg@paravelsystems.com>
* Added a 'PostPodcast' method to the Web API. * Added a 'RemovePodcast' method to the Web API. * Added a 'PostRss' method to the Web API. * Added a 'RemoveRss' method to the Web API. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
parent
5349a8e853
commit
5a549b7866
@ -20294,3 +20294,8 @@
|
||||
2020-09-21 Fred Gleason <fredg@paravelsystems.com>
|
||||
* Added a 'SHA1' column to the 'Podcast Item List' dialog in
|
||||
rdcastmanager(1).
|
||||
2020-09-21 Fred Gleason <fredg@paravelsystems.com>
|
||||
* Added a 'PostPodcast' method to the Web API.
|
||||
* Added a 'RemovePodcast' method to the Web API.
|
||||
* Added a 'PostRss' method to the Web API.
|
||||
* Added a 'RemoveRss' method to the Web API.
|
||||
|
@ -839,6 +839,7 @@
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Delete Podcast</code>, Feed Permission
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
A <computeroutput>404</computeroutput> error will be returned if the
|
||||
@ -847,7 +848,7 @@
|
||||
</para>
|
||||
<table xml:id="ex.delete_podcast
|
||||
" frame="all">
|
||||
<title>GetPodcast Call Fields</title>
|
||||
<title>DeletePodcast Call Fields</title>
|
||||
<tgroup cols="3" align="left" colsep="1" rowsep="1">
|
||||
<colspec colname="FIELD NAME" />
|
||||
<colspec colname="MEANING" />
|
||||
@ -1783,7 +1784,8 @@
|
||||
<title>GetPodcast</title>
|
||||
<subtitle>Get posted podcast audio</subtitle>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_GET_PODCAST</code>
|
||||
Command Code: <code>RDXPORT_COMMAND_GET_PODCAST</code>, Feed Permissions
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Edit Podcast</code>, Feed Permission
|
||||
@ -2850,6 +2852,132 @@
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>PostPodcast</title>
|
||||
<subtitle>Upload podcast audio from the audio store to the remote archive</subtitle>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_POST_PODCAST</code>
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Add Podcast</code>, Feed Permission
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
A <computeroutput>404</computeroutput> error will be returned if the
|
||||
requested podcast's parent feed is not authorized for the specified
|
||||
Rivendell user in RDAdmin->ManageUsers->PodcastFeedPermissions.
|
||||
</para>
|
||||
<table xml:id="ex.post_podcast
|
||||
" frame="all">
|
||||
<title>PostPodcast 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>
|
||||
40
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
ID
|
||||
</entry>
|
||||
<entry>
|
||||
ID of podcast item (integer)
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>PostRss</title>
|
||||
<subtitle>Upload podcast RSS XML to the remote archive</subtitle>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_POST_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.post_rss
|
||||
" frame="all">
|
||||
<title>PostRss 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>
|
||||
42
|
||||
</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>Rehash</title>
|
||||
<subtitle>Generate a SHA-1 hash for a cut and write it to the database</subtitle>
|
||||
@ -3040,6 +3168,132 @@
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>RemovePodcast</title>
|
||||
<subtitle>Delete podcast audio from the remote archive</subtitle>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_REMOVE_PODCAST</code>
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Delete Podcast</code>, Feed Permission
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
A <computeroutput>404</computeroutput> error will be returned if the
|
||||
requested podcast's parent feed is not authorized for the specified
|
||||
Rivendell user in RDAdmin->ManageUsers->PodcastFeedPermissions.
|
||||
</para>
|
||||
<table xml:id="ex.remove_podcast
|
||||
" frame="all">
|
||||
<title>RemovePodcast 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>
|
||||
41
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
ID
|
||||
</entry>
|
||||
<entry>
|
||||
ID of podcast item (integer)
|
||||
</entry>
|
||||
<entry>
|
||||
Mandatory
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>RemoveRss</title>
|
||||
<subtitle>Remove podcast RSS XML from the remote archive</subtitle>
|
||||
<para>
|
||||
Command Code: <code>RDXPORT_COMMAND_REMOVE_RSS</code>
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Delete 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.remove_rss
|
||||
" frame="all">
|
||||
<title>RemoveRss 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>
|
||||
43
|
||||
</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>SaveFile</title>
|
||||
<subtitle>
|
||||
@ -3658,6 +3912,7 @@
|
||||
</para>
|
||||
<para>
|
||||
Required User Permissions: <code>Create Podcast</code>, Feed Permission
|
||||
or <code>Administer System</code>
|
||||
</para>
|
||||
<para>
|
||||
A <computeroutput>404</computeroutput> error will be returned if the
|
||||
|
462
lib/rdfeed.cpp
462
lib/rdfeed.cpp
@ -48,23 +48,6 @@
|
||||
#include "rdwavefile.h"
|
||||
#include "rdxport_interface.h"
|
||||
|
||||
size_t __RDFeed_Readfunction_Callback(char *buffer,size_t size,size_t nitems,
|
||||
void *userdata)
|
||||
{
|
||||
RDFeed *feed=(RDFeed *)userdata;
|
||||
|
||||
int curlsize=size*nitems;
|
||||
int segsize=feed->feed_xml.size()-feed->feed_xml_ptr;
|
||||
if(segsize<curlsize) {
|
||||
curlsize=segsize;
|
||||
}
|
||||
memcpy(buffer,feed->feed_xml.mid(feed->feed_xml_ptr,curlsize).constData(),
|
||||
curlsize);
|
||||
feed->feed_xml_ptr+=curlsize;
|
||||
return curlsize;
|
||||
}
|
||||
|
||||
|
||||
RDFeed::RDFeed(const QString &keyname,RDConfig *config,QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
@ -809,7 +792,7 @@ bool RDFeed::deleteImage(int img_id,QString *err_msg)
|
||||
}
|
||||
|
||||
|
||||
QString RDFeed::audioUrl(const QString &cgi_hostname,unsigned cast_id)
|
||||
QString RDFeed::audioUrl(unsigned cast_id)
|
||||
{
|
||||
RDPodcast *cast=new RDPodcast(feed_config,cast_id);
|
||||
QUrl url(baseUrl(cast->feedId()));
|
||||
@ -844,81 +827,70 @@ QString RDFeed::imageUrl(int img_id) const
|
||||
|
||||
bool RDFeed::postXml(QString *err_msg)
|
||||
{
|
||||
long response_code;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
bool ret=false;
|
||||
char errstr[CURL_ERROR_SIZE];
|
||||
QDateTime now=QDateTime::currentDateTime();
|
||||
struct curl_httppost *first=NULL;
|
||||
struct curl_httppost *last=NULL;
|
||||
|
||||
//
|
||||
// Generate POST Data
|
||||
//
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"COMMAND",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
(const char *)QString().sprintf("%u",RDXPORT_COMMAND_POST_RSS),
|
||||
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,
|
||||
(const char *)QString().sprintf("%u",feed_id),
|
||||
CURLFORM_END);
|
||||
|
||||
//
|
||||
// Set up the transfer
|
||||
//
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
*err_msg=tr("Unable to get CURL handle.");
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,stdout);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent());
|
||||
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());
|
||||
|
||||
//
|
||||
// Send it
|
||||
//
|
||||
if((curl_err=curl_easy_perform(curl))!=CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
|
||||
feed_xml=rssXml(err_msg,now).toUtf8();
|
||||
feed_xml_ptr=0;
|
||||
|
||||
//
|
||||
// Authentication
|
||||
// Clean up
|
||||
//
|
||||
if((QUrl(feedUrl()).scheme().toLower()=="sftp")&&
|
||||
(!rda->station()->sshIdentityFile().isEmpty())&&purgeUseIdFile()) {
|
||||
curl_easy_setopt(curl,CURLOPT_USERNAME,
|
||||
purgeUsername().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_SSH_PRIVATE_KEYFILE,
|
||||
rda->station()->sshIdentityFile().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_KEYPASSWD,
|
||||
purgePassword().toUtf8().constData());
|
||||
}
|
||||
else {
|
||||
curl_easy_setopt(curl,CURLOPT_USERNAME,
|
||||
purgeUsername().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_PASSWORD,
|
||||
purgePassword().toUtf8().constData());
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_URL,feedUrl().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_UPLOAD,1);
|
||||
curl_easy_setopt(curl,CURLOPT_READFUNCTION, __RDFeed_Readfunction_Callback);
|
||||
curl_easy_setopt(curl,CURLOPT_READDATA,this);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent().utf8());
|
||||
curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errstr);
|
||||
/*
|
||||
curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
|
||||
curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTION,UploadErrorCallback);
|
||||
*/
|
||||
switch((curl_err=curl_easy_perform(curl))) {
|
||||
case CURLE_OK:
|
||||
case CURLE_PARTIAL_FILE:
|
||||
setLastBuildDateTime(now);
|
||||
ret=true;
|
||||
break;
|
||||
|
||||
default:
|
||||
*err_msg=errstr;
|
||||
ret=false;
|
||||
break;
|
||||
}
|
||||
curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
|
||||
//
|
||||
// Update Enclosing Superfeeds
|
||||
// Process the results
|
||||
//
|
||||
QStringList superfeeds=isSubfeedOf();
|
||||
for(int i=0;i<superfeeds.size();i++) {
|
||||
QString err_msg2;
|
||||
RDFeed *feed=new RDFeed(superfeeds.at(i),feed_config,this);
|
||||
if(!feed->postXml(&err_msg2)) {
|
||||
*err_msg+="\n"+err_msg2;
|
||||
}
|
||||
delete feed;
|
||||
if((response_code<200)||(response_code>299)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -936,8 +908,74 @@ bool RDFeed::postXmlConditional(const QString &caption,QWidget *widget)
|
||||
}
|
||||
|
||||
|
||||
bool RDFeed::deleteXml(QString *err_msg)
|
||||
bool RDFeed::removeRss(QString *err_msg)
|
||||
{
|
||||
long response_code;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
struct curl_httppost *first=NULL;
|
||||
struct curl_httppost *last=NULL;
|
||||
|
||||
//
|
||||
// Generate POST Data
|
||||
//
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"COMMAND",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
(const char *)QString().sprintf("%u",RDXPORT_COMMAND_REMOVE_RSS),
|
||||
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,
|
||||
(const char *)QString().sprintf("%u",feed_id),
|
||||
CURLFORM_END);
|
||||
|
||||
//
|
||||
// Set up the transfer
|
||||
//
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,stdout);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent());
|
||||
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());
|
||||
|
||||
//
|
||||
// Send it
|
||||
//
|
||||
if((curl_err=curl_easy_perform(curl))!=CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
/*
|
||||
RDDelete::ErrorCode conv_err;
|
||||
RDDelete *conv=new RDDelete(rda->config());
|
||||
if(!conv->urlIsSupported(feedUrl())) {
|
||||
@ -954,6 +992,7 @@ bool RDFeed::deleteXml(QString *err_msg)
|
||||
delete conv;
|
||||
|
||||
return conv_err==RDDelete::ErrorOk;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -995,11 +1034,7 @@ unsigned RDFeed::postCut(const QString &cutname,Error *err)
|
||||
QString err_msg;
|
||||
QString tmpfile;
|
||||
QString destfile;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
RDPodcast *cast=NULL;
|
||||
RDUpload *upload=NULL;
|
||||
RDUpload::ErrorCode upload_err;
|
||||
RDAudioConvert::ErrorCode audio_conv_err;
|
||||
RDAudioExport::ErrorCode export_err;
|
||||
|
||||
@ -1060,47 +1095,23 @@ unsigned RDFeed::postCut(const QString &cutname,Error *err)
|
||||
}
|
||||
delete settings;
|
||||
delete conv;
|
||||
|
||||
//
|
||||
// Upload
|
||||
//
|
||||
emit postProgressChanged(2);
|
||||
QFile file(tmpfile);
|
||||
int length=file.size();
|
||||
unsigned cast_id=CreateCast(&destfile,length,cut->length());
|
||||
delete cut;
|
||||
cast=new RDPodcast(feed_config,cast_id);
|
||||
upload=new RDUpload(rda->config(),this);
|
||||
upload->setSourceFile(tmpfile);
|
||||
upload->setDestinationUrl(purgeUrl()+"/"+cast->audioFilename());
|
||||
switch((upload_err=upload->runUpload(purgeUsername(),purgePassword(),
|
||||
rda->station()->sshIdentityFile(),
|
||||
purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))) {
|
||||
case RDUpload::ErrorOk:
|
||||
*err=RDFeed::ErrorOk;
|
||||
break;
|
||||
|
||||
default:
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
sql=QString().sprintf("delete from PODCASTS where ID=%u",cast_id);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
delete upload;
|
||||
delete cast;
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(5);
|
||||
return 0;
|
||||
}
|
||||
emit postProgressChanged(3);
|
||||
postProgressChanged(2);
|
||||
|
||||
//
|
||||
// Save to Audio Store
|
||||
//
|
||||
QFile file(tmpfile);
|
||||
int length=file.size();
|
||||
unsigned cast_id=CreateCast(&destfile,length,cut->length());
|
||||
cast=new RDPodcast(feed_config,cast_id);
|
||||
SavePodcast(cast_id,tmpfile);
|
||||
unlink(tmpfile);
|
||||
delete upload;
|
||||
|
||||
//
|
||||
// Upload to remote archive
|
||||
//
|
||||
PostPodcast(cast_id);
|
||||
postProgressChanged(3);
|
||||
|
||||
//
|
||||
// Set default cast parameters
|
||||
@ -1109,11 +1120,14 @@ unsigned RDFeed::postCut(const QString &cutname,Error *err)
|
||||
cast->setItemTitle(cart->title());
|
||||
cast->setItemImageId(defaultItemImageId());
|
||||
delete cart;
|
||||
delete cut;
|
||||
delete cast;
|
||||
|
||||
emit postProgressChanged(4);
|
||||
postXml(&err_msg);
|
||||
|
||||
//
|
||||
// Update posted XML
|
||||
//
|
||||
postXml(&err_msg);
|
||||
emit postProgressChanged(5);
|
||||
|
||||
return cast_id;
|
||||
@ -1123,20 +1137,16 @@ unsigned RDFeed::postCut(const QString &cutname,Error *err)
|
||||
unsigned RDFeed::postFile(const QString &srcfile,Error *err)
|
||||
{
|
||||
QString err_msg;
|
||||
QString sql;
|
||||
RDSqlQuery *q;
|
||||
QString cmd;
|
||||
QString tmpfile;
|
||||
QString tmpfile2;
|
||||
QString destfile;
|
||||
int time_length=0;
|
||||
RDUpload *upload=NULL;
|
||||
RDUpload::ErrorCode upload_err;
|
||||
RDWaveFile *wave=NULL;
|
||||
RDWaveData wavedata;
|
||||
unsigned audio_time=0;
|
||||
|
||||
emit postProgressRangeChanged(0,4);
|
||||
emit postProgressRangeChanged(0,6);
|
||||
emit postProgressChanged(0);
|
||||
|
||||
//
|
||||
@ -1153,7 +1163,6 @@ unsigned RDFeed::postFile(const QString &srcfile,Error *err)
|
||||
settings->setBitRate(uploadBitRate());
|
||||
settings->setNormalizationLevel(normalizeLevel()/100);
|
||||
conv->setDestinationSettings(settings);
|
||||
|
||||
emit postProgressChanged(1);
|
||||
|
||||
switch(conv->convert()) {
|
||||
@ -1171,7 +1180,7 @@ unsigned RDFeed::postFile(const QString &srcfile,Error *err)
|
||||
delete conv;
|
||||
*err=RDFeed::ErrorUnsupportedType;
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(4);
|
||||
emit postProgressChanged(6);
|
||||
return 0;
|
||||
|
||||
case RDAudioConvert::ErrorNoSource:
|
||||
@ -1187,56 +1196,30 @@ unsigned RDFeed::postFile(const QString &srcfile,Error *err)
|
||||
delete conv;
|
||||
*err=RDFeed::ErrorGeneral;
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(4);
|
||||
emit postProgressChanged(6);
|
||||
return 0;
|
||||
}
|
||||
delete settings;
|
||||
delete conv;
|
||||
|
||||
//
|
||||
// Upload
|
||||
//
|
||||
emit postProgressChanged(2);
|
||||
|
||||
QFile file(tmpfile);
|
||||
int length=file.size();
|
||||
|
||||
unsigned cast_id=CreateCast(&destfile,length,time_length);
|
||||
RDPodcast *cast=new RDPodcast(feed_config,cast_id);
|
||||
upload=new RDUpload(rda->config(),this);
|
||||
upload->setSourceFile(tmpfile);
|
||||
upload->setDestinationUrl(purgeUrl()+"/"+cast->audioFilename());
|
||||
switch((upload_err=upload->runUpload(purgeUsername(),purgePassword(),
|
||||
rda->station()->sshIdentityFile(),
|
||||
purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))) {
|
||||
case RDUpload::ErrorOk:
|
||||
sql=QString().sprintf("update PODCASTS set AUDIO_TIME=%u where ID=%u",
|
||||
audio_time,cast_id);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
break;
|
||||
|
||||
default:
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
sql=QString().sprintf("delete from PODCASTS where ID=%u",cast_id);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
delete upload;
|
||||
delete cast;
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(4);
|
||||
return 0;
|
||||
}
|
||||
delete upload;
|
||||
|
||||
//
|
||||
// Save to Audio Store
|
||||
//
|
||||
QFile file(tmpfile);
|
||||
int length=file.size();
|
||||
unsigned cast_id=CreateCast(&destfile,length,time_length);
|
||||
RDPodcast *cast=new RDPodcast(feed_config,cast_id);
|
||||
SavePodcast(cast_id,tmpfile);
|
||||
unlink(QString(tmpfile)+".wav");
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(3);
|
||||
|
||||
//
|
||||
// Upload to remote archive
|
||||
//
|
||||
PostPodcast(cast_id);
|
||||
postProgressChanged(4);
|
||||
|
||||
//
|
||||
// Set default cast parameters
|
||||
@ -1247,13 +1230,17 @@ unsigned RDFeed::postFile(const QString &srcfile,Error *err)
|
||||
else {
|
||||
cast->setItemTitle(srcfile.split("/").last());
|
||||
}
|
||||
cast->setAudioTime(audio_time);
|
||||
cast->setItemImageId(defaultItemImageId());
|
||||
delete cast;
|
||||
emit postProgressChanged(5);
|
||||
|
||||
emit postProgressChanged(3);
|
||||
//
|
||||
//
|
||||
// Update posted XML
|
||||
//
|
||||
postXml(&err_msg);
|
||||
|
||||
emit postProgressChanged(4);
|
||||
emit postProgressChanged(6);
|
||||
|
||||
*err=RDFeed::ErrorOk;
|
||||
return cast_id;
|
||||
@ -1264,17 +1251,17 @@ unsigned RDFeed::postLog(const QString &logname,const QTime &start_time,
|
||||
bool stop_at_stop,int start_line,int end_line,
|
||||
RDFeed::Error *err)
|
||||
{
|
||||
QString sql;
|
||||
RDSqlQuery *q=NULL;
|
||||
QString tmpfile;
|
||||
QString destfile;
|
||||
QString err_msg;
|
||||
RDUpload *upload=NULL;
|
||||
RDUpload::ErrorCode upload_err;
|
||||
RDRenderer *renderer=NULL;
|
||||
RDSettings *settings=NULL;
|
||||
RDLogEvent *log_event=NULL;
|
||||
|
||||
feed_render_start_line=start_line;
|
||||
feed_render_end_line=end_line;
|
||||
|
||||
emit postProgressRangeChanged(0,4+(end_line-start_line));
|
||||
emit postProgressChanged(0);
|
||||
|
||||
//
|
||||
@ -1288,8 +1275,6 @@ unsigned RDFeed::postLog(const QString &logname,const QTime &start_time,
|
||||
return 0;
|
||||
}
|
||||
|
||||
emit postProgressRangeChanged(0,3+log_event->size());
|
||||
|
||||
//
|
||||
// Render Log
|
||||
//
|
||||
@ -1301,7 +1286,6 @@ unsigned RDFeed::postLog(const QString &logname,const QTime &start_time,
|
||||
settings->setSampleRate(uploadSampleRate());
|
||||
settings->setBitRate(uploadBitRate());
|
||||
settings->setNormalizationLevel(normalizeLevel()/100);
|
||||
|
||||
renderer=new RDRenderer(this);
|
||||
connect(renderer,SIGNAL(progressMessageSent(const QString &)),
|
||||
this,SLOT(renderMessage(const QString &)));
|
||||
@ -1318,52 +1302,24 @@ unsigned RDFeed::postLog(const QString &logname,const QTime &start_time,
|
||||
return 0;
|
||||
}
|
||||
delete renderer;
|
||||
|
||||
emit postProgressChanged(1+log_event->size());
|
||||
emit postProgressChanged(1+(end_line-start_line));
|
||||
|
||||
//
|
||||
// Upload Rendered File
|
||||
// Save to Audio Store
|
||||
//
|
||||
QFile f(tmpfile);
|
||||
unsigned cast_id=
|
||||
CreateCast(&destfile,f.size(),log_event->length(0,log_event->size()));
|
||||
RDPodcast *cast=new RDPodcast(feed_config,cast_id);
|
||||
upload=new RDUpload(rda->config(),this);
|
||||
upload->setSourceFile(tmpfile);
|
||||
upload->setDestinationUrl(purgeUrl()+"/"+cast->audioFilename());
|
||||
switch((upload_err=upload->runUpload(purgeUsername(),purgePassword(),
|
||||
rda->station()->sshIdentityFile(),
|
||||
purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))) {
|
||||
case RDUpload::ErrorOk:
|
||||
sql=QString().sprintf("update PODCASTS set AUDIO_TIME=%u where ID=%u",
|
||||
log_event->length(0,log_event->size()),cast_id);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
break;
|
||||
|
||||
default:
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
sql=QString().sprintf("delete from PODCASTS where ID=%u",cast_id);
|
||||
q=new RDSqlQuery(sql);
|
||||
delete q;
|
||||
delete upload;
|
||||
delete cast;
|
||||
delete settings;
|
||||
delete log_event;
|
||||
*err=RDFeed::ErrorUploadFailed;
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(3+log_event->size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
emit postProgressChanged(2+log_event->size());
|
||||
|
||||
//
|
||||
// Save to Audio Store
|
||||
//
|
||||
SavePodcast(cast_id,tmpfile);
|
||||
unlink(tmpfile);
|
||||
emit postProgressChanged(2+(end_line-start_line));
|
||||
|
||||
//
|
||||
// Save to remote archive
|
||||
//
|
||||
PostPodcast(cast_id);
|
||||
emit postProgressChanged(3+(end_line-start_line));
|
||||
|
||||
//
|
||||
// Set default cast parameters
|
||||
@ -1376,16 +1332,14 @@ unsigned RDFeed::postLog(const QString &logname,const QTime &start_time,
|
||||
cast->setItemTitle(log->description());
|
||||
}
|
||||
cast->setItemImageId(defaultItemImageId());
|
||||
cast->setAudioTime(log_event->length(start_line,1+end_line));
|
||||
delete log;
|
||||
|
||||
postXml(&err_msg);
|
||||
|
||||
*err=RDFeed::ErrorOk;
|
||||
|
||||
emit postProgressChanged(3+log_event->size());
|
||||
emit postProgressChanged(4+(end_line-start_line));
|
||||
|
||||
delete cast;
|
||||
delete upload;
|
||||
delete settings;
|
||||
delete log_event;
|
||||
unlink(tmpfile);
|
||||
@ -1683,7 +1637,9 @@ void RDFeed::renderMessage(const QString &msg)
|
||||
|
||||
void RDFeed::renderLineStartedData(int lineno,int total_lines)
|
||||
{
|
||||
emit postProgressChanged(lineno+1);
|
||||
if((lineno>=feed_render_start_line)&&(lineno<=feed_render_end_line)) {
|
||||
emit postProgressChanged(1+(lineno-feed_render_start_line));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1761,6 +1717,75 @@ bool RDFeed::SavePodcast(unsigned cast_id,const QString &src_filename) const
|
||||
}
|
||||
|
||||
|
||||
bool RDFeed::PostPodcast(unsigned cast_id) const
|
||||
{
|
||||
long response_code;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
struct curl_httppost *first=NULL;
|
||||
struct curl_httppost *last=NULL;
|
||||
|
||||
//
|
||||
// Generate POST Data
|
||||
//
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"COMMAND",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
(const char *)QString().sprintf("%u",RDXPORT_COMMAND_POST_PODCAST),
|
||||
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,
|
||||
(const char *)QString().sprintf("%u",cast_id),
|
||||
CURLFORM_END);
|
||||
|
||||
//
|
||||
// Set up the transfer
|
||||
//
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,stdout);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent());
|
||||
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());
|
||||
|
||||
//
|
||||
// Send it
|
||||
//
|
||||
if((curl_err=curl_easy_perform(curl))!=CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
unsigned RDFeed::CreateCast(QString *filename,int bytes,int msecs) const
|
||||
{
|
||||
QString sql;
|
||||
@ -1924,8 +1949,7 @@ QString RDFeed::ResolveItemWildcards(const QString &tmplt,RDSqlQuery *item_q,
|
||||
}
|
||||
ret.replace("%ITEM_EXPLICIT%",explicit_str);
|
||||
ret.replace("%ITEM_AUDIO_URL%",
|
||||
RDXmlEscape(audioUrl(feed_cgi_hostname,
|
||||
item_q->value(14).toUInt())));
|
||||
RDXmlEscape(audioUrl(item_q->value(14).toUInt())));
|
||||
ret.replace("%ITEM_AUDIO_LENGTH%",item_q->value(11).toString());
|
||||
ret.replace("%ITEM_AUDIO_TIME%",
|
||||
RDGetTimeLength(item_q->value(12).toInt(),false,false));
|
||||
|
10
lib/rdfeed.h
10
lib/rdfeed.h
@ -132,11 +132,12 @@ class RDFeed : public QObject
|
||||
int importImageFile(const QString &pathname,QString *err_msg,
|
||||
QString desc="") const;
|
||||
bool deleteImage(int img_id,QString *err_msg);
|
||||
QString audioUrl(const QString &cgi_hostname,unsigned cast_id);
|
||||
QString audioUrl(unsigned cast_id);
|
||||
QString imageUrl(int img_id) const;
|
||||
bool postXml(QString *err_msg);
|
||||
bool postXmlConditional(const QString &caption,QWidget *widget);
|
||||
bool deleteXml(QString *err_msg);
|
||||
//bool deleteXml(QString *err_msg);
|
||||
bool removeRss(QString *err_msg);
|
||||
bool deleteImages(QString *err_msg);
|
||||
unsigned postCut(const QString &cutname,Error *err);
|
||||
unsigned postFile(const QString &srcfile,Error *err);
|
||||
@ -161,6 +162,7 @@ class RDFeed : public QObject
|
||||
|
||||
private:
|
||||
bool SavePodcast(unsigned cast_id,const QString &src_filename) const;
|
||||
bool PostPodcast(unsigned cast_id) const;
|
||||
unsigned CreateCast(QString *filename,int bytes,int msecs) const;
|
||||
QString ResolveChannelWildcards(const QString &tmplt,RDSqlQuery *chan_q,
|
||||
const QDateTime &build_datetime);
|
||||
@ -178,8 +180,8 @@ class RDFeed : public QObject
|
||||
RDConfig *feed_config;
|
||||
QByteArray feed_xml;
|
||||
int feed_xml_ptr;
|
||||
friend size_t __RDFeed_Readfunction_Callback(char *buffer,size_t size,
|
||||
size_t nitems,void *userdata);
|
||||
int feed_render_start_line;
|
||||
int feed_render_end_line;
|
||||
};
|
||||
|
||||
|
||||
|
@ -362,30 +362,12 @@ void RDPodcast::setStatus(RDPodcast::Status status)
|
||||
}
|
||||
|
||||
|
||||
bool RDPodcast::removeAudio(RDFeed *feed,QString *err_text,bool log_debug) const
|
||||
bool RDPodcast::dropAudio(RDFeed *feed,QString *err_text,bool log_debug) const
|
||||
{
|
||||
RDDelete::ErrorCode conv_err;
|
||||
QUrl url(feed->purgeUrl()+"/"+audioFilename());
|
||||
RDDelete *conv=new RDDelete(rda->config());
|
||||
if(!conv->urlIsSupported(url)) {
|
||||
*err_text="unsupported url scheme";
|
||||
delete conv;
|
||||
if(!RemovePodcast(podcast_id)) {
|
||||
return false;
|
||||
}
|
||||
conv->setTargetUrl(url);
|
||||
conv_err=conv->runDelete(feed->purgeUsername(),feed->purgePassword(),
|
||||
rda->station()->sshIdentityFile(),
|
||||
feed->purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData());
|
||||
*err_text=RDDelete::errorText(conv_err);
|
||||
delete conv;
|
||||
|
||||
//
|
||||
// Delete from Audio Store
|
||||
//
|
||||
DeletePodcast(id());
|
||||
|
||||
return conv_err==RDDelete::ErrorOk;
|
||||
return DeletePodcast(podcast_id);
|
||||
}
|
||||
|
||||
|
||||
@ -472,6 +454,75 @@ bool RDPodcast::DeletePodcast(unsigned cast_id) const
|
||||
}
|
||||
|
||||
|
||||
bool RDPodcast::RemovePodcast(unsigned cast_id) const
|
||||
{
|
||||
long response_code;
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
struct curl_httppost *first=NULL;
|
||||
struct curl_httppost *last=NULL;
|
||||
|
||||
//
|
||||
// Generate POST Data
|
||||
//
|
||||
curl_formadd(&first,&last,CURLFORM_PTRNAME,"COMMAND",
|
||||
CURLFORM_COPYCONTENTS,
|
||||
(const char *)QString().sprintf("%u",RDXPORT_COMMAND_REMOVE_PODCAST),
|
||||
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,
|
||||
(const char *)QString().sprintf("%u",cast_id),
|
||||
CURLFORM_END);
|
||||
|
||||
//
|
||||
// Set up the transfer
|
||||
//
|
||||
if((curl=curl_easy_init())==NULL) {
|
||||
curl_formfree(first);
|
||||
return false;
|
||||
}
|
||||
curl_easy_setopt(curl,CURLOPT_WRITEDATA,stdout);
|
||||
curl_easy_setopt(curl,CURLOPT_HTTPPOST,first);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent());
|
||||
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());
|
||||
|
||||
//
|
||||
// Send it
|
||||
//
|
||||
if((curl_err=curl_easy_perform(curl))!=CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
curl_formfree(first);
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void RDPodcast::SetRow(const QString ¶m,int value) const
|
||||
{
|
||||
QString sql;
|
||||
|
@ -74,7 +74,7 @@ class RDPodcast
|
||||
void setExpirationDateTime(const QDateTime &dt) const;
|
||||
RDPodcast::Status status() const;
|
||||
void setStatus(RDPodcast::Status status);
|
||||
bool removeAudio(RDFeed *feed,QString *err_text,bool log_debug) const;
|
||||
bool dropAudio(RDFeed *feed,QString *err_text,bool log_debug) const;
|
||||
static QString guid(const QString &url,const QString &filename,
|
||||
unsigned feed_id,unsigned cast_id);
|
||||
static QString guid(const QString &full_url,
|
||||
@ -82,6 +82,7 @@ class RDPodcast
|
||||
|
||||
private:
|
||||
bool DeletePodcast(unsigned cast_id) const;
|
||||
bool RemovePodcast(unsigned cast_id) const;
|
||||
void SetRow(const QString ¶m,int value) const;
|
||||
void SetRow(const QString ¶m,const QString &value) const;
|
||||
void SetRow(const QString ¶m,const QDateTime &datetime,const QString &value) const;
|
||||
|
@ -60,6 +60,10 @@
|
||||
#define RDXPORT_COMMAND_GET_PODCAST 37
|
||||
#define RDXPORT_COMMAND_SAVE_PODCAST 38
|
||||
#define RDXPORT_COMMAND_DELETE_PODCAST 39
|
||||
#define RDXPORT_COMMAND_POST_PODCAST 40
|
||||
#define RDXPORT_COMMAND_REMOVE_PODCAST 41
|
||||
#define RDXPORT_COMMAND_POST_RSS 42
|
||||
#define RDXPORT_COMMAND_REMOVE_RSS 43
|
||||
|
||||
|
||||
#endif // RDXPORT_INTERFACE_H
|
||||
|
@ -72,6 +72,14 @@ ListFeeds::ListFeeds(QWidget *parent)
|
||||
list_delete_button->setText(tr("&Delete"));
|
||||
connect(list_delete_button,SIGNAL(clicked()),this,SLOT(deleteData()));
|
||||
|
||||
//
|
||||
// Repost Button
|
||||
//
|
||||
list_repost_button=new QPushButton(this);
|
||||
list_repost_button->setFont(buttonFont());
|
||||
list_repost_button->setText(tr("&Repost"));
|
||||
connect(list_repost_button,SIGNAL(clicked()),this,SLOT(repostData()));
|
||||
|
||||
//
|
||||
// Close Button
|
||||
//
|
||||
@ -118,7 +126,7 @@ ListFeeds::~ListFeeds()
|
||||
|
||||
QSize ListFeeds::sizeHint() const
|
||||
{
|
||||
return QSize(800,300);
|
||||
return QSize(800,390);
|
||||
}
|
||||
|
||||
|
||||
@ -231,7 +239,7 @@ void ListFeeds::deleteData()
|
||||
pd->setValue(pd->value()+1);
|
||||
qApp->processEvents();
|
||||
cast=new RDPodcast(rda->config(),q->value(0).toUInt());
|
||||
cast->removeAudio(feed,&errs,rda->config()->logXloadDebugData());
|
||||
cast->dropAudio(feed,&errs,rda->config()->logXloadDebugData());
|
||||
delete cast;
|
||||
}
|
||||
delete q;
|
||||
@ -239,7 +247,7 @@ void ListFeeds::deleteData()
|
||||
//
|
||||
// Delete Remote XML
|
||||
//
|
||||
if(!feed->deleteXml(&errs)) {
|
||||
if(!feed->removeRss(&errs)) {
|
||||
QMessageBox::warning(this,"RDAdmin - "+tr("Warning"),
|
||||
tr("Failed to delete remote feed XML.")+
|
||||
"["+errs+"].");
|
||||
@ -293,6 +301,11 @@ void ListFeeds::doubleClickedData(Q3ListViewItem *item,const QPoint &pt,
|
||||
}
|
||||
|
||||
|
||||
void ListFeeds::repostData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ListFeeds::closeData()
|
||||
{
|
||||
done(0);
|
||||
@ -304,6 +317,7 @@ void ListFeeds::resizeEvent(QResizeEvent *e)
|
||||
list_add_button->setGeometry(size().width()-90,30,80,50);
|
||||
list_edit_button->setGeometry(size().width()-90,90,80,50);
|
||||
list_delete_button->setGeometry(size().width()-90,150,80,50);
|
||||
list_repost_button->setGeometry(size().width()-90,240,80,50);
|
||||
list_close_button->setGeometry(size().width()-90,size().height()-60,80,50);
|
||||
list_feeds_view->setGeometry(10,30,size().width()-120,size().height()-40);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ class ListFeeds : public RDDialog
|
||||
void editData();
|
||||
void deleteData();
|
||||
void doubleClickedData(Q3ListViewItem *item,const QPoint &pt,int col);
|
||||
void repostData();
|
||||
void closeData();
|
||||
|
||||
protected:
|
||||
@ -52,6 +53,7 @@ class ListFeeds : public RDDialog
|
||||
QPushButton *list_add_button;
|
||||
QPushButton *list_edit_button;
|
||||
QPushButton *list_delete_button;
|
||||
QPushButton *list_repost_button;
|
||||
QPushButton *list_close_button;
|
||||
};
|
||||
|
||||
|
@ -5208,6 +5208,10 @@ Stále ještě jej chcete smazat?</translation>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished">&Vyvěsit znovu</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -4974,6 +4974,10 @@ Wollen Sie ihn immernoch löschen?</translation>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -5171,6 +5171,10 @@ Do you still want to delete it?</source>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished">&Republicar</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -4120,6 +4120,10 @@ Permissions</source>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -4835,6 +4835,10 @@ Klikk på "Lisens"-knappen for fleire opplysningar.</translation>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -4835,6 +4835,10 @@ Klikk på "Lisens"-knappen for fleire opplysningar.</translation>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -4958,6 +4958,10 @@ Você ainda quer Deletar?</translation>
|
||||
<source>Public URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Repost</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListGpis</name>
|
||||
|
@ -390,10 +390,9 @@ void ListCasts::deleteData()
|
||||
sleep(1);
|
||||
qApp->processEvents();
|
||||
RDPodcast *cast=new RDPodcast(rda->config(),item->id());
|
||||
if(!cast->removeAudio(list_feed,&err_text,
|
||||
rda->config()->logXloadDebugData())) {
|
||||
if(!cast->dropAudio(list_feed,&err_text,rda->config()->logXloadDebugData())) {
|
||||
if(QMessageBox::warning(this,"RDCastManager - "+tr("Remote Error"),
|
||||
tr("Unable to delete remote audio!\n")+
|
||||
tr("Unable to drop remote audio!\n")+
|
||||
tr("The server said: \"")+err_text+"\".\n\n"+
|
||||
tr("Continue deleting cast?"),
|
||||
QMessageBox::Yes,QMessageBox::No)==QMessageBox::No) {
|
||||
|
@ -330,7 +330,7 @@ Podcast trotzdem löschen?</translation>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation>Nelze smazat soubory se zvukem na jiném serveru!</translation>
|
||||
<translation type="obsolete">Nelze smazat soubory se zvukem na jiném serveru!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
@ -414,6 +414,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -315,7 +315,7 @@ Podcast trotzdem löschen?</translation>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation>Kann die Audiodatei(en) auf dem anderen Server nicht löschen!</translation>
|
||||
<translation type="obsolete">Kann die Audiodatei(en) auf dem anderen Server nicht löschen!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
@ -399,6 +399,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -269,7 +269,7 @@ Suscripción</translation>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation>¡No fue posible eliminar audio remoto!
|
||||
<translation type="obsolete">¡No fue posible eliminar audio remoto!
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
@ -354,6 +354,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -168,11 +168,6 @@ Car&t/Cut</source>
|
||||
<source>Remote Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@ -255,6 +250,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -299,11 +299,6 @@ Vil du halda fram med å sletta podkasten?</translation>
|
||||
<source>Posting Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@ -386,6 +381,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -299,11 +299,6 @@ Vil du halda fram med å sletta podkasten?</translation>
|
||||
<source>Posting Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@ -386,6 +381,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -277,11 +277,6 @@ Continuar deletando cast?</translation>
|
||||
<source>Never</source>
|
||||
<translation>Nunca</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to delete remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The server said: "</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@ -364,6 +359,11 @@ Log</source>
|
||||
<source>[none]</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to drop remote audio!
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogDialog</name>
|
||||
|
@ -148,7 +148,7 @@ void MainObject::ProcessFeed(const QString &key_name)
|
||||
bool deleted=false;
|
||||
if(q->value(1).toDateTime()<now) { // Delete expired cast
|
||||
RDPodcast *cast=new RDPodcast(rda->config(),q->value(0).toUInt());
|
||||
if(!cast->removeAudio(feed,&err_msg,false)) {
|
||||
if(!cast->dropAudio(feed,&err_msg,false)) {
|
||||
rda->syslog(LOG_WARNING,
|
||||
"audio purge failed for cast %u [%s] on feed \"%s\" [%s]",
|
||||
q->value(0).toUInt(),
|
||||
|
@ -1437,7 +1437,7 @@ void MainObject::DeleteCast()
|
||||
|
||||
RDFeed *feed=new RDFeed(cast_feed_id,rda->config());
|
||||
RDPodcast *cast=new RDPodcast(rda->config(),cast_cast_id);
|
||||
cast->removeAudio(feed,&errs,rda->config()->logXloadDebugData());
|
||||
cast->dropAudio(feed,&errs,rda->config()->logXloadDebugData());
|
||||
delete cast;
|
||||
delete feed;
|
||||
|
||||
|
@ -24,18 +24,40 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <rdapplication.h>
|
||||
#include <rdconf.h>
|
||||
#include <rddelete.h>
|
||||
#include <rdescape_string.h>
|
||||
#include <rdfeed.h>
|
||||
#include <rdformpost.h>
|
||||
#include <rdgroup.h>
|
||||
#include <rdhash.h>
|
||||
#include <rdpodcast.h>
|
||||
#include <rdupload.h>
|
||||
#include <rduser.h>
|
||||
#include <rdweb.h>
|
||||
|
||||
#include "rdxport.h"
|
||||
|
||||
size_t __PostRss_Readfunction_Callback(char *buffer,size_t size,size_t nitems,
|
||||
void *userdata)
|
||||
{
|
||||
Xport *xport=(Xport *)userdata;
|
||||
|
||||
int curlsize=size*nitems;
|
||||
int segsize=xport->xport_curl_data.size()-xport->xport_curl_data_ptr;
|
||||
if(segsize<curlsize) {
|
||||
curlsize=segsize;
|
||||
}
|
||||
memcpy(buffer,xport->xport_curl_data.mid(xport->xport_curl_data_ptr,curlsize).constData(),
|
||||
curlsize);
|
||||
xport->xport_curl_data_ptr+=curlsize;
|
||||
return curlsize;
|
||||
}
|
||||
|
||||
|
||||
void Xport::SavePodcast()
|
||||
{
|
||||
int cast_id=0;
|
||||
@ -64,7 +86,9 @@ void Xport::SavePodcast()
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=cast->keyName();
|
||||
if((!rda->user()->addPodcast())||(!rda->user()->feedAuthorized(keyname))) {
|
||||
if(((!rda->user()->addPodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
@ -122,7 +146,9 @@ void Xport::GetPodcast()
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=cast->keyName();
|
||||
if((!rda->user()->editPodcast())||(!rda->user()->feedAuthorized(keyname))) {
|
||||
if(((!rda->user()->addPodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
@ -180,7 +206,9 @@ void Xport::DeletePodcast()
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=cast->keyName();
|
||||
if((!rda->user()->deletePodcast())||(!rda->user()->feedAuthorized(keyname))) {
|
||||
if(((!rda->user()->deletePodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
@ -205,3 +233,289 @@ void Xport::DeletePodcast()
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
||||
|
||||
void Xport::PostPodcast()
|
||||
{
|
||||
int cast_id=0;
|
||||
QString keyname;
|
||||
QString destpath;
|
||||
QString err_msg;
|
||||
RDPodcast *cast=NULL;
|
||||
RDFeed *feed=NULL;
|
||||
QString msg="OK";
|
||||
RDUpload::ErrorCode upload_err;
|
||||
|
||||
if(!xport_post->getValue("ID",&cast_id)) {
|
||||
XmlExit("Missing ID",400,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
|
||||
cast=new RDPodcast(rda->config(),cast_id);
|
||||
if(!cast->exists()) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=cast->keyName();
|
||||
if(((!rda->user()->addPodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
destpath=QString(RD_AUDIO_ROOT)+"/"+cast->audioFilename();
|
||||
feed=new RDFeed(keyname,rda->config(),this);
|
||||
|
||||
RDUpload *upload=new RDUpload(rda->config(),this);
|
||||
upload->setSourceFile(destpath);
|
||||
QString desturl=feed->purgeUrl()+"/"+cast->audioFilename();
|
||||
upload->setDestinationUrl(desturl);
|
||||
if((upload_err=upload->
|
||||
runUpload(feed->purgeUsername(),feed->purgePassword(),
|
||||
rda->station()->sshIdentityFile(),feed->purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))!=RDUpload::ErrorOk) {
|
||||
delete upload;
|
||||
delete feed;
|
||||
delete cast;
|
||||
XmlExit(QString("Upload to \"")+desturl+"\" failed ["+
|
||||
RDUpload::errorText(upload_err)+"]",500,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
delete upload;
|
||||
|
||||
printf("Content-type: text/html; charset: UTF-8\n");
|
||||
printf("Status: 200\n\n");
|
||||
printf("OK\n");
|
||||
|
||||
rda->syslog(LOG_DEBUG,
|
||||
"posted podcast audio \"%s\"",destpath.toUtf8().constData());
|
||||
|
||||
delete feed;
|
||||
delete cast;
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
||||
|
||||
void Xport::RemovePodcast()
|
||||
{
|
||||
int cast_id=0;
|
||||
QString keyname;
|
||||
QString destpath;
|
||||
QString err_msg;
|
||||
RDPodcast *cast=NULL;
|
||||
RDFeed *feed=NULL;
|
||||
QString msg="OK";
|
||||
RDDelete::ErrorCode del_err;
|
||||
|
||||
if(!xport_post->getValue("ID",&cast_id)) {
|
||||
XmlExit("Missing ID",400,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
|
||||
cast=new RDPodcast(rda->config(),cast_id);
|
||||
if(!cast->exists()) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
keyname=cast->keyName();
|
||||
if(((!rda->user()->deletePodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
delete cast;
|
||||
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
destpath=QString(RD_AUDIO_ROOT)+"/"+cast->audioFilename();
|
||||
feed=new RDFeed(keyname,rda->config(),this);
|
||||
|
||||
RDDelete *del=new RDDelete(rda->config(),this);
|
||||
QString desturl=feed->purgeUrl()+"/"+cast->audioFilename();
|
||||
del->setTargetUrl(desturl);
|
||||
if((del_err=del->
|
||||
runDelete(feed->purgeUsername(),feed->purgePassword(),
|
||||
rda->station()->sshIdentityFile(),feed->purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))!=RDDelete::ErrorOk) {
|
||||
delete del;
|
||||
delete feed;
|
||||
delete cast;
|
||||
XmlExit(QString("Deletion of \"")+desturl+"\" failed ["+
|
||||
RDDelete::errorText(del_err)+"]",500,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
delete del;
|
||||
|
||||
printf("Content-type: text/html; charset: UTF-8\n");
|
||||
printf("Status: 200\n\n");
|
||||
printf("OK\n");
|
||||
|
||||
rda->syslog(LOG_DEBUG,
|
||||
"delete podcast audio \"%s\"",destpath.toUtf8().constData());
|
||||
|
||||
delete feed;
|
||||
delete cast;
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
||||
|
||||
void Xport::PostRss()
|
||||
{
|
||||
int feed_id=0;
|
||||
QString keyname;
|
||||
QString destpath;
|
||||
QString err_msg;
|
||||
RDFeed *feed=NULL;
|
||||
QString msg="OK";
|
||||
bool ret=false;
|
||||
|
||||
CURL *curl=NULL;
|
||||
CURLcode curl_err;
|
||||
char errstr[CURL_ERROR_SIZE];
|
||||
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
|
||||
//
|
||||
if((QUrl(feed->feedUrl()).scheme().toLower()=="sftp")&&
|
||||
(!rda->station()->sshIdentityFile().isEmpty())&&feed->purgeUseIdFile()) {
|
||||
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());
|
||||
}
|
||||
else {
|
||||
curl_easy_setopt(curl,CURLOPT_USERNAME,
|
||||
feed->purgeUsername().toUtf8().constData());
|
||||
curl_easy_setopt(curl,CURLOPT_PASSWORD,
|
||||
feed->purgePassword().toUtf8().constData());
|
||||
}
|
||||
|
||||
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_READDATA,this);
|
||||
|
||||
curl_easy_setopt(curl,CURLOPT_TIMEOUT,RD_CURL_TIMEOUT);
|
||||
curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1);
|
||||
curl_easy_setopt(curl,CURLOPT_USERAGENT,
|
||||
(const char *)rda->config()->userAgent().utf8());
|
||||
curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errstr);
|
||||
|
||||
//curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
|
||||
//curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTION,UploadErrorCallback);
|
||||
|
||||
switch((curl_err=curl_easy_perform(curl))) {
|
||||
case CURLE_OK:
|
||||
case CURLE_PARTIAL_FILE:
|
||||
feed->setLastBuildDateTime(now);
|
||||
ret=true;
|
||||
break;
|
||||
|
||||
default:
|
||||
err_msg=errstr;
|
||||
ret=false;
|
||||
break;
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
//
|
||||
// Update Enclosing Superfeeds
|
||||
//
|
||||
QStringList superfeeds=feed->isSubfeedOf();
|
||||
for(int i=0;i<superfeeds.size();i++) {
|
||||
QString err_msg2;
|
||||
RDFeed *feed=new RDFeed(superfeeds.at(i),rda->config(),this);
|
||||
if(!feed->postXml(&err_msg2)) {
|
||||
err_msg+="\n"+err_msg2;
|
||||
}
|
||||
delete feed;
|
||||
}
|
||||
|
||||
if(!ret) {
|
||||
XmlExit(err_msg,500,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
|
||||
printf("Content-type: text/html; charset: UTF-8\n");
|
||||
printf("Status: 200\n\n");
|
||||
printf("OK\n");
|
||||
|
||||
rda->syslog(LOG_DEBUG,
|
||||
"posted RSS XML to \"%s\"",feed->feedUrl().toUtf8().constData());
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
||||
|
||||
void Xport::RemoveRss()
|
||||
{
|
||||
int feed_id=0;
|
||||
RDFeed *feed=NULL;
|
||||
QString keyname;
|
||||
QString destpath;
|
||||
QString err_msg;
|
||||
// RDPodcast *cast=NULL;
|
||||
QString msg="OK";
|
||||
RDDelete::ErrorCode del_err;
|
||||
|
||||
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()->deletePodcast())||
|
||||
(!rda->user()->feedAuthorized(keyname)))&&
|
||||
(!rda->user()->adminConfig())) {
|
||||
|
||||
delete feed;
|
||||
XmlExit("No such feed",404,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
|
||||
RDDelete *del=new RDDelete(rda->config(),this);
|
||||
QString desturl=feed->feedUrl();
|
||||
del->setTargetUrl(desturl);
|
||||
if((del_err=del->
|
||||
runDelete(feed->purgeUsername(),feed->purgePassword(),
|
||||
rda->station()->sshIdentityFile(),feed->purgeUseIdFile(),
|
||||
rda->config()->logXloadDebugData()))!=RDDelete::ErrorOk) {
|
||||
delete del;
|
||||
delete feed;
|
||||
XmlExit(QString("Deletion of \"")+desturl+"\" failed ["+
|
||||
RDDelete::errorText(del_err)+"]",500,"podcasts.cpp",LINE_NUMBER);
|
||||
}
|
||||
delete del;
|
||||
|
||||
printf("Content-type: text/html; charset: UTF-8\n");
|
||||
printf("Status: 200\n\n");
|
||||
printf("OK\n");
|
||||
|
||||
rda->syslog(LOG_DEBUG,
|
||||
"deleted podcast RSS \"%s\"",destpath.toUtf8().constData());
|
||||
|
||||
delete feed;
|
||||
|
||||
Exit(0);
|
||||
}
|
||||
|
@ -308,6 +308,22 @@ void Xport::ripcConnectedData(bool state)
|
||||
DeletePodcast();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_POST_PODCAST:
|
||||
PostPodcast();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_REMOVE_PODCAST:
|
||||
RemovePodcast();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_POST_RSS:
|
||||
PostRss();
|
||||
break;
|
||||
|
||||
case RDXPORT_COMMAND_REMOVE_RSS:
|
||||
RemoveRss();
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Content-type: text/html\n\n");
|
||||
printf("rdxport: missing/invalid command\n");
|
||||
|
@ -85,6 +85,10 @@ class Xport : public QObject
|
||||
void SavePodcast();
|
||||
void GetPodcast();
|
||||
void DeletePodcast();
|
||||
void PostPodcast();
|
||||
void RemovePodcast();
|
||||
void PostRss();
|
||||
void RemoveRss();
|
||||
void LockLog();
|
||||
QString LogLockXml(bool result,const QString &log_name,const QString &guid,
|
||||
const QString &username,const QString &stationname,
|
||||
@ -100,6 +104,10 @@ class Xport : public QObject
|
||||
RDFormPost *xport_post;
|
||||
QString xport_remote_hostname;
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,9 +53,13 @@ install-exec-am:
|
||||
cp listservices.html $(DESTDIR)@libexecdir@
|
||||
cp listsystemsettings.html $(DESTDIR)@libexecdir@
|
||||
cp locklog.html $(DESTDIR)@libexecdir@
|
||||
cp postpodcast.html $(DESTDIR)@libexecdir@
|
||||
cp postrss.html $(DESTDIR)@libexecdir@
|
||||
cp rehash.html $(DESTDIR)@libexecdir@
|
||||
cp removecart.html $(DESTDIR)@libexecdir@
|
||||
cp removecut.html $(DESTDIR)@libexecdir@
|
||||
cp removepodcast.html $(DESTDIR)@libexecdir@
|
||||
cp removerss.html $(DESTDIR)@libexecdir@
|
||||
cp savefile.html $(DESTDIR)@libexecdir@
|
||||
cp savelog.html $(DESTDIR)@libexecdir@
|
||||
cp savepodcast.html $(DESTDIR)@libexecdir@
|
||||
@ -97,9 +101,13 @@ uninstall-local:
|
||||
rm -f $(DESTDIR)@libexecdir@/listservices.html
|
||||
rm -f $(DESTDIR)@libexecdir@/listsystemsettings.html
|
||||
rm -f $(DESTDIR)@libexecdir@/locklog.html
|
||||
rm -f $(DESTDIR)@libexecdir@/postpodcast.html
|
||||
rm -f $(DESTDIR)@libexecdir@/postrss.html
|
||||
rm -f $(DESTDIR)@libexecdir@/rehash.html
|
||||
rm -f $(DESTDIR)@libexecdir@/removecart.html
|
||||
rm -f $(DESTDIR)@libexecdir@/removecut.html
|
||||
rm -f $(DESTDIR)@libexecdir@/removepodcast.html
|
||||
rm -f $(DESTDIR)@libexecdir@/removepodrss.html
|
||||
rm -f $(DESTDIR)@libexecdir@/savefile.html
|
||||
rm -f $(DESTDIR)@libexecdir@/savelog.html
|
||||
rm -f $(DESTDIR)@libexecdir@/savepodcast.html
|
||||
@ -140,9 +148,13 @@ EXTRA_DIST = addcart.html\
|
||||
listservices.html\
|
||||
listsystemsettings.html\
|
||||
locklog.html\
|
||||
postpodcast.html\
|
||||
postrss.html\
|
||||
rehash.html\
|
||||
removecart.html\
|
||||
removecut.html\
|
||||
removepodcast.html\
|
||||
removerss.html\
|
||||
savefile.html\
|
||||
savelog.html\
|
||||
savepodcast.html\
|
||||
|
33
web/tests/postpodcast.html
Normal file
33
web/tests/postpodcast.html
Normal file
@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rivendell POSTPODCAST Service Test Harness</title>
|
||||
<body>
|
||||
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="COMMAND" value="40">
|
||||
<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>
|
33
web/tests/postrss.html
Normal file
33
web/tests/postrss.html
Normal file
@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rivendell POSTRSS Service Test Harness</title>
|
||||
<body>
|
||||
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="COMMAND" value="42">
|
||||
<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>
|
33
web/tests/removepodcast.html
Normal file
33
web/tests/removepodcast.html
Normal file
@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rivendell REMOVEPODCAST Service Test Harness</title>
|
||||
<body>
|
||||
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="COMMAND" value="41">
|
||||
<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>
|
33
web/tests/removerss.html
Normal file
33
web/tests/removerss.html
Normal file
@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rivendell REMOVERSS Service Test Harness</title>
|
||||
<body>
|
||||
<form action="/rd-bin/rdxport.cgi" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="COMMAND" value="43">
|
||||
<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>
|
Loading…
x
Reference in New Issue
Block a user