From 1bf1d94bfebd454c17bac66e8124339228bb0664 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 16 Sep 2021 12:16:08 -0400 Subject: [PATCH] 2021-09-16 Fred Gleason * Added a ' SaveWebgetFilesDirectory=' directive to rd.conf(5). Signed-off-by: Fred Gleason --- ChangeLog | 2 ++ conf/rd.conf-sample | 9 ++++++ lib/rdconfig.cpp | 11 +++++++- lib/rdconfig.h | 2 ++ web/webget/webget.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++ web/webget/webget.h | 5 ++-- 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3bc256e..9dbf768f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22427,3 +22427,5 @@ 2021-09-13 Fred Gleason * Added an 'RDGroups::create()' static method. * Added an 'RDGroups::remove()' static method. +2021-09-16 Fred Gleason + * Added a ' SaveWebgetFilesDirectory=' directive to rd.conf(5). diff --git a/conf/rd.conf-sample b/conf/rd.conf-sample index a030bb4d..989ac555 100644 --- a/conf/rd.conf-sample +++ b/conf/rd.conf-sample @@ -188,3 +188,12 @@ TranscodingDelay=0 ; dropboxes configured. Rivendell imposes a hard limit of 999 on this ; setting. ; MeterPortRange=100 + +; Save original files processed by the Webget service to the indicated +; directory. Files so saved will have the date-time that the file was +; processed prepended to the original filename, for example: +; +; myfile.mp3 => YYYYMMDD-HHMMSS-myfile.mp3 +; +; Default action is to not save files. +; SaveWebgetFilesDirectory= diff --git a/lib/rdconfig.cpp b/lib/rdconfig.cpp index 8fdbdac0..578c347c 100644 --- a/lib/rdconfig.cpp +++ b/lib/rdconfig.cpp @@ -387,6 +387,12 @@ bool RDConfig::lockRdairplayMemory() const } +QString RDConfig::saveWebgetFilesDirectory() const +{ + return conf_save_webget_files_directory; +} + + int RDConfig::meterBasePort() const { return conf_meter_base_port; @@ -607,7 +613,9 @@ bool RDConfig::load() conf_disable_maint_checks= profile->boolValue("Hacks","DisableMaintChecks",false); - conf_lock_rdairplay_memory= + conf_save_webget_files_directory= + profile->stringValue("Hacks","SaveWebgetFilesDirectory"); + conf_lock_rdairplay_memory= profile->boolValue("Hacks","LockRdairplayMemory",false); conf_meter_base_port= profile->intValue("Hacks","MeterPortBaseNumber",RD_DEFAULT_METER_SOCKET_BASE_UDP_PORT); @@ -736,6 +744,7 @@ void RDConfig::clear() conf_jack_ports[0].clear(); conf_jack_ports[1].clear(); conf_disable_maint_checks=false; + conf_save_webget_files_directory=""; conf_lock_rdairplay_memory=false; conf_meter_base_port=RD_DEFAULT_METER_SOCKET_BASE_UDP_PORT; conf_meter_port_range=RD_METER_SOCKET_PORT_RANGE; diff --git a/lib/rdconfig.h b/lib/rdconfig.h index 5de36d8b..ceaa774c 100644 --- a/lib/rdconfig.h +++ b/lib/rdconfig.h @@ -103,6 +103,7 @@ class RDConfig bool lockRdairplayMemory() const; int meterBasePort() const; int meterPortRange() const; + QString saveWebgetFilesDirectory() const; bool enableMixerLogging() const; uid_t uid() const; gid_t gid() const; @@ -174,6 +175,7 @@ class RDConfig QString conf_http_user_agent; bool conf_disable_maint_checks; bool conf_lock_rdairplay_memory; + QString conf_save_webget_files_directory; int conf_meter_base_port; int conf_meter_port_range; std::vector conf_jack_ports[2]; diff --git a/web/webget/webget.cpp b/web/webget/webget.cpp index 0e12e90c..427547aa 100644 --- a/web/webget/webget.cpp +++ b/web/webget/webget.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -473,6 +474,9 @@ void MainObject::PutAudio() // QStringList args; + if(!rda->config()->saveWebgetFilesDirectory().isEmpty()) { + SaveSourceFile(filename); + } args.push_back(QString("--ticket=")+webget_ticket+":"+ webget_post->clientAddress().toString()); args.push_back("--send-mail"); @@ -770,6 +774,67 @@ bool MainObject::Authenticate() } +void MainObject::SaveSourceFile(const QString &filepath) const +{ + char buffer[1024]; + ssize_t n; + int src_fd=-1; + int dst_fd=-1; + QDir dir(rda->config()->saveWebgetFilesDirectory()); + if(!dir.exists()) { + rda->syslog(LOG_WARNING,"SaveWebgetFilesDirectory \"%s\" does not exist", + rda->config()->saveWebgetFilesDirectory().toUtf8().constData()); + return; + } + QDateTime now=QDateTime::currentDateTime(); + QStringList f0=filepath.split("/",QString::SkipEmptyParts); + QString filename=rda->config()->saveWebgetFilesDirectory()+"/"+ + now.toString("yyyyMMdd-hhmmss-")+f0.last(); + + // + // Open Source File + // + if((src_fd=open(filepath.toUtf8(),O_RDONLY))<0) { + rda->syslog(LOG_WARNING, + "unable to open source file \"%s\" for SaveWebgetFilesDirectory [%s]", + filepath.toUtf8().constData(),strerror(errno)); + return; + } + + // + // Open Destination File + // + int num=1; + while((dst_fd=open(filename.toUtf8(),O_WRONLY|O_CREAT|O_EXCL,S_IRUSR|S_IRGRP))<0) { + if(errno!=EEXIST) { + rda->syslog(LOG_WARNING, + "unable to open destination file \"%s\" for SaveWebgetFilesDirectory [%s]", + filename.toUtf8().constData(),strerror(errno)); + close(src_fd); + return; + } + filename=rda->config()->saveWebgetFilesDirectory()+"/"+ + now.toString("yyyyMMdd-hhmmss")+QString().sprintf("[%d]-",num)+f0.last(); + num++; + } + + // + // Move the data + // + while((n=read(src_fd,buffer,1024))>0) { + write(dst_fd,buffer,n); + } + if(n<0) { + rda->syslog(LOG_WARNING,"error while reading source file \"%s\" for SaveWebgetFilesDirectory [%s]", + filepath.toUtf8().constData(),strerror(errno)); + } + close(src_fd); + close(dst_fd); + rda->syslog(LOG_INFO,"saved Webget file \"%s\"", + filename.toUtf8().constData()); +} + + void MainObject::Exit(int code) { if(webget_post!=NULL) { diff --git a/web/webget/webget.h b/web/webget/webget.h index a555a8c0..d573334a 100644 --- a/web/webget/webget.h +++ b/web/webget/webget.h @@ -2,7 +2,7 @@ // // Rivendell audio upload/download utility // -// (C) Copyright 2018-2020 Fred Gleason +// (C) Copyright 2018-2021 Fred Gleason // // 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 @@ -21,7 +21,7 @@ #ifndef WEBGET_H #define WEBGET_H -#include +#include #include #include @@ -46,6 +46,7 @@ class MainObject : public QObject void ServeForm(); void ServeLogin(int resp_code); bool Authenticate(); + void SaveSourceFile(const QString &filepath) const; void Exit(int code); void TextExit(const QString &msg,int code,int line) const; RDFormPost *webget_post;