17#include <Poco/Net/AcceptCertificateHandler.h>
18#include <Poco/Net/HTTPRequest.h>
19#include <Poco/Net/HTTPResponse.h>
20#include <Poco/Net/HTTPSClientSession.h>
21#include <Poco/Net/PrivateKeyPassphraseHandler.h>
22#include <Poco/Net/SSLException.h>
23#include <Poco/Net/SSLManager.h>
25#include <Poco/SharedPtr.h>
26#include <Poco/StreamCopier.h>
29#include <boost/regex.hpp>
38 "The file to publish.");
41 "The workspace to publish.");
42 declareProperty(
"NameInCatalog",
"",
43 "The name to give to the file being saved. The file name or workspace "
44 "name is used by default. "
45 "This can only contain alphanumerics, underscores or periods.");
46 declareProperty(
"InvestigationNumber",
"",
"The investigation number where the published file will be saved to.");
47 declareProperty(
"DataFileDescription",
"",
"A short description of the datafile you are publishing to the catalog.");
48 declareProperty(
"Session",
"",
"The session information of the catalog to use.");
60 boost::regex re(
"^[a-zA-Z0-9_.]*$");
61 if (!boost::regex_match(nameInCatalog.begin(), nameInCatalog.end(), re)) {
62 throw std::runtime_error(
"The filename can only contain characters, "
63 "numbers, underscores and periods");
67 if ((ws.empty() && filePath.empty()) || (!ws.empty() && !filePath.empty())) {
68 throw std::runtime_error(
"Please select a workspace or a file to publish. Not both.");
72 auto catalogInfoService = std::dynamic_pointer_cast<API::ICatalogInfoService>(
76 if (!catalogInfoService)
77 throw std::runtime_error(
"The catalog that you are using does not support "
78 "publishing to the archives.");
81 if (!filePath.empty()) {
82 std::string fileName = Poco::Path(filePath).getFileName();
85 if (nameInCatalog.empty()) {
87 g_log.
notice(
"NameInCatalog has not been set. Using filename instead: " + fileName +
".");
91 if (nameInCatalog.empty()) {
93 g_log.
notice(
"NameInCatalog has not been set. Using workspace name instead: " +
workspace->getName() +
".");
105 std::ios_base::openmode mode =
isDataFile(filePath) ? std::ios_base::binary : std::ios_base::in;
108 std::ifstream fileStream(filePath.c_str(), mode);
110 if (fileStream.rdstate() & std::ios::failbit)
129 Poco::URI uri(uploadURL);
130 std::string path(uri.getPathAndQuery());
132 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> certificateHandler =
133 new Poco::Net::AcceptCertificateHandler(
true);
136 const Poco::Net::Context::Ptr context =
137 new Poco::Net::Context(Poco::Net::Context::CLIENT_USE,
"",
"",
"", Poco::Net::Context::VERIFY_NONE);
140 Poco::Net::SSLManager::instance().initializeClient(
nullptr, certificateHandler, context);
141 Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context);
145 Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_PUT, path, Poco::Net::HTTPMessage::HTTP_1_1);
148 request.setChunkedTransferEncoding(
true);
149 std::ostream &os = session.sendRequest(request);
151 Poco::StreamCopier::copyStream(fileContents, os);
154 Poco::Net::HTTPResponse response;
156 std::istream &responseStream = session.receiveResponse(response);
159 Poco::Net::HTTPResponse::HTTPStatus HTTPStatus = response.getStatus();
163 if (!IDSError.empty()) {
173 }
catch (Poco::Net::SSLException &
error) {
174 throw std::runtime_error(
error.displayText());
178 catch (Poco::Exception &) {
188 std::string extension = Poco::Path(filePath).getExtension();
189 std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
190 return extension ==
"raw" || extension ==
"nxs";
202 saveNexus->initialize();
204 saveNexus->setProperty(
"InputWorkspace",
workspace->getName());
207 saveNexus->execute();
217 std::stringstream ss;
221 std::string fileName = Poco::Path(Poco::Path(
getPropertyValue(
"NameInCatalog")).getFileName()).getBaseName() +
".py";
234 wsHistory->initialize();
235 wsHistory->setProperty(
"InputWorkspace",
workspace->getName());
236 wsHistory->execute();
237 return wsHistory->getPropertyValue(
"ScriptText");
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void cancel() override
Raises the cancel flag.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
A property class for workspaces.
const std::string getIDSError(const Poco::Net::HTTPResponse::HTTPStatus &HTTPStatus, std::istream &responseStream)
Obtain the error message returned by the IDS.
CatalogPublish is responsible for publishing user data to the data archive.
void saveWorkspaceToNexus(Mantid::API::Workspace_sptr &workspace)
Saves the workspace as a nexus file to the user's default directory.
void exec() override
Override algorithm execute method.
void publishWorkspaceHistory(Mantid::API::ICatalogInfoService_sptr &catalogInfoService, Mantid::API::Workspace_sptr &workspace)
Publish the history of a given workspace.
const std::string generateWorkspaceHistory(Mantid::API::Workspace_sptr &workspace)
Generate the history of a given workspace.
bool isDataFile(const std::string &filePath)
True if the extension of the file is a datafile.
void publish(std::istream &fileContents, const std::string &uploadURL)
Stream the contents of a file to a given URL.
Records the filename and the description of failure.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ICatalogInfoService > ICatalogInfoService_sptr
@ Input
An input workspace.