Add App::Link support to Cloud module

ONLY enabled if the Cloud Module is compiled into FreeCAD
    ALL files must be saved into a Cloud Based storage
    Add a Signal to the PropertyLink to enable support of external storage
    Put the Assembly Document as active document

Signed-off-by: Jean-Marie Verdun <jmverdun3@gmail.com>
This commit is contained in:
Jean-Marie Verdun
2020-07-12 19:51:23 -04:00
committed by Yorik van Havre
parent cb2099aa6b
commit 0b1af7c838
6 changed files with 87 additions and 13 deletions

View File

@@ -179,6 +179,7 @@ public:
boost::signals2::signal<void (const App::DocumentObject&)> signalFinishRestoreObject;
boost::signals2::signal<void (const App::Document&,const App::Property&)> signalChangePropertyEditor;
//@}
boost::signals2::signal<void (std::string)> signalLinkXsetValue;
void clearDocument();

View File

@@ -2463,6 +2463,19 @@ public:
const char *filename, App::Document *pDoc, bool relative, QString *fullPath = 0)
{
bool absolute;
// The path could be an URI, in that case
// TODO: build a far much more resilient approach to test for an URI
std::string prefix("https://");
std::string FileName(filename);
auto res = std::mismatch(prefix.begin(), prefix.end(), FileName.begin());
if ( res.first == prefix.end() )
{
// We do have an URI
QString path = QString::fromUtf8(filename);
if ( fullPath )
*fullPath = path;
return std::string(filename);
}
// make sure the filename is aboluste path
QString path = QDir::cleanPath(QString::fromUtf8(filename));
if((absolute=QFileInfo(path).isAbsolute())) {
@@ -2534,12 +2547,28 @@ public:
}
static QString getFullPath(const char *p) {
if(!p) return QString();
return QFileInfo(QString::fromUtf8(p)).canonicalFilePath();
}
QString path = QString::fromUtf8(p);;
std::string prefix("https://");
std::string Path(path.toStdString());
auto res = std::mismatch(prefix.begin(), prefix.end(), Path.begin());
if ( res.first == prefix.end() )
return(path);
else
{
if(!p) return QString();
return QFileInfo(QString::fromUtf8(p)).canonicalFilePath();
}
}
QString getFullPath() const {
return QFileInfo(myPos->first).canonicalFilePath();
QString path = myPos->first;
std::string prefix("https://");
std::string Path(path.toStdString());
auto res = std::mismatch(prefix.begin(), prefix.end(), Path.begin());
if ( res.first == prefix.end() )
return(path);
else
return QFileInfo(myPos->first).canonicalFilePath();
}
const char *filePath() const {
@@ -2984,6 +3013,7 @@ void PropertyXLink::setValue(std::string &&filename, std::string &&name,
DocumentObject *pObject=0;
DocInfoPtr info;
if(filename.size()) {
owner->getDocument()->signalLinkXsetValue(filename);
info = DocInfo::get(filename.c_str(),owner->getDocument(),this,name.c_str());
if(info->pcDoc)
pObject = info->pcDoc->getObject(name.c_str());

View File

@@ -25,7 +25,7 @@
#define APP_PROPERTYLINKS_H
// Std. configurations
#include <boost/signals2.hpp>
#include <vector>
#include <map>

View File

@@ -263,7 +263,7 @@ void Cloud::CloudWriter::createBucket()
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
@@ -533,7 +533,7 @@ char *Cloud::MD5Sum(const char *ptr, long size)
return(output);
}
struct curl_slist *Cloud::BuildHeaderAmzS3v4(const char *URL, const char *TCPPort, const char *PublicKey, struct Cloud::AmzDatav4 *Data)
struct curl_slist *Cloud::BuildHeaderAmzS3v4(const char *URL, const char *PublicKey, struct Cloud::AmzDatav4 *Data)
{
char header_data[1024];
struct curl_slist *chunk = NULL;
@@ -671,7 +671,7 @@ Cloud::CloudWriter::CloudWriter(const char* URL, const char* TokenAuth, const ch
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
@@ -887,7 +887,7 @@ Cloud::CloudReader::CloudReader(const char* URL, const char* TokenAuth, const ch
else
{
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(),"application/xml", path, this->TokenSecret, NULL, 0, (char *)&parameters[0], this->Region);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
@@ -982,7 +982,7 @@ void Cloud::CloudReader::DownloadFile(Cloud::CloudReader::FileEntry *entry)
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
@@ -1110,7 +1110,7 @@ void Cloud::CloudWriter::pushCloud(const char *FileName, const char *data, long
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
@@ -1265,6 +1265,40 @@ void readFiles(Cloud::CloudReader reader, Base::XMLReader *xmlreader)
}
}
void Cloud::Module::LinkXSetValue(std::string filename)
{
// Need to check if the document exist
// if not we have to create a new one
// and Restore the associated Document
//
std::vector<Document*> Documents;
Documents = App::GetApplication().getDocuments();
for (std::vector<Document*>::iterator it = Documents.begin() ; it != Documents.end(); it++)
{
if ( (*it)->FileName.getValue() == filename )
{
// The document exist
// we can exit
return;
}
}
size_t header = filename.find_first_of(":");
string protocol=filename.substr(0,header);
string url_new=filename.substr(header+3); //url_new is the url excluding the http part
size_t part2 = url_new.find_first_of("/");
string path =url_new.substr(part2+1);
// Starting from here the Document doesn't exist we must create it
// and make it the active Document before Restoring
App::Document* newDoc;
string newName;
Document* currentDoc = GetApplication().getActiveDocument();
newName = GetApplication().getUniqueDocumentName("unnamed");
newDoc = GetApplication().newDocument(newName.c_str(), (const char*)path.c_str(), true);
GetApplication().setActiveDocument(newDoc);
this->cloudRestore((const char*)path.c_str());
GetApplication().setActiveDocument(currentDoc);
}
bool Cloud::Module::cloudRestore (const char *BucketName)
{
@@ -1272,6 +1306,7 @@ bool Cloud::Module::cloudRestore (const char *BucketName)
Document* doc = GetApplication().getActiveDocument();
// clean up if the document is not empty
// !TODO: mind exceptions while restoring!
doc->signalLinkXsetValue.connect(boost::bind(&Cloud::Module::LinkXSetValue,this,_1));
doc->clearUndos();
@@ -1296,7 +1331,7 @@ bool Cloud::Module::cloudRestore (const char *BucketName)
GetApplication().signalStartRestoreDocument(*doc);
doc->setStatus(Document::Restoring, true);
try {
// Document::Restore(reader);
doc->Restore(reader);
@@ -1320,6 +1355,12 @@ bool Cloud::Module::cloudRestore (const char *BucketName)
GetApplication().signalFinishRestoreDocument(*doc);
doc->setStatus(Document::Restoring, false);
doc->Label.setValue(BucketName);
// The FileName shall be an URI format
string uri;
uri = this->URL.getStrValue()+":"+this->TCPPort.getStrValue()+"/"+string(BucketName);
doc->FileName.setValue(uri);
doc->signalLinkXsetValue.disconnect(boost::bind(&Cloud::Module::LinkXSetValue,this,_1));
return(true);
}

View File

@@ -72,7 +72,7 @@ size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmem
struct AmzData *ComputeDigestAmzS3v2(char *operation, char *data_type, const char *target, const char *Secret, const char *ptr, long size);
struct AmzDatav4 *ComputeDigestAmzS3v4(char *operation, const char *server, char *data_type, const char *target, const char *Secret, const char *ptr, long size, char *paramters, std::string Region);
struct curl_slist *BuildHeaderAmzS3v2(const char *URL, const char *TCPPort, const char *PublicKey, struct AmzData *Data);
struct curl_slist *BuildHeaderAmzS3v4(const char *URL, const char *TCPPort, const char *PublicKey, struct AmzDatav4 *Data);
struct curl_slist *BuildHeaderAmzS3v4(const char *URL, const char *PublicKey, struct AmzDatav4 *Data);
char *MD5Sum(const char *ptr, long size);
char *SHA256Sum(const char *ptr, long size);
@@ -159,6 +159,7 @@ public:
App::PropertyString Region;
bool cloudSave(const char* BucketName);
bool cloudRestore(const char* BucketName);
void LinkXSetValue(std::string filename);
private:
Py::Object sCloudURL (const Py::Tuple& args);

View File

@@ -1,3 +1,4 @@
add_compile_options("-DBUILD_CLOUD")
#----------------------------- Control certificate validation ------------
option(ALLOW_SELF_SIGNED_CERTIFICATE "Allow self signed certificate" OFF)
if (ALLOW_SELF_SIGNED_CERTIFICATE)