2020-09-22 Fred Gleason <fredg@paravelsystems.com>

* Added a 'PostImage' method to the Web API.
	* Added a 'RemoveImage' method to the Web API.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason
2020-09-23 13:11:11 -04:00
parent d534aacfd1
commit 9ae7f909cb
20 changed files with 539 additions and 211 deletions

View File

@@ -392,7 +392,7 @@ void Xport::PostRss()
xport_curl_data_ptr=0;
//
// Authentication
// Authentication Parameters
//
if((QUrl(feed->feedUrl()).scheme().toLower()=="sftp")&&
(!rda->station()->sshIdentityFile().isEmpty())&&feed->purgeUseIdFile()) {
@@ -410,6 +410,9 @@ void Xport::PostRss()
feed->purgePassword().toUtf8().constData());
}
//
// Transfer Parameters
//
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);
@@ -421,9 +424,9 @@ void Xport::PostRss()
(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);
//
// Execute it
//
switch((curl_err=curl_easy_perform(curl))) {
case CURLE_OK:
case CURLE_PARTIAL_FILE:
@@ -519,3 +522,188 @@ void Xport::RemoveRss()
Exit(0);
}
void Xport::PostImage()
{
int img_id=0;
QString keyname;
QString desturl;
QString err_msg;
unsigned feed_id=0;
RDFeed *feed=NULL;
QString file_ext;
bool ret=false;
QString sql;
RDSqlQuery *q=NULL;
CURL *curl=NULL;
CURLcode curl_err;
char errstr[CURL_ERROR_SIZE];
QDateTime now=QDateTime::currentDateTime();
if(!xport_post->getValue("ID",&img_id)) {
XmlExit("Missing ID",400,"podcasts.cpp",LINE_NUMBER);
}
sql=QString("select ")+
"FEED_ID,"+ // 00
"DATA,"+ // 01
"FILE_EXTENSION "+ // 02
"from FEED_IMAGES where "+
QString().sprintf("ID=%d",img_id);
q=new RDSqlQuery(sql);
if(q->first()) {
feed_id=q->value(0).toUInt();
xport_curl_data=q->value(1).toByteArray();
xport_curl_data_ptr=0;
file_ext=q->value(2).toString();
}
delete q;
if(feed_id==0) {
XmlExit("invalid image 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()->adminConfig()) {
delete feed;
XmlExit("No such feed",404,"podcasts.cpp",LINE_NUMBER);
}
desturl=feed->purgeUrl()+"/"+RDFeed::imageFilename(feed_id,img_id,file_ext);
if((curl=curl_easy_init())==NULL) {
XmlExit("unable to get CURL handle",500,"podcasts.cpp",LINE_NUMBER);
}
//
// Authentication Parameters
//
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());
}
//
// Transfer Parameters
//
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_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);
//
// Execute it
//
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);
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 image \"%s\"",desturl.toUtf8().constData());
Exit(0);
}
void Xport::RemoveImage()
{
int img_id=0;
QString keyname;
unsigned feed_id=0;
RDFeed *feed=NULL;
QString desturl;
QString file_ext;
QString sql;
RDSqlQuery *q=NULL;
QDateTime now=QDateTime::currentDateTime();
RDDelete::ErrorCode del_err;
if(!xport_post->getValue("ID",&img_id)) {
XmlExit("Missing ID",400,"podcasts.cpp",LINE_NUMBER);
}
sql=QString("select ")+
"FEED_ID,"+ // 00
"FILE_EXTENSION "+ // 01
"from FEED_IMAGES where "+
QString().sprintf("ID=%d",img_id);
q=new RDSqlQuery(sql);
if(q->first()) {
feed_id=q->value(0).toUInt();
file_ext=q->value(1).toString();
}
delete q;
if(feed_id==0) {
XmlExit("invalid image 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()->adminConfig()) {
delete feed;
XmlExit("No such podcast",404,"podcasts.cpp",LINE_NUMBER);
}
feed=new RDFeed(keyname,rda->config(),this);
desturl=feed->purgeUrl()+"/"+RDFeed::imageFilename(feed_id,img_id,file_ext);
RDDelete *del=new RDDelete(rda->config(),this);
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 image \"")+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 image \"%s\"",desturl.toUtf8().constData());
delete feed;
Exit(0);
}

View File

@@ -324,6 +324,14 @@ void Xport::ripcConnectedData(bool state)
RemoveRss();
break;
case RDXPORT_COMMAND_POST_IMAGE:
PostImage();
break;
case RDXPORT_COMMAND_REMOVE_IMAGE:
RemoveImage();
break;
default:
printf("Content-type: text/html\n\n");
printf("rdxport: missing/invalid command\n");

View File

@@ -89,6 +89,8 @@ class Xport : public QObject
void RemovePodcast();
void PostRss();
void RemoveRss();
void PostImage();
void RemoveImage();
void LockLog();
QString LogLockXml(bool result,const QString &log_name,const QString &guid,
const QString &username,const QString &stationname,