From 5d73130123ffad900bb130234700aed06ae0a122 Mon Sep 17 00:00:00 2001 From: Javier Navarro Date: Tue, 23 Jun 2020 17:01:19 +0200 Subject: [PATCH 01/52] Handle custom ETD errors (Obj-C) --- bindings/ios/MEGAError.h | 55 ++++++++++++++++++++++++++++++++++++ bindings/ios/MEGAError.mm | 12 ++++++++ bindings/ios/MEGASdk.h | 40 ++++++++++++++++++++++++++ bindings/ios/MEGASdk.mm | 8 ++++++ bindings/ios/MEGATransfer.h | 7 +++++ bindings/ios/MEGATransfer.mm | 6 ++++ 6 files changed, 128 insertions(+) diff --git a/bindings/ios/MEGAError.h b/bindings/ios/MEGAError.h index 29dcb5f670..83c469bfab 100644 --- a/bindings/ios/MEGAError.h +++ b/bindings/ios/MEGAError.h @@ -65,6 +65,24 @@ typedef NS_ENUM(NSInteger, MEGAErrorContext) { MEGAErrorContextUpload = 3 ///< Upload transfer context. }; +/** + * @brief User custom error details + */ +typedef NS_ENUM(NSInteger, MEGAUserErrorCode) { + MEGAUserErrorCodeETDUnknown = -1, ///< Unknown state + MEGAUserErrorCodeETDSuspension = 7 ///< Account suspend by an ETD/ToS 'severe' +}; + +/** + * @brief Link custom error details + */ +typedef NS_ENUM(NSInteger, MEGALinkErrorCode) { + MEGALinkErrorCodeUnknown = -1, ///< Unknown state + MEGALinkErrorCodeUndeleted = 0, ///< Link is undeleted + MEGALinkErrorCodeUndeletedDown = 1, ///< Link is deleted or down + MEGALinkErrorCodeDownETD = 2 ///< Link is down due to an ETD specifically +}; + /** * @brief Provides information about an error. */ @@ -91,6 +109,43 @@ typedef NS_ENUM(NSInteger, MEGAErrorContext) { */ @property (readonly, nonatomic) long long value; +/** + * @brief YES if error has extra info + * + * @note Can return YES for: + * - MEGARequestTypeFetchnodes with error MEGAErrorTypeApiENoent + * - MEGARequestTypeGetPublicNode with error MEGAErrorTypeApiETooMany + * - MEGARequestTypeImportLink with error MEGAErrorTypeApiETooMany + * - [MEGATransferDelegate onTransferFinish:transfer:error:] with error MEGAErrorTypeApiETooMany + */ +@property (readonly, nonatomic, getter=hasExtraInfo) BOOL extraInfo; + +/** + * @brief The user status + * + * This property contains valid value when extraInfo is YES + * Possible values: + * MEGAUserErrorCodeETDSuspension + * + * Otherwise, it value is MEGAUserErrorCodeETDUnknown + * + */ +@property (readonly, nonatomic) MEGAUserErrorCode userStatus; + +/** + * @brief The link status + * + * This property contains valid value when extraInfo is YES + * Possible values: + * MEGALinkErrorCodeUndeleted + * MEGALinkErrorCodeUndeletedDown + * MEGALinkErrorCodeDownETD + * + * Otherwise, it value is MEGALinkErrorCodeUnknown + * + */ +@property (readonly, nonatomic) MEGALinkErrorCode linkStatus; + /** * @brief Creates a copy of this MEGAError object. * diff --git a/bindings/ios/MEGAError.mm b/bindings/ios/MEGAError.mm index 9a8cfce9b4..b80f1741bb 100644 --- a/bindings/ios/MEGAError.mm +++ b/bindings/ios/MEGAError.mm @@ -69,6 +69,18 @@ - (long long)value { return self.megaError ? self.megaError->getValue() : 0; } +- (BOOL)hasExtraInfo { + return self.megaError ? self.megaError->hasExtraInfo() : NO; +} + +- (MEGAUserErrorCode)userStatus { + return self.megaError ? MEGAUserErrorCode(self.megaError->getUserStatus()) : MEGAUserErrorCodeETDUnknown; +} + +- (MEGALinkErrorCode)linkStatus { + return self.megaError ? MEGALinkErrorCode(self.megaError->getLinkStatus()) : MEGALinkErrorCodeUnknown; +} + - (NSString *)nameWithErrorCode:(NSInteger)errorCode { return MegaError::getErrorString((int)errorCode) ? [[NSString alloc] initWithUTF8String:MegaError::getErrorString((int)errorCode)] : nil; } diff --git a/bindings/ios/MEGASdk.h b/bindings/ios/MEGASdk.h index de070ecb2e..7d4b5b9588 100644 --- a/bindings/ios/MEGASdk.h +++ b/bindings/ios/MEGASdk.h @@ -6857,6 +6857,8 @@ typedef NS_ENUM(NSInteger, AffiliateType) { /** * @brief Check if a node has an access level. * + * @deprecated Use checkAccessErrorExtendedForNode + * * @param node Node to check. * @param level Access level to check. * Valid values for this parameter are: @@ -6874,8 +6876,31 @@ typedef NS_ENUM(NSInteger, AffiliateType) { */ - (MEGAError *)checkAccessForNode:(MEGANode *)node level:(MEGAShareType)level; +/** + * @brief Check if a node has an access level + * + * @param node Node to check + * @param level Access level to check + * Valid values for this parameter are: + * - MEGAShareTypeAccessOwner + * - MEGAShareTypeAccessFull + * - MEGAShareTypeAccessReadWrite + * - MEGAShareTypeAccessRead + * + * @return Error with the result. + * Valid values for the error code are: + * - MEGAErrorTypeApiOk - The node has the required access level + * - MEGAErrorTypeApiEAccess - The node doesn't have the required access level + * - MEGAErrorTypeApiENoent - The node doesn't exist in the account + * - MEGAErrorTypeApiEArgs - Invalid parameters + */ +- (MEGAError *)checkAccessErrorExtendedForNode:(MEGANode *)node level:(MEGAShareType)level; + /** * @brief Check if a node can be moved to a target node. + * + * @deprecated User checkMoveErrorExtendedForNode + * * @param node Node to check. * @param target Target for the move operation. * @return MEGAError object with the result: @@ -6888,6 +6913,21 @@ typedef NS_ENUM(NSInteger, AffiliateType) { */ - (MEGAError *)checkMoveForNode:(MEGANode *)node target:(MEGANode *)target; +/** + * @brief Check if a node can be moved to a target node. + * + * @param node Node to check. + * @param target Target for the move operation. + * @return MEGAError object with the result: + * Valid values for the error code are: + * - MEGAErrorTypeApiOk - The node can be moved to the target + * - MEGAErrorTypeApiEAccess - The node can't be moved because of permissions problems + * - MEGAErrorTypeApiECircular - The node can't be moved because that would create a circular linkage + * - MEGAErrorTypeApiENoent - The node or the target doesn't exist in the account + * - MEGAErrorTypeApiEArgs - Invalid parameters + */ +- (MEGAError *)checkMoveErrorExtendedForNode:(MEGANode *)node target:(MEGANode *)target; + /** * @brief Check if a node is in the Rubbish bin tree * diff --git a/bindings/ios/MEGASdk.mm b/bindings/ios/MEGASdk.mm index d5eeaf0ed6..021a45d7c6 100644 --- a/bindings/ios/MEGASdk.mm +++ b/bindings/ios/MEGASdk.mm @@ -2010,6 +2010,10 @@ - (MEGAError *)checkAccessForNode:(MEGANode *)node level:(MEGAShareType)level { return [[MEGAError alloc] initWithMegaError:self.megaApi->checkAccess((node != nil) ? [node getCPtr] : NULL, (int) level).copy() cMemoryOwn:YES]; } +- (MEGAError *)checkAccessErrorExtendedForNode:(MEGANode *)node level:(MEGAShareType)level { + return [[MEGAError alloc] initWithMegaError:self.megaApi->checkAccessErrorExtended(node.getCPtr, (int)level) cMemoryOwn:YES]; +} + - (BOOL)isNodeInRubbish:(MEGANode *)node { return self.megaApi->isInRubbish(node ? [node getCPtr] : NULL); } @@ -2018,6 +2022,10 @@ - (MEGAError *)checkMoveForNode:(MEGANode *)node target:(MEGANode *)target { return [[MEGAError alloc] initWithMegaError:self.megaApi->checkMove((node != nil) ? [node getCPtr] : NULL, (target != nil) ? [target getCPtr] : NULL).copy() cMemoryOwn:YES]; } +- (MEGAError *)checkMoveErrorExtendedForNode:(MEGANode *)node target:(MEGANode *)target { + return [[MEGAError alloc] initWithMegaError:self.megaApi->checkMoveErrorExtended(node.getCPtr, target.getCPtr) cMemoryOwn:YES]; +} + - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString recursive:(BOOL)recursive { return [[MEGANodeList alloc] initWithNodeList:self.megaApi->search((node != nil) ? [node getCPtr] : NULL, (searchString != nil) ? [searchString UTF8String] : NULL, recursive) cMemoryOwn:YES]; } diff --git a/bindings/ios/MEGATransfer.h b/bindings/ios/MEGATransfer.h index 70a70241d6..339c911149 100644 --- a/bindings/ios/MEGATransfer.h +++ b/bindings/ios/MEGATransfer.h @@ -20,6 +20,7 @@ */ #import #import "MEGANode.h" +#import "MEGAError.h" typedef NS_ENUM (NSInteger, MEGATransferType) { MEGATransferTypeDownload, @@ -191,6 +192,12 @@ typedef NS_ENUM (NSInteger, MEGATransferState) { */ @property (readonly, nonatomic) BOOL isStreamingTransfer; +/** + * @brief The last error related to the transfer with extra info + * + */ +@property (readonly, nonatomic) MEGAError *lastErrorExtended; + /** * @brief YES if it's a folder transfer, otherwise (file transfer) it returns NO */ diff --git a/bindings/ios/MEGATransfer.mm b/bindings/ios/MEGATransfer.mm index 3a75bf5cb8..f0caf355ac 100644 --- a/bindings/ios/MEGATransfer.mm +++ b/bindings/ios/MEGATransfer.mm @@ -20,6 +20,7 @@ */ #import "MEGATransfer.h" #import "MEGANode+init.h" +#import "MEGAError+init.h" using namespace mega; @@ -145,6 +146,11 @@ - (BOOL)isStreamingTransfer { return self.megaTransfer ? (BOOL) self.megaTransfer->isStreamingTransfer() : NO; } +- (MEGAError *)lastErrorExtended { + mega::MegaError *e = (mega::MegaError *)self.megaTransfer->getLastErrorExtended(); + return e ? [[MEGAError alloc] initWithMegaError:e cMemoryOwn:NO] : nil; +} + - (BOOL)isFolderTransfer { return self.megaTransfer ? (BOOL) self.megaTransfer->isFolderTransfer() : NO; } From cbbb254557cf5a64bd19ad154b0b6fabeee9a4dc Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 08:42:02 +0200 Subject: [PATCH 02/52] Add missing start and trailing dot to webclient_is_image_thumb --- src/megaclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index 38339950a6..896606a19f 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14282,7 +14282,7 @@ namespace action_bucket_compare // these lists of file extensions (and the logic to use them) all come from the webclient - if updating here, please make sure the webclient is updated too, preferably webclient first. const static string webclient_is_image_def = ".jpg.jpeg.gif.bmp.png."; const static string webclient_is_image_raw = ".3fr.arw.cr2.crw.ciff.cs1.dcr.dng.erf.iiq.k25.kdc.mef.mos.mrw.nef.nrw.orf.pef.raf.raw.rw2.rwl.sr2.srf.srw.x3f."; - const static string webclient_is_image_thumb = "psd.svg.tif.tiff.webp"; // leaving out .pdf + const static string webclient_is_image_thumb = ".psd.svg.tif.tiff.webp."; // leaving out .pdf const static string webclient_mime_photo_extensions = ".3ds.bmp.btif.cgm.cmx.djv.djvu.dwg.dxf.fbs.fh.fh4.fh5.fh7.fhc.fpx.fst.g3.gif.heic.heif.ico.ief.jpe.jpeg.jpg.ktx.mdi.mmr.npx.pbm.pct.pcx.pgm.pic.png.pnm.ppm.psd.ras.rgb.rlc.sgi.sid.svg.svgz.tga.tif.tiff.uvg.uvi.uvvg.uvvi.wbmp.wdp.webp.xbm.xif.xpm.xwd."; const static string webclient_mime_video_extensions = ".3g2.3gp.asf.asx.avi.dvb.f4v.fli.flv.fvt.h261.h263.h264.jpgm.jpgv.jpm.m1v.m2v.m4u.m4v.mj2.mjp2.mk3d.mks.mkv.mng.mov.movie.mp4.mp4v.mpe.mpeg.mpg.mpg4.mxu.ogv.pyv.qt.smv.uvh.uvm.uvp.uvs.uvu.uvv.uvvh.uvvm.uvvp.uvvs.uvvu.uvvv.viv.vob.webm.wm.wmv.wmx.wvx."; From 0d8d62440cb89f307a28909171f6477e87a8bbe8 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 09:11:19 +0200 Subject: [PATCH 03/52] Add new extension lists for audio and document node types --- src/megaclient.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index 896606a19f..ff7b1444a2 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14285,6 +14285,8 @@ namespace action_bucket_compare const static string webclient_is_image_thumb = ".psd.svg.tif.tiff.webp."; // leaving out .pdf const static string webclient_mime_photo_extensions = ".3ds.bmp.btif.cgm.cmx.djv.djvu.dwg.dxf.fbs.fh.fh4.fh5.fh7.fhc.fpx.fst.g3.gif.heic.heif.ico.ief.jpe.jpeg.jpg.ktx.mdi.mmr.npx.pbm.pct.pcx.pgm.pic.png.pnm.ppm.psd.ras.rgb.rlc.sgi.sid.svg.svgz.tga.tif.tiff.uvg.uvi.uvvg.uvvi.wbmp.wdp.webp.xbm.xif.xpm.xwd."; const static string webclient_mime_video_extensions = ".3g2.3gp.asf.asx.avi.dvb.f4v.fli.flv.fvt.h261.h263.h264.jpgm.jpgv.jpm.m1v.m2v.m4u.m4v.mj2.mjp2.mk3d.mks.mkv.mng.mov.movie.mp4.mp4v.mpe.mpeg.mpg.mpg4.mxu.ogv.pyv.qt.smv.uvh.uvm.uvp.uvs.uvu.uvv.uvvh.uvvm.uvvp.uvvs.uvvu.uvvv.viv.vob.webm.wm.wmv.wmx.wvx."; + const static string webclient_mime_audio_extensions = ".aac.adp.aif.aifc.aiff.au.caf.dra.dts.dtshd.ecelp4800.ecelp7470.ecelp9600.eol.flac.kar.lvp.m2a.m3a.m3u.m4a.mid.midi.mka.mp2.mp2a.mp3.mp4a.mpga.oga.ogg.pya.ra.ram.rip.rmi.rmp.s3m.sil.snd.spx.uva.uvva.wav.wax.weba.wma.xm."; + const static string webclient_mime_document_extensions = ".ans.ascii.doc.docx.dotx.json.log.ods.odt.pdf.pps.ppt.pptx.rtf.stc.std.stw.sti.sxc.sxd.sxi.sxm.sxw.txt.wpd.wps.xls.xlsx.xlt.xltm."; bool nodeIsVideo(const Node* n, char ext[12], const MegaClient& mc) { From 0daec9266ac2855255447bcaa7315c665386fcc7 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 09:13:00 +0200 Subject: [PATCH 04/52] Add new methods to check node types --- include/mega/megaclient.h | 12 ++++++++++ src/megaclient.cpp | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/include/mega/megaclient.h b/include/mega/megaclient.h index 728b517831..82bc3864b1 100644 --- a/include/mega/megaclient.h +++ b/include/mega/megaclient.h @@ -1250,6 +1250,18 @@ class MEGA_API MegaClient // determine if the file is a video, photo, or media (video or photo). If the extension (with trailing .) is not precalculated, pass null bool nodeIsMedia(const Node*, bool* isphoto, bool* isvideo) const; + // determine if the file is a photo. + bool nodeIsPhoto(const Node* n) const; + + // determine if the file is a video. + bool nodeIsVideo(const Node* n) const; + + // determine if the file is an audio. + bool nodeIsAudio(const Node* n) const; + + // determine if the file is a document. + bool nodeIsDocument(const Node* n) const; + // generate & return upload handle handle getuploadhandle(); diff --git a/src/megaclient.cpp b/src/megaclient.cpp index ff7b1444a2..c2dc384cc6 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14316,6 +14316,16 @@ namespace action_bucket_compare return action_bucket_compare::webclient_mime_video_extensions.find(ext) != string::npos; } + bool nodeIsAudio(const Node* n, char ext[12]) + { + return action_bucket_compare::webclient_mime_audio_extensions.find(ext) != string::npos; + } + + bool nodeIsDocument(const Node* n, char ext[12]) + { + return action_bucket_compare::webclient_mime_document_extensions.find(ext) != string::npos; + } + bool nodeIsPhoto(const Node* n, char ext[12]) { // evaluate according to the webclient rules, so that we get exactly the same bucketing. @@ -14383,6 +14393,46 @@ bool MegaClient::nodeIsMedia(const Node* n, bool* isphoto, bool* isvideo) const return false; } +bool MegaClient::nodeIsVideo(const Node* n) const +{ + char ext[12]; + if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) + { + return action_bucket_compare::nodeIsVideo(n, ext, *this); + } + return false; +} + +bool MegaClient::nodeIsPhoto(const Node* n) const +{ + char ext[12]; + if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) + { + return action_bucket_compare::nodeIsPhoto(n, ext); + } + return false; +} + +bool MegaClient::nodeIsAudio(const Node* n) const +{ + char ext[12]; + if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) + { + return action_bucket_compare::nodeIsAudio(n, ext); + } + return false; +} + +bool MegaClient::nodeIsDocument(const Node* n) const +{ + char ext[12]; + if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) + { + return action_bucket_compare::nodeIsDocument(n, ext); + } + return false; +} + recentactions_vector MegaClient::getRecentActions(unsigned maxcount, m_time_t since) { recentactions_vector rav; From a96045236808ff97476f0d2516c9fb62caa8fba2 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 10:44:15 +0200 Subject: [PATCH 05/52] Check node type in SearchTreeProcessor - Add new enum type --- include/megaapi.h | 3 +++ include/megaapi_impl.h | 7 +++++-- src/megaapi_impl.cpp | 41 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index 26d04ade33..facd5b8771 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -13095,6 +13095,9 @@ class MegaApi ORDER_VIDEO_ASC, ORDER_VIDEO_DESC, ORDER_LINK_CREATION_ASC, ORDER_LINK_CREATION_DESC,}; + typedef enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, + NODE_VIDEO, NODE_DOCUMENT,} nodefiletype_t; + /** * @brief Get the number of child nodes * diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 18ff995d56..18787c3f7e 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -1881,14 +1881,17 @@ class TreeProcessor class SearchTreeProcessor : public TreeProcessor { public: - SearchTreeProcessor(const char *search); - virtual bool processNode(Node* node); + SearchTreeProcessor(MegaClient *client, const char *search, MegaApi::nodefiletype_t type); + virtual bool processNode(Node *node); + bool isValidTypeNode(Node *node); virtual ~SearchTreeProcessor() {} vector &getResults(); protected: + MegaApi::nodefiletype_t type; const char *search; vector results; + MegaClient *client; }; class OutShareProcessor : public TreeProcessor diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 71f41d38d0..24a8655b7c 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11728,7 +11728,12 @@ MegaNode *MegaApiImpl::getNodeByCRC(const char *crc, MegaNode *parent) return NULL; } -SearchTreeProcessor::SearchTreeProcessor(const char *search) { this->search = search; } +SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, MegaApi::nodefiletype_t type) +{ + this->search = search; + this->type = type; + this->client = client; +} #if defined(_WIN32) || defined(__APPLE__) @@ -11763,19 +11768,47 @@ bool SearchTreeProcessor::processNode(Node* node) return true; } - if (!search) + if (!search && (!client || (type < MegaApi::NODE_UNKNOWN || type > MegaApi::NODE_DOCUMENT))) { + // If no search string provided, client and type must be valid, otherwise return false return false; } - if (node->type <= FOLDERNODE && strcasestr(node->displayname(), search) != NULL) + if (node->type <= FOLDERNODE && (!search || strcasestr(node->displayname(), search) != NULL)) { - results.push_back(node); + if (isValidTypeNode(node)) + { + results.push_back(node); + } } return true; } +bool SearchTreeProcessor::isValidTypeNode(Node *node) +{ + assert(node); + if (!client) + { + return true; + } + + switch (type) + { + case MegaApi::NODE_PHOTO: + return client->nodeIsPhoto(node); + case MegaApi::NODE_AUDIO: + return client->nodeIsAudio(node); + case MegaApi::NODE_VIDEO: + return client->nodeIsVideo(node); + case MegaApi::NODE_DOCUMENT: + return client->nodeIsDocument(node); + case MegaApi::NODE_UNKNOWN: + default: + return true; + } +} + vector &SearchTreeProcessor::getResults() { return results; From 9eb4a98dc24cfc09ad2a23cd1406cd1418293c0e Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 11:47:56 +0200 Subject: [PATCH 06/52] Refactor internal node search methods to accept type parameter --- include/megaapi_impl.h | 6 +++--- src/megaapi_impl.cpp | 27 ++++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 18787c3f7e..aaac22589f 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -2421,11 +2421,11 @@ class MegaApiImpl : public MegaApp MegaRecentActionBucketList* getRecentActions(unsigned days = 90, unsigned maxnodes = 10000); - MegaNodeList* search(MegaNode* node, const char* searchString, MegaCancelToken *cancelToken, bool recursive = 1, int order = MegaApi::ORDER_NONE); + MegaNodeList* search(MegaNode* node, const char* searchString, MegaCancelToken *cancelToken, bool recursive = 1, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); bool processMegaTree(MegaNode* node, MegaTreeProcessor* processor, bool recursive = 1); - MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE); + MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); - MegaNodeList* searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target); + MegaNodeList* searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target, int type = MegaApi::NODE_UNKNOWN); MegaNode *createForeignFileNode(MegaHandle handle, const char *key, const char *name, m_off_t size, m_off_t mtime, MegaHandle parentHandle, const char *privateauth, const char *publicauth, const char *chatauth); diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 24a8655b7c..5126d0b0bc 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10772,10 +10772,11 @@ bool MegaApiImpl::processMegaTree(MegaNode* n, MegaTreeProcessor* processor, boo return result; } -MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target) +MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target, int type) { - if (!searchString) + if (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) { + // If no search string and type is not valid return new MegaNodeListPrivate(); } @@ -10808,7 +10809,7 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(searchString); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -10821,7 +10822,7 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance && !(cancelToken && cancelToken->isCancelled()); it++) { node = client->nodebyhandle(it->first); - SearchTreeProcessor searchProcessor(searchString); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -10833,10 +10834,11 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance return nodeList; } -MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *cancelToken, int order) +MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { - if(!searchString) + if (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) { + // If no search string and type is not valid return new MegaNodeListPrivate(); } @@ -10860,11 +10862,9 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(client->rootnodes[i]); - - SearchTreeProcessor searchProcessor(searchString); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); node_vector& vNodes = searchProcessor.getResults(); - result.insert(result.end(), vNodes.begin(), vNodes.end()); } @@ -10874,7 +10874,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(searchString); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11376,10 +11376,11 @@ bool MegaApiImpl::processTree(Node* node, TreeProcessor* processor, bool recursi return result; } -MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order) +MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type) { - if (!n || !searchString) + if (!n || (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT))) { + // If node is not valid or no search string and type is not valid return new MegaNodeListPrivate(); } @@ -11401,7 +11402,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCan return new MegaNodeListPrivate(); } - SearchTreeProcessor searchProcessor(searchString); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); for (node_list::iterator it = node->children.begin(); it != node->children.end() && !(cancelToken && cancelToken->isCancelled()); ) { From 37a5e827427da2ccf2111867419e8daac926f423 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 13:04:09 +0200 Subject: [PATCH 07/52] Return an empty list if nodetype and order are incompatibles In example node type NODE_PHOTO and order ORDER_VIDEO_ASC are incompatible --- src/megaapi_impl.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 5126d0b0bc..96fc8bc092 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10780,6 +10780,12 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance return new MegaNodeListPrivate(); } + if (type != MegaApi::NODE_UNKNOWN + && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) + { + return new MegaNodeListPrivate(); + } + if (cancelToken && cancelToken->isCancelled()) { return new MegaNodeListPrivate(); @@ -10842,6 +10848,12 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can return new MegaNodeListPrivate(); } + if (type != MegaApi::NODE_UNKNOWN + && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) + { + return new MegaNodeListPrivate(); + } + if (cancelToken && cancelToken->isCancelled()) { return new MegaNodeListPrivate(); @@ -11384,6 +11396,12 @@ MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCan return new MegaNodeListPrivate(); } + if (type != MegaApi::NODE_UNKNOWN + && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) + { + return new MegaNodeListPrivate(); + } + if (cancelToken && cancelToken->isCancelled()) { return new MegaNodeListPrivate(); From 7885a63ae2754f91306892fd907c0c1e9a17d744 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 30 Jul 2020 15:04:47 +0200 Subject: [PATCH 08/52] Add new MegaApi public interfaces for search nodes by type --- include/megaapi.h | 415 ++++++++++++++++++++++++++++++++++++++++++++++ src/megaapi.cpp | 25 +++ 2 files changed, 440 insertions(+) diff --git a/include/megaapi.h b/include/megaapi.h index facd5b8771..65cc42b720 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14546,6 +14546,421 @@ class MegaApi */ MegaNodeList* searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE); + /** + * @brief Search nodes containing a search string in their name and allow to filter by the type of the node + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * this method will return a list that contains nodes of the same type as provided. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: + * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param recursive True if you want to seach recursively in the node tree. + * False if you want to seach in the children of the node only + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 + * Same behavior than MegaApi::ORDER_DEFAULT_ASC + * + * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 + * Same behavior than MegaApi::ORDER_DEFAULT_DESC + * + * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC + * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. + * They will be eventually removed. + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_PHOTO = 1 + * - MegaApi::NODE_AUDIO = 2 + * - MegaApi::NODE_VIDEO = 3 + * - MegaApi::NODE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ + MegaNodeList* searchByType(MegaNode* node, const char* searchString, MegaCancelToken *cancelToken, bool recursive = 1, int order = ORDER_NONE, int type = NODE_UNKNOWN); + + /** + * @brief Search nodes containing a search string in their name + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * this method will return a list that contains nodes of the same type as provided. + * + * The search will consider every accessible node for the account: + * - Cloud drive + * - Inbox + * - Rubbish bin + * - Incoming shares from other users + * + * You take the ownership of the returned value. + * + * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: + * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * @param searchString Search string. The search is case-insensitive + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 + * Same behavior than MegaApi::ORDER_DEFAULT_ASC + * + * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 + * Same behavior than MegaApi::ORDER_DEFAULT_DESC + * + * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC + * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. + * They will be eventually removed. + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_PHOTO = 1 + * - MegaApi::NODE_AUDIO = 2 + * - MegaApi::NODE_VIDEO = 3 + * - MegaApi::NODE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ + MegaNodeList* searchByType(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); + + /** + * @brief Search nodes on incoming shares containing a search string in their name + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * this method will return a list that contains nodes of the same type as provided. + * + * The method will search exclusively on incoming shares + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * You take the ownership of the returned value. + * + * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: + * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 + * Same behavior than MegaApi::ORDER_DEFAULT_ASC + * + * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 + * Same behavior than MegaApi::ORDER_DEFAULT_DESC + * + * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC + * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. + * They will be eventually removed. + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_PHOTO = 1 + * - MegaApi::NODE_AUDIO = 2 + * - MegaApi::NODE_VIDEO = 3 + * - MegaApi::NODE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ + MegaNodeList* searchOnInSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); + + /** + * @brief Search nodes on outbound shares containing a search string in their name + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * this method will return a list that contains nodes of the same type as provided. + * + * The method will search exclusively on outbound shares + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * You take the ownership of the returned value. + * + * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: + * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 + * Same behavior than MegaApi::ORDER_DEFAULT_ASC + * + * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 + * Same behavior than MegaApi::ORDER_DEFAULT_DESC + * + * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC + * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. + * They will be eventually removed. + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_PHOTO = 1 + * - MegaApi::NODE_AUDIO = 2 + * - MegaApi::NODE_VIDEO = 3 + * - MegaApi::NODE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ + MegaNodeList* searchOnOutSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); + + /** + * @brief Search nodes on public links shares containing a search string in their name + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * this method will return a list that contains nodes of the same type as provided. + * + * The method will search exclusively on public links shares + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * You take the ownership of the returned value. + * + * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: + * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 + * Same behavior than MegaApi::ORDER_DEFAULT_ASC + * + * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 + * Same behavior than MegaApi::ORDER_DEFAULT_DESC + * + * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC + * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. + * They will be eventually removed. + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_PHOTO = 1 + * - MegaApi::NODE_AUDIO = 2 + * - MegaApi::NODE_VIDEO = 3 + * - MegaApi::NODE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ + MegaNodeList* searchOnPublicLinksBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); + /** * @brief Return a list of buckets, each bucket containing a list of recently added/modified nodes * diff --git a/src/megaapi.cpp b/src/megaapi.cpp index d8ae64dc59..5a922f8ed1 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3748,6 +3748,31 @@ MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelT return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_PUBLICLINK); } +MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type) +{ + return pImpl->search(n, searchString, cancelToken, recursive, order, type); +} + +MegaNodeList* MegaApi::searchByType(const char *searchString, MegaCancelToken *cancelToken, int order, int type) +{ + return pImpl->search(searchString, cancelToken, order, type); +} + +MegaNodeList* MegaApi::searchOnInSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) +{ + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_INSHARE, type); +} + +MegaNodeList* MegaApi::searchOnOutSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) +{ + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_OUTSHARE, type); +} + +MegaNodeList* MegaApi::searchOnPublicLinksBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) +{ + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_PUBLICLINK, type); +} + long long MegaApi::getSize(MegaNode *n) { return pImpl->getSize(n); From 6b761227b50d8d565394bc8068e2b174ec679f75 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 20 Aug 2020 11:30:19 +0200 Subject: [PATCH 09/52] Update extensions lists --- src/megaclient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index c2dc384cc6..a07c3dc557 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14285,8 +14285,8 @@ namespace action_bucket_compare const static string webclient_is_image_thumb = ".psd.svg.tif.tiff.webp."; // leaving out .pdf const static string webclient_mime_photo_extensions = ".3ds.bmp.btif.cgm.cmx.djv.djvu.dwg.dxf.fbs.fh.fh4.fh5.fh7.fhc.fpx.fst.g3.gif.heic.heif.ico.ief.jpe.jpeg.jpg.ktx.mdi.mmr.npx.pbm.pct.pcx.pgm.pic.png.pnm.ppm.psd.ras.rgb.rlc.sgi.sid.svg.svgz.tga.tif.tiff.uvg.uvi.uvvg.uvvi.wbmp.wdp.webp.xbm.xif.xpm.xwd."; const static string webclient_mime_video_extensions = ".3g2.3gp.asf.asx.avi.dvb.f4v.fli.flv.fvt.h261.h263.h264.jpgm.jpgv.jpm.m1v.m2v.m4u.m4v.mj2.mjp2.mk3d.mks.mkv.mng.mov.movie.mp4.mp4v.mpe.mpeg.mpg.mpg4.mxu.ogv.pyv.qt.smv.uvh.uvm.uvp.uvs.uvu.uvv.uvvh.uvvm.uvvp.uvvs.uvvu.uvvv.viv.vob.webm.wm.wmv.wmx.wvx."; - const static string webclient_mime_audio_extensions = ".aac.adp.aif.aifc.aiff.au.caf.dra.dts.dtshd.ecelp4800.ecelp7470.ecelp9600.eol.flac.kar.lvp.m2a.m3a.m3u.m4a.mid.midi.mka.mp2.mp2a.mp3.mp4a.mpga.oga.ogg.pya.ra.ram.rip.rmi.rmp.s3m.sil.snd.spx.uva.uvva.wav.wax.weba.wma.xm."; - const static string webclient_mime_document_extensions = ".ans.ascii.doc.docx.dotx.json.log.ods.odt.pdf.pps.ppt.pptx.rtf.stc.std.stw.sti.sxc.sxd.sxi.sxm.sxw.txt.wpd.wps.xls.xlsx.xlt.xltm."; + const static string webclient_mime_audio_extensions = ".3ga.aac.adp.aif.aifc.aiff.au.caf.dra.dts.dtshd.ecelp4800.ecelp7470.ecelp9600.eol.flac.iff.kar.lvp.m2a.m3a.m3u.m4a.mid.midi.mka.mp2.mp2a.mp3.mp4a.mpga.oga.ogg.opus.pya.ra.ram.rip.rmi.rmp.s3m.sil.snd.spx.uva.uvva.wav.wax.weba.wma.xm."; + const static string webclient_mime_document_extensions = ".ans.ascii.doc.docx.dotx.json.log.ods.odt.pages.pdf.ppc.pps.ppt.pptx.rtf.stc.std.stw.sti.sxc.sxd.sxi.sxm.sxw.txt.wpd.wps.xls.xlsx.xlt.xltm."; bool nodeIsVideo(const Node* n, char ext[12], const MegaClient& mc) { From 2dd6a600f5304d2db8fc789498a0a6b46c674de7 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 20 Aug 2020 14:42:50 +0200 Subject: [PATCH 10/52] Add constant for max extension length getextension methods have a parameter to specify max extension length. In current code, this parameter is set to 8 characters, in most of the places where method is called, and some sopported extensions like `ecelp4800` are longer than 8 chars. We are going to add a new constant to unify this max extension len, and make easier to modify it, if longer extensions are added in the future. --- include/mega/types.h | 3 +++ src/gfx.cpp | 4 ++-- src/gfx/freeimage.cpp | 4 ++-- src/mediafileattribute.cpp | 2 +- src/megaapi_impl.cpp | 8 ++++---- src/megaclient.cpp | 2 +- src/transfer.cpp | 2 +- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mega/types.h b/include/mega/types.h index 825579871b..f436fc0cbe 100644 --- a/include/mega/types.h +++ b/include/mega/types.h @@ -275,6 +275,9 @@ typedef enum { TYPE_UNKNOWN = -1, FILENODE = 0, FOLDERNODE, ROOTNODE, INCOMINGNO const int FILENODEKEYLENGTH = 32; const int FOLDERNODEKEYLENGTH = 16; +// Max file extension length +const int MAXEXTENSIONLEN = 12; + typedef list sync_list; // persistent resource cache storage diff --git a/src/gfx.cpp b/src/gfx.cpp index 20bbf2e839..1b7fb4524c 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -34,7 +34,7 @@ const int GfxProc::dimensionsavatar[][2] = { bool GfxProc::isgfx(string* localfilename) { - char ext[8]; + char ext[MAXEXTENSIONLEN]; const char* supported; if (!(supported = supportedformats())) @@ -58,7 +58,7 @@ bool GfxProc::isgfx(string* localfilename) bool GfxProc::isvideo(string *localfilename) { - char ext[8]; + char ext[MAXEXTENSIONLEN]; const char* supported; if (!(supported = supportedvideoformats())) diff --git a/src/gfx/freeimage.cpp b/src/gfx/freeimage.cpp index 16f4f2cbb0..359302b574 100644 --- a/src/gfx/freeimage.cpp +++ b/src/gfx/freeimage.cpp @@ -250,7 +250,7 @@ bool GfxProcFreeImage::readbitmapFfmpeg(FileAccess* fa, string* imagePath, int s seek_target = av_rescale_q(formatContext->duration / 5, av_get_time_base_q(), videoStream->time_base); } - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (client->fsaccess->getextension(LocalPath::fromLocalname(*imagePath),ext,8) && strcmp(ext,".mp3") && seek_target > 0 @@ -405,7 +405,7 @@ bool GfxProcFreeImage::readbitmap(FileAccess* fa, string* localname, int size) #endif #ifdef HAVE_FFMPEG - char ext[8]; + char ext[MAXEXTENSIONLEN]; bool isvideo = false; if (client->fsaccess->getextension(LocalPath::fromLocalname(*localname), ext, sizeof ext)) { diff --git a/src/mediafileattribute.cpp b/src/mediafileattribute.cpp index 2e757a2f63..1450334d69 100644 --- a/src/mediafileattribute.cpp +++ b/src/mediafileattribute.cpp @@ -78,7 +78,7 @@ void MediaFileInfo::requestCodecMappingsOneTime(MegaClient* client, LocalPath* i { if (ifSuitableFilename) { - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (!client->fsaccess->getextension(*ifSuitableFilename, ext, sizeof(ext)) || !MediaProperties::isMediaFilenameExt(ext)) { diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 96fc8bc092..0850c2420c 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -1049,7 +1049,7 @@ bool MegaBackgroundMediaUploadPrivate::analyseMediaInfo(const char* inputFilepat auto localfilename = LocalPath::fromPath(inputFilepath, *api->fsAccess); - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (api->fsAccess->getextension(localfilename, ext, sizeof(ext)) && MediaProperties::isMediaFilenameExt(ext)) { mediaproperties.extractMediaPropertyFileAttributes(localfilename, api->fsAccess); @@ -27053,7 +27053,7 @@ int MegaHTTPServer::onBody(http_parser *parser, const char *b, size_t n) httpctx->server->fsAccess->tmpnamelocal(suffix); httpctx->tmpFileName.append(suffix.toPath(*httpctx->server->fsAccess)); - char ext[8]; + char ext[MAXEXTENSIONLEN]; LocalPath localpath = LocalPath::fromPath(httpctx->path, *httpctx->server->fsAccess); if (httpctx->server->fsAccess->getextension(localpath, ext, sizeof ext)) { @@ -28111,7 +28111,7 @@ int MegaHTTPServer::onMessageComplete(http_parser *parser) httpctx->tmpFileName=httpctx->server->basePath; httpctx->tmpFileName.append("httputfile"); httpctx->tmpFileName.append(LocalPath::tmpNameLocal(*httpctx->server->fsAccess).toPath(*httpctx->server->fsAccess)); - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (httpctx->server->fsAccess->getextension(LocalPath::fromPath(httpctx->path, *httpctx->server->fsAccess), ext, sizeof ext)) { httpctx->tmpFileName.append(ext); @@ -30819,7 +30819,7 @@ void MegaFTPDataServer::processReceivedData(MegaTCPContext *tcpctx, ssize_t nrea fds->fsAccess->tmpnamelocal(suffix); ftpdatactx->tmpFileName.append(suffix.toPath(*fds->fsAccess)); - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (ftpdatactx->server->fsAccess->getextension(LocalPath::fromPath(fds->controlftpctx->arg1, *ftpdatactx->server->fsAccess), ext, sizeof ext)) { ftpdatactx->tmpFileName.append(ext); diff --git a/src/megaclient.cpp b/src/megaclient.cpp index a07c3dc557..bf202fd770 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14358,7 +14358,7 @@ namespace action_bucket_compare bool getExtensionDotted(const Node* n, char ext[12], const MegaClient& mc) { auto localname = LocalPath::fromPath(n->displayname(), *mc.fsaccess); - if (mc.fsaccess->getextension(localname, ext, 8)) // plenty of buffer space left to append a '.' + if (mc.fsaccess->getextension(localname, ext, MAXEXTENSIONLEN)) // plenty of buffer space left to append a '.' { strcat(ext, "."); return true; diff --git a/src/transfer.cpp b/src/transfer.cpp index cca3998a5a..b612cd6911 100644 --- a/src/transfer.cpp +++ b/src/transfer.cpp @@ -548,7 +548,7 @@ void Transfer::addAnyMissingMediaFileAttributes(Node* node, /*const*/ LocalPath& assert(type == PUT || (node && node->type == FILENODE)); #ifdef USE_MEDIAINFO - char ext[8]; + char ext[MAXEXTENSIONLEN]; if (((type == PUT && size >= 16) || (node && node->nodekey().size() == FILENODEKEYLENGTH && node->size >= 16)) && client->fsaccess->getextension(localpath, ext, sizeof(ext)) && MediaProperties::isMediaFilenameExt(ext) && From 5f3dc7925d10670ea9c377d2c24a86e906f516e2 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 09:37:32 +0200 Subject: [PATCH 11/52] Add flag to checkPreview in method nodeIsPhoto --- include/mega/megaclient.h | 2 +- src/megaapi_impl.cpp | 2 +- src/megaclient.cpp | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/mega/megaclient.h b/include/mega/megaclient.h index 82bc3864b1..5ed6da17d8 100644 --- a/include/mega/megaclient.h +++ b/include/mega/megaclient.h @@ -1251,7 +1251,7 @@ class MEGA_API MegaClient bool nodeIsMedia(const Node*, bool* isphoto, bool* isvideo) const; // determine if the file is a photo. - bool nodeIsPhoto(const Node* n) const; + bool nodeIsPhoto(const Node* n, bool checkPreview) const; // determine if the file is a video. bool nodeIsVideo(const Node* n) const; diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 0850c2420c..d58d857337 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11815,7 +11815,7 @@ bool SearchTreeProcessor::isValidTypeNode(Node *node) switch (type) { case MegaApi::NODE_PHOTO: - return client->nodeIsPhoto(node); + return client->nodeIsPhoto(node, false); case MegaApi::NODE_AUDIO: return client->nodeIsAudio(node); case MegaApi::NODE_VIDEO: diff --git a/src/megaclient.cpp b/src/megaclient.cpp index bf202fd770..8932a5cfc8 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14326,12 +14326,13 @@ namespace action_bucket_compare return action_bucket_compare::webclient_mime_document_extensions.find(ext) != string::npos; } - bool nodeIsPhoto(const Node* n, char ext[12]) + bool nodeIsPhoto(const Node* n, char ext[12], bool checkPreview) { // evaluate according to the webclient rules, so that we get exactly the same bucketing. return action_bucket_compare::webclient_is_image_def.find(ext) != string::npos || action_bucket_compare::webclient_is_image_raw.find(ext) != string::npos || - (action_bucket_compare::webclient_mime_photo_extensions.find(ext) != string::npos && n->hasfileattribute(GfxProc::PREVIEW)); + (action_bucket_compare::webclient_mime_photo_extensions.find(ext) != string::npos + && (!checkPreview || n->hasfileattribute(GfxProc::PREVIEW))); } static bool compare(const Node* a, const Node* b, MegaClient* mc) @@ -14374,7 +14375,7 @@ bool MegaClient::nodeIsMedia(const Node* n, bool* isphoto, bool* isvideo) const char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { - bool a = action_bucket_compare::nodeIsPhoto(n, ext); + bool a = action_bucket_compare::nodeIsPhoto(n, ext, true); if (isphoto) { *isphoto = a; @@ -14403,12 +14404,12 @@ bool MegaClient::nodeIsVideo(const Node* n) const return false; } -bool MegaClient::nodeIsPhoto(const Node* n) const +bool MegaClient::nodeIsPhoto(const Node* n, bool checkPreview) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { - return action_bucket_compare::nodeIsPhoto(n, ext); + return action_bucket_compare::nodeIsPhoto(n, ext, checkPreview); } return false; } From d4c952f2a34d289491caf8ce2f7387091ee9c182 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 11:06:46 +0200 Subject: [PATCH 12/52] Fix condition If node and searchstring are not provided, and node type is not valid return an empty list --- src/megaapi_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index d58d857337..87c90c1455 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11390,7 +11390,7 @@ bool MegaApiImpl::processTree(Node* node, TreeProcessor* processor, bool recursi MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type) { - if (!n || (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT))) + if (!n && !searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) { // If node is not valid or no search string and type is not valid return new MegaNodeListPrivate(); From df878f66cf0683115432833658d9d9b6aef72c3d Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 11:34:47 +0200 Subject: [PATCH 13/52] Improve MegaApiImpl::search method If node is provided, it will be the parent node of the tree to explore, search string and/or nodeType can be added to search parameters If node is not provided search will consider every accessible node for the account and search string and/or nodeType can be added to search parameters If node and searchString are not provided, and node type is not valid, this method will return an empty list Both search types can be performed recursively or not --- src/megaapi_impl.cpp | 60 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 87c90c1455..f15398d5c4 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11414,23 +11414,59 @@ MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCan return new MegaNodeListPrivate(); } - Node *node = client->nodebyhandle(n->getHandle()); - if (!node) + MegaNodeList *nodeList = nullptr; + if (n) { - return new MegaNodeListPrivate(); - } + Node *node = client->nodebyhandle(n->getHandle()); + if (!node) + { + return new MegaNodeListPrivate(); + } - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - for (node_list::iterator it = node->children.begin(); it != node->children.end() - && !(cancelToken && cancelToken->isCancelled()); ) - { - processTree(*it++, &searchProcessor, recursive, cancelToken); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + for (node_list::iterator it = node->children.begin(); it != node->children.end() + && !(cancelToken && cancelToken->isCancelled()); ) + { + processTree(*it++, &searchProcessor, recursive, cancelToken); + } + + vector& vNodes = searchProcessor.getResults(); + sortByComparatorFunction(vNodes, order, *client); + nodeList = new MegaNodeListPrivate(vNodes.data(), int(vNodes.size())); } + else + { + node_vector result; + Node *node; + + // rootnodes + for (unsigned int i = 0; i < (sizeof client->rootnodes / sizeof *client->rootnodes) + && !(cancelToken && cancelToken->isCancelled()); i++) + { + node = client->nodebyhandle(client->rootnodes[i]); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + node_vector& vNodes = searchProcessor.getResults(); + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } - vector& vNodes = searchProcessor.getResults(); - sortByComparatorFunction(vNodes, order, *client); + // inshares + MegaShareList *shares = getInSharesList(MegaApi::ORDER_NONE); + for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) + { + node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - MegaNodeList *nodeList = new MegaNodeListPrivate(vNodes.data(), int(vNodes.size())); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + vector& vNodes = searchProcessor.getResults(); + + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } + delete shares; + + sortByComparatorFunction(result, order, *client); + nodeList = new MegaNodeListPrivate(result.data(), int(result.size())); + } return nodeList; } From a65248bf7cef683957d2be05ecbef8d7299c9c3f Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 12:57:59 +0200 Subject: [PATCH 14/52] Add searchtarget_t enum Minor style adjustments --- include/megaapi.h | 5 ++++- include/megaapi_impl.h | 4 +--- src/megaapi.cpp | 16 ++++++++-------- src/megaapi_impl.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index 65cc42b720..55f6155eca 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -13098,6 +13098,9 @@ class MegaApi typedef enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, NODE_VIDEO, NODE_DOCUMENT,} nodefiletype_t; + typedef enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, + TARGET_ROOTNODES, TARGET_ALL } searchtarget_t; + /** * @brief Get the number of child nodes * @@ -14628,7 +14631,7 @@ class MegaApi * * @return List of nodes that match with the search parameters */ - MegaNodeList* searchByType(MegaNode* node, const char* searchString, MegaCancelToken *cancelToken, bool recursive = 1, int order = ORDER_NONE, int type = NODE_UNKNOWN); + MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); /** * @brief Search nodes containing a search string in their name diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index aaac22589f..d2477ed0e9 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -2008,8 +2008,6 @@ class MegaApiImpl : public MegaApp static MegaApiImpl* ImplOf(MegaApi*); - enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, }; - //Multiple listener management. void addListener(MegaListener* listener); void addRequestListener(MegaRequestListener* listener); @@ -2421,7 +2419,7 @@ class MegaApiImpl : public MegaApp MegaRecentActionBucketList* getRecentActions(unsigned days = 90, unsigned maxnodes = 10000); - MegaNodeList* search(MegaNode* node, const char* searchString, MegaCancelToken *cancelToken, bool recursive = 1, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); + MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN, int target = MegaApi::TARGET_ALL); bool processMegaTree(MegaNode* node, MegaTreeProcessor* processor, bool recursive = 1); MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); diff --git a/src/megaapi.cpp b/src/megaapi.cpp index 5a922f8ed1..58edd4ebb4 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3735,22 +3735,22 @@ MegaNodeList *MegaApi::search(const char *searchString, MegaCancelToken *cancelT MegaNodeList* MegaApi::searchOnInShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_INSHARE); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_INSHARE); } MegaNodeList* MegaApi::searchOnOutShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_OUTSHARE); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_OUTSHARE); } MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_PUBLICLINK); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK); } -MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type) +MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) { - return pImpl->search(n, searchString, cancelToken, recursive, order, type); + return pImpl->search(n, searchString, cancelToken, recursive, order, type, target); } MegaNodeList* MegaApi::searchByType(const char *searchString, MegaCancelToken *cancelToken, int order, int type) @@ -3760,17 +3760,17 @@ MegaNodeList* MegaApi::searchByType(const char *searchString, MegaCancelToken *c MegaNodeList* MegaApi::searchOnInSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_INSHARE, type); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_INSHARE, type); } MegaNodeList* MegaApi::searchOnOutSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_OUTSHARE, type); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_OUTSHARE, type); } MegaNodeList* MegaApi::searchOnPublicLinksBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApiImpl::TARGET_PUBLICLINK, type); + return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK, type); } long long MegaApi::getSize(MegaNode *n) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index f15398d5c4..2f59f8e551 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10791,7 +10791,7 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance return new MegaNodeListPrivate(); } - if (target < TARGET_INSHARE || target > TARGET_PUBLICLINK) + if (target < MegaApi::TARGET_INSHARE || target > MegaApi::TARGET_PUBLICLINK) { return new MegaNodeListPrivate(); } @@ -10805,10 +10805,10 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance node_vector result; Node *node; - if (target == TARGET_INSHARE || target == TARGET_OUTSHARE) + if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_OUTSHARE) { // Search in inShares or outShares - ::mega::unique_ptr shares (target == TARGET_INSHARE + ::mega::unique_ptr shares (target == MegaApi::TARGET_INSHARE ? getInSharesList(MegaApi::ORDER_NONE) : getOutShares(MegaApi::ORDER_NONE)); @@ -11388,7 +11388,7 @@ bool MegaApiImpl::processTree(Node* node, TreeProcessor* processor, bool recursi return result; } -MegaNodeList* MegaApiImpl::search(MegaNode* n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type) +MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) { if (!n && !searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) { From 2dd8d36b5c5557528de9c6ed17183cbe6c4f36a8 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 13:09:02 +0200 Subject: [PATCH 15/52] Allow to filter search by target If node is not specified this method will search in rootnodes, inshares, outshares and public links by default. If target is specified the search will be restricted to the target type. --- src/megaapi_impl.cpp | 79 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 2f59f8e551..6795c052f3 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11417,12 +11417,14 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan MegaNodeList *nodeList = nullptr; if (n) { + // if node is provided, it will be the parent node of the tree to explore Node *node = client->nodebyhandle(n->getHandle()); if (!node) { return new MegaNodeListPrivate(); } + // searchString and nodeType (if provided), are considered in search SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); for (node_list::iterator it = node->children.begin(); it != node->children.end() && !(cancelToken && cancelToken->isCancelled()); ) @@ -11439,30 +11441,73 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan node_vector result; Node *node; - // rootnodes - for (unsigned int i = 0; i < (sizeof client->rootnodes / sizeof *client->rootnodes) - && !(cancelToken && cancelToken->isCancelled()); i++) + // Target parameter is only considered if node is not provided + if (target < MegaApi::TARGET_INSHARE || target > MegaApi::TARGET_ALL) { - node = client->nodebyhandle(client->rootnodes[i]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - processTree(node, &searchProcessor, recursive, cancelToken); - node_vector& vNodes = searchProcessor.getResults(); - result.insert(result.end(), vNodes.begin(), vNodes.end()); + return new MegaNodeListPrivate(); } - // inshares - MegaShareList *shares = getInSharesList(MegaApi::ORDER_NONE); - for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) + if (target == MegaApi::TARGET_ROOTNODES || target == MegaApi::TARGET_ALL) { - node = client->nodebyhandle(shares->get(i)->getNodeHandle()); + // Search on rootnodes + for (unsigned int i = 0; i < (sizeof client->rootnodes / sizeof *client->rootnodes) + && !(cancelToken && cancelToken->isCancelled()); i++) + { + node = client->nodebyhandle(client->rootnodes[i]); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + node_vector& vNodes = searchProcessor.getResults(); + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } + } - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - processTree(node, &searchProcessor, recursive, cancelToken); - vector& vNodes = searchProcessor.getResults(); + if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_ALL) + { + // Search on inshares + MegaShareList *shares = getInSharesList(MegaApi::ORDER_NONE); + for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) + { + node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - result.insert(result.end(), vNodes.begin(), vNodes.end()); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + vector& vNodes = searchProcessor.getResults(); + + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } + delete shares; + } + + if (target == MegaApi::TARGET_OUTSHARE || target == MegaApi::TARGET_ALL) + { + // Search on outshares + MegaShareList *shares = getOutShares(MegaApi::ORDER_NONE); + for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) + { + node = client->nodebyhandle(shares->get(i)->getNodeHandle()); + + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + vector& vNodes = searchProcessor.getResults(); + + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } + delete shares; + } + + if (target == MegaApi::TARGET_PUBLICLINK || target == MegaApi::TARGET_ALL) + { + // Search on public links + for (auto it = client->mPublicLinks.begin(); it != client->mPublicLinks.end() + && !(cancelToken && cancelToken->isCancelled()); it++) + { + node = client->nodebyhandle(it->first); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, true, cancelToken); + vector& vNodes = searchProcessor.getResults(); + result.insert(result.end(), vNodes.begin(), vNodes.end()); + } } - delete shares; sortByComparatorFunction(result, order, *client); nodeList = new MegaNodeListPrivate(result.data(), int(result.size())); From 19357ad5f7b0051c3583afd52434a5e4ab80e691 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 14:06:31 +0200 Subject: [PATCH 16/52] Remove unneeded methods --- include/megaapi.h | 333 +--------------------------------------------- src/megaapi.cpp | 22 +-- 2 files changed, 2 insertions(+), 353 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index 55f6155eca..1b8f3032e6 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14631,338 +14631,7 @@ class MegaApi * * @return List of nodes that match with the search parameters */ - MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); - - /** - * @brief Search nodes containing a search string in their name - * - * The search is case-insensitive. If the search string is not provided but type has any value - * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), - * this method will return a list that contains nodes of the same type as provided. - * - * The search will consider every accessible node for the account: - * - Cloud drive - * - Inbox - * - Rubbish bin - * - Incoming shares from other users - * - * You take the ownership of the returned value. - * - * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: - * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC - * - * @param searchString Search string. The search is case-insensitive - * @param order Order for the returned list - * Valid values for this parameter are: - * - MegaApi::ORDER_NONE = 0 - * Undefined order - * - * - MegaApi::ORDER_DEFAULT_ASC = 1 - * Folders first in alphabetical order, then files in the same order - * - * - MegaApi::ORDER_DEFAULT_DESC = 2 - * Files first in reverse alphabetical order, then folders in the same order - * - * - MegaApi::ORDER_SIZE_ASC = 3 - * Sort by size, ascending - * - * - MegaApi::ORDER_SIZE_DESC = 4 - * Sort by size, descending - * - * - MegaApi::ORDER_CREATION_ASC = 5 - * Sort by creation time in MEGA, ascending - * - * - MegaApi::ORDER_CREATION_DESC = 6 - * Sort by creation time in MEGA, descending - * - * - MegaApi::ORDER_MODIFICATION_ASC = 7 - * Sort by modification time of the original file, ascending - * - * - MegaApi::ORDER_MODIFICATION_DESC = 8 - * Sort by modification time of the original file, descending - * - * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 - * Same behavior than MegaApi::ORDER_DEFAULT_ASC - * - * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 - * Same behavior than MegaApi::ORDER_DEFAULT_DESC - * - * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC - * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. - * They will be eventually removed. - * - * - MegaApi::ORDER_PHOTO_ASC = 11 - * Sort with photos first, then by date ascending - * - * - MegaApi::ORDER_PHOTO_DESC = 12 - * Sort with photos first, then by date descending - * - * - MegaApi::ORDER_VIDEO_ASC = 13 - * Sort with videos first, then by date ascending - * - * - MegaApi::ORDER_VIDEO_DESC = 14 - * Sort with videos first, then by date descending - * - * @param type Type of nodes requested in the search - * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 - * - MegaApi::NODE_PHOTO = 1 - * - MegaApi::NODE_AUDIO = 2 - * - MegaApi::NODE_VIDEO = 3 - * - MegaApi::NODE_DOCUMENT = 4 - * - * @return List of nodes that match with the search parameters - */ - MegaNodeList* searchByType(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); - - /** - * @brief Search nodes on incoming shares containing a search string in their name - * - * The search is case-insensitive. If the search string is not provided but type has any value - * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), - * this method will return a list that contains nodes of the same type as provided. - * - * The method will search exclusively on incoming shares - * - * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling - * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until - * this method returns. - * - * You take the ownership of the returned value. - * - * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: - * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC - * - * @param searchString Search string. The search is case-insensitive - * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. - * @param order Order for the returned list - * Valid values for this parameter are: - * - MegaApi::ORDER_NONE = 0 - * Undefined order - * - * - MegaApi::ORDER_DEFAULT_ASC = 1 - * Folders first in alphabetical order, then files in the same order - * - * - MegaApi::ORDER_DEFAULT_DESC = 2 - * Files first in reverse alphabetical order, then folders in the same order - * - * - MegaApi::ORDER_SIZE_ASC = 3 - * Sort by size, ascending - * - * - MegaApi::ORDER_SIZE_DESC = 4 - * Sort by size, descending - * - * - MegaApi::ORDER_CREATION_ASC = 5 - * Sort by creation time in MEGA, ascending - * - * - MegaApi::ORDER_CREATION_DESC = 6 - * Sort by creation time in MEGA, descending - * - * - MegaApi::ORDER_MODIFICATION_ASC = 7 - * Sort by modification time of the original file, ascending - * - * - MegaApi::ORDER_MODIFICATION_DESC = 8 - * Sort by modification time of the original file, descending - * - * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 - * Same behavior than MegaApi::ORDER_DEFAULT_ASC - * - * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 - * Same behavior than MegaApi::ORDER_DEFAULT_DESC - * - * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC - * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. - * They will be eventually removed. - * - * - MegaApi::ORDER_PHOTO_ASC = 11 - * Sort with photos first, then by date ascending - * - * - MegaApi::ORDER_PHOTO_DESC = 12 - * Sort with photos first, then by date descending - * - * - MegaApi::ORDER_VIDEO_ASC = 13 - * Sort with videos first, then by date ascending - * - * - MegaApi::ORDER_VIDEO_DESC = 14 - * Sort with videos first, then by date descending - * - * @param type Type of nodes requested in the search - * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 - * - MegaApi::NODE_PHOTO = 1 - * - MegaApi::NODE_AUDIO = 2 - * - MegaApi::NODE_VIDEO = 3 - * - MegaApi::NODE_DOCUMENT = 4 - * - * @return List of nodes that match with the search parameters - */ - MegaNodeList* searchOnInSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); - - /** - * @brief Search nodes on outbound shares containing a search string in their name - * - * The search is case-insensitive. If the search string is not provided but type has any value - * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), - * this method will return a list that contains nodes of the same type as provided. - * - * The method will search exclusively on outbound shares - * - * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling - * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until - * this method returns. - * - * You take the ownership of the returned value. - * - * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: - * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC - * - * @param searchString Search string. The search is case-insensitive - * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. - * @param order Order for the returned list - * Valid values for this parameter are: - * - MegaApi::ORDER_NONE = 0 - * Undefined order - * - * - MegaApi::ORDER_DEFAULT_ASC = 1 - * Folders first in alphabetical order, then files in the same order - * - * - MegaApi::ORDER_DEFAULT_DESC = 2 - * Files first in reverse alphabetical order, then folders in the same order - * - * - MegaApi::ORDER_SIZE_ASC = 3 - * Sort by size, ascending - * - * - MegaApi::ORDER_SIZE_DESC = 4 - * Sort by size, descending - * - * - MegaApi::ORDER_CREATION_ASC = 5 - * Sort by creation time in MEGA, ascending - * - * - MegaApi::ORDER_CREATION_DESC = 6 - * Sort by creation time in MEGA, descending - * - * - MegaApi::ORDER_MODIFICATION_ASC = 7 - * Sort by modification time of the original file, ascending - * - * - MegaApi::ORDER_MODIFICATION_DESC = 8 - * Sort by modification time of the original file, descending - * - * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 - * Same behavior than MegaApi::ORDER_DEFAULT_ASC - * - * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 - * Same behavior than MegaApi::ORDER_DEFAULT_DESC - * - * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC - * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. - * They will be eventually removed. - * - * - MegaApi::ORDER_PHOTO_ASC = 11 - * Sort with photos first, then by date ascending - * - * - MegaApi::ORDER_PHOTO_DESC = 12 - * Sort with photos first, then by date descending - * - * - MegaApi::ORDER_VIDEO_ASC = 13 - * Sort with videos first, then by date ascending - * - * - MegaApi::ORDER_VIDEO_DESC = 14 - * Sort with videos first, then by date descending - * - * @param type Type of nodes requested in the search - * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 - * - MegaApi::NODE_PHOTO = 1 - * - MegaApi::NODE_AUDIO = 2 - * - MegaApi::NODE_VIDEO = 3 - * - MegaApi::NODE_DOCUMENT = 4 - * - * @return List of nodes that match with the search parameters - */ - MegaNodeList* searchOnOutSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); - - /** - * @brief Search nodes on public links shares containing a search string in their name - * - * The search is case-insensitive. If the search string is not provided but type has any value - * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), - * this method will return a list that contains nodes of the same type as provided. - * - * The method will search exclusively on public links shares - * - * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling - * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until - * this method returns. - * - * You take the ownership of the returned value. - * - * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: - * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC - * - * @param searchString Search string. The search is case-insensitive - * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. - * @param order Order for the returned list - * Valid values for this parameter are: - * - MegaApi::ORDER_NONE = 0 - * Undefined order - * - * - MegaApi::ORDER_DEFAULT_ASC = 1 - * Folders first in alphabetical order, then files in the same order - * - * - MegaApi::ORDER_DEFAULT_DESC = 2 - * Files first in reverse alphabetical order, then folders in the same order - * - * - MegaApi::ORDER_SIZE_ASC = 3 - * Sort by size, ascending - * - * - MegaApi::ORDER_SIZE_DESC = 4 - * Sort by size, descending - * - * - MegaApi::ORDER_CREATION_ASC = 5 - * Sort by creation time in MEGA, ascending - * - * - MegaApi::ORDER_CREATION_DESC = 6 - * Sort by creation time in MEGA, descending - * - * - MegaApi::ORDER_MODIFICATION_ASC = 7 - * Sort by modification time of the original file, ascending - * - * - MegaApi::ORDER_MODIFICATION_DESC = 8 - * Sort by modification time of the original file, descending - * - * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 - * Same behavior than MegaApi::ORDER_DEFAULT_ASC - * - * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 - * Same behavior than MegaApi::ORDER_DEFAULT_DESC - * - * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC - * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. - * They will be eventually removed. - * - * - MegaApi::ORDER_PHOTO_ASC = 11 - * Sort with photos first, then by date ascending - * - * - MegaApi::ORDER_PHOTO_DESC = 12 - * Sort with photos first, then by date descending - * - * - MegaApi::ORDER_VIDEO_ASC = 13 - * Sort with videos first, then by date ascending - * - * - MegaApi::ORDER_VIDEO_DESC = 14 - * Sort with videos first, then by date descending - * - * @param type Type of nodes requested in the search - * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 - * - MegaApi::NODE_PHOTO = 1 - * - MegaApi::NODE_AUDIO = 2 - * - MegaApi::NODE_VIDEO = 3 - * - MegaApi::NODE_DOCUMENT = 4 - * - * @return List of nodes that match with the search parameters - */ - MegaNodeList* searchOnPublicLinksBytype(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE, int type = NODE_UNKNOWN); + MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); /** * @brief Return a list of buckets, each bucket containing a list of recently added/modified nodes diff --git a/src/megaapi.cpp b/src/megaapi.cpp index 58edd4ebb4..00709247eb 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3748,31 +3748,11 @@ MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelT return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK); } -MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) +MegaNodeList* MegaApi::search(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) { return pImpl->search(n, searchString, cancelToken, recursive, order, type, target); } -MegaNodeList* MegaApi::searchByType(const char *searchString, MegaCancelToken *cancelToken, int order, int type) -{ - return pImpl->search(searchString, cancelToken, order, type); -} - -MegaNodeList* MegaApi::searchOnInSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) -{ - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_INSHARE, type); -} - -MegaNodeList* MegaApi::searchOnOutSharesBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) -{ - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_OUTSHARE, type); -} - -MegaNodeList* MegaApi::searchOnPublicLinksBytype(const char *searchString, MegaCancelToken *cancelToken, int order, int type) -{ - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK, type); -} - long long MegaApi::getSize(MegaNode *n) { return pImpl->getSize(n); From b58935bd4319182cec87855e582c6f138b050527 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Fri, 21 Aug 2020 14:51:16 +0200 Subject: [PATCH 17/52] Improve documentation for new search method --- include/megaapi.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index 1b8f3032e6..d54daffba0 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14550,7 +14550,23 @@ class MegaApi MegaNodeList* searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order = ORDER_NONE); /** - * @brief Search nodes containing a search string in their name and allow to filter by the type of the node + * @brief Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore, or on the contrary search in a + * specific target (root nodes, inshares, outshares, public links) + * - Search recursively + * - Containing a search string in their name + * - Filter by the type of the node + * - Order the returned list + * + * If node is provided, it will be the parent node of the tree to explore, + * search string and/or nodeType can be added to search parameters + * + * If node and searchString are not provided, and node type is not valid, this method will + * return an empty list. + * + * If parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter + * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, + * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC * * The search is case-insensitive. If the search string is not provided but type has any value * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), @@ -14562,9 +14578,6 @@ class MegaApi * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until * this method returns. * - * Note that if parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter order are invalid: - * - MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC - * * @param node The parent node of the tree to explore * @param searchString Search string. The search is case-insensitive * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. @@ -14629,6 +14642,14 @@ class MegaApi * - MegaApi::NODE_VIDEO = 3 * - MegaApi::NODE_DOCUMENT = 4 * + * @param target Target type where this method will search + * Valid values for this parameter are + * - TARGET_INSHARE = 0 + * - TARGET_OUTSHARE = 1 + * - TARGET_PUBLICLINK = 2 + * - TARGET_ROOTNODES = 3 + * - TARGET_ALL = 4 + * * @return List of nodes that match with the search parameters */ MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); From e7760e381a6b6501a2272a66ac17a94bb795fb11 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Mon, 24 Aug 2020 09:23:47 +0200 Subject: [PATCH 18/52] Style adjustments --- include/mega/megaclient.h | 10 +++++----- src/megaapi_impl.cpp | 3 ++- src/megaclient.cpp | 18 +++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/mega/megaclient.h b/include/mega/megaclient.h index 5ed6da17d8..bc58f0945a 100644 --- a/include/mega/megaclient.h +++ b/include/mega/megaclient.h @@ -1248,19 +1248,19 @@ class MEGA_API MegaClient recentactions_vector getRecentActions(unsigned maxcount, m_time_t since); // determine if the file is a video, photo, or media (video or photo). If the extension (with trailing .) is not precalculated, pass null - bool nodeIsMedia(const Node*, bool* isphoto, bool* isvideo) const; + bool nodeIsMedia(const Node*, bool *isphoto, bool *isvideo) const; // determine if the file is a photo. - bool nodeIsPhoto(const Node* n, bool checkPreview) const; + bool nodeIsPhoto(const Node *n, bool checkPreview) const; // determine if the file is a video. - bool nodeIsVideo(const Node* n) const; + bool nodeIsVideo(const Node *n) const; // determine if the file is an audio. - bool nodeIsAudio(const Node* n) const; + bool nodeIsAudio(const Node *n) const; // determine if the file is a document. - bool nodeIsDocument(const Node* n) const; + bool nodeIsDocument(const Node *n) const; // generate & return upload handle handle getuploadhandle(); diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 6795c052f3..695e8f9902 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11392,7 +11392,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan { if (!n && !searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) { - // If node is not valid or no search string and type is not valid + // If node is not valid, and no search string, and type is not valid return new MegaNodeListPrivate(); } @@ -11876,6 +11876,7 @@ bool SearchTreeProcessor::processNode(Node* node) if (node->type <= FOLDERNODE && (!search || strcasestr(node->displayname(), search) != NULL)) { + // If no search string provided (filter by node type), or search string match with node name if (isValidTypeNode(node)) { results.push_back(node); diff --git a/src/megaclient.cpp b/src/megaclient.cpp index 8932a5cfc8..b19cba1d30 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14288,7 +14288,7 @@ namespace action_bucket_compare const static string webclient_mime_audio_extensions = ".3ga.aac.adp.aif.aifc.aiff.au.caf.dra.dts.dtshd.ecelp4800.ecelp7470.ecelp9600.eol.flac.iff.kar.lvp.m2a.m3a.m3u.m4a.mid.midi.mka.mp2.mp2a.mp3.mp4a.mpga.oga.ogg.opus.pya.ra.ram.rip.rmi.rmp.s3m.sil.snd.spx.uva.uvva.wav.wax.weba.wma.xm."; const static string webclient_mime_document_extensions = ".ans.ascii.doc.docx.dotx.json.log.ods.odt.pages.pdf.ppc.pps.ppt.pptx.rtf.stc.std.stw.sti.sxc.sxd.sxi.sxm.sxw.txt.wpd.wps.xls.xlsx.xlt.xltm."; - bool nodeIsVideo(const Node* n, char ext[12], const MegaClient& mc) + bool nodeIsVideo(const Node *n, char ext[12], const MegaClient& mc) { if (n->hasfileattribute(fa_media) && n->nodekey().size() == FILENODEKEYLENGTH) { @@ -14316,17 +14316,17 @@ namespace action_bucket_compare return action_bucket_compare::webclient_mime_video_extensions.find(ext) != string::npos; } - bool nodeIsAudio(const Node* n, char ext[12]) + bool nodeIsAudio(const Node *n, char ext[12]) { return action_bucket_compare::webclient_mime_audio_extensions.find(ext) != string::npos; } - bool nodeIsDocument(const Node* n, char ext[12]) + bool nodeIsDocument(const Node *n, char ext[12]) { return action_bucket_compare::webclient_mime_document_extensions.find(ext) != string::npos; } - bool nodeIsPhoto(const Node* n, char ext[12], bool checkPreview) + bool nodeIsPhoto(const Node *n, char ext[12], bool checkPreview) { // evaluate according to the webclient rules, so that we get exactly the same bucketing. return action_bucket_compare::webclient_is_image_def.find(ext) != string::npos || @@ -14370,7 +14370,7 @@ namespace action_bucket_compare } // end namespace action_bucket_compare -bool MegaClient::nodeIsMedia(const Node* n, bool* isphoto, bool* isvideo) const +bool MegaClient::nodeIsMedia(const Node *n, bool *isphoto, bool *isvideo) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) @@ -14394,7 +14394,7 @@ bool MegaClient::nodeIsMedia(const Node* n, bool* isphoto, bool* isvideo) const return false; } -bool MegaClient::nodeIsVideo(const Node* n) const +bool MegaClient::nodeIsVideo(const Node *n) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) @@ -14404,7 +14404,7 @@ bool MegaClient::nodeIsVideo(const Node* n) const return false; } -bool MegaClient::nodeIsPhoto(const Node* n, bool checkPreview) const +bool MegaClient::nodeIsPhoto(const Node *n, bool checkPreview) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) @@ -14414,7 +14414,7 @@ bool MegaClient::nodeIsPhoto(const Node* n, bool checkPreview) const return false; } -bool MegaClient::nodeIsAudio(const Node* n) const +bool MegaClient::nodeIsAudio(const Node *n) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) @@ -14424,7 +14424,7 @@ bool MegaClient::nodeIsAudio(const Node* n) const return false; } -bool MegaClient::nodeIsDocument(const Node* n) const +bool MegaClient::nodeIsDocument(const Node *n) const { char ext[12]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) From c5077c70abd56325db1de5f22b8dae0b77abddd0 Mon Sep 17 00:00:00 2001 From: Lancy Date: Tue, 1 Sep 2020 14:19:48 +1200 Subject: [PATCH 19/52] feat(New Home): iOS binding for new Home API #IOS-4145 --- bindings/ios/MEGASdk.h | 101 ++++++++++++++++++++++++++++++++++++++++ bindings/ios/MEGASdk.mm | 12 ++++- 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/bindings/ios/MEGASdk.h b/bindings/ios/MEGASdk.h index 73790ed5ba..52772fd2ec 100644 --- a/bindings/ios/MEGASdk.h +++ b/bindings/ios/MEGASdk.h @@ -71,6 +71,22 @@ typedef NS_ENUM (NSInteger, MEGASortOrderType) { MEGASortOrderTypeLinkCreationDesc }; +typedef NS_ENUM (NSInteger, MEGANodeFormatType) { + MEGANodeFormatTypeUnknown = 0, + MEGANodeFormatTypePhoto, + MEGANodeFormatTypeAudio, + MEGANodeFormatTypeVideo, + MEGANodeFormatTypeDocument, +}; + +typedef NS_ENUM (NSInteger, MEGAFolderTargetType) { + MEGAFolderTargetTypeInShare = 0, + MEGAFolderTargetTypeOutShare, + MEGAFolderTargetTypePublicLink, + MEGAFolderTargetTypeRootNodes, + MEGAFolderTargetTypeAll, +}; + typedef NS_ENUM (NSInteger, MEGAEventType) { MEGAEventTypeFeedback = 0, MEGAEventTypeDebug, @@ -7082,6 +7098,91 @@ typedef NS_ENUM(NSInteger, AffiliateType) { */ - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString; +/** + * @brief Search nodes containing a search string in their name. + * + * The search is case-insensitive. + * + * @param node The parent node of the tree to explore. + * @param searchString Search string. The search is case-insensitive. + * If the search string is not provided but nodeFormatType has any value apart from MEGANodeFormatTypeUnknown + * this method will return a list that contains nodes of the same type as provided. + * @param cancelToken MEGACancelToken to be able to cancel the processing at any time. + * @param recursive YES if you want to seach recursively in the node tree. + * NO if you want to seach in the children of the node only + * @param orderType MEGASortOrderType for the returned list. + * Valid values for this parameter are: + * - MEGASortOrderTypeNone = 0 + * Undefined order + * + * - MEGASortOrderTypeDefaultAsc = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MEGASortOrderTypeDefaultDesc = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MEGASortOrderTypeSizeAsc = 3 + * Sort by size, ascending + * + * - MEGASortOrderTypeSizeDesc = 4 + * Sort by size, descending + * + * - MEGASortOrderTypeCreationAsc = 5 + * Sort by creation time in MEGA, ascending + * + * - MEGASortOrderTypeCreationDesc = 6 + * Sort by creation time in MEGA, descending + * + * - MEGASortOrderTypeModificationAsc = 7 + * Sort by modification time of the original file, ascending + * + * - MEGASortOrderTypeModificationDesc = 8 + * Sort by modification time of the original file, descending + * + * - MEGASortOrderTypeAlphabeticalAsc = 9 + * Same behavior than MEGASortOrderTypeDefaultAsc + * + * - MEGASortOrderTypeAlphabeticalDesc = 10 + * Same behavior than MEGASortOrderTypeDefaultDesc + * + * - MEGASortOrderTypePhotoAsc = 11 + * Sort with photos first, then by date ascending + * + * - MEGASortOrderTypePhotoDesc = 12 + * Sort with photos first, then by date descending + * + * - MEGASortOrderTypeVideoAsc = 13 + * Sort with videos first, then by date ascending + * + * - MEGASortOrderTypeVideoDesc = 14 + * Sort with videos first, then by date descending + * + * @param nodeFormatType Type of nodes requested in the search + * Valid values for this parameter are: + * - MEGANodeFormatTypeUnknown = 0 + * - MEGANodeFormatTypePhoto = 1 + * - MEGANodeFormatTypeAudio = 2 + * - MEGANodeFormatTypeVideo = 3 + * - MEGANodeFormatTypeDocument = 4 + * + * @param folderTargetType Target type where this method will search + * Valid values for this parameter are + * - MEGAFolderTargetTypeInShare = 0 + * - MEGAFolderTargetTypeOutShare = 1 + * - MEGAFolderTargetTypePublicLink = 2 + * - MEGAFolderTargetTypeRootNodes = 3 + * - MEGAFolderTargetTypeAll = 4 + * + * @return List of nodes that contain the desired string in their name. + */ +- (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node + searchString:(nullable NSString *)searchString + cancelToken:(MEGACancelToken *)cancelToken + recursive:(BOOL)recursive + orderType:(MEGASortOrderType)orderType + nodeFormatType:(MEGANodeFormatType)nodeFormatType + folderTargetType:(MEGAFolderTargetType)folderTargetType; + /** * @brief Return an array of buckets, each bucket containing a list of recently added/modified nodes * diff --git a/bindings/ios/MEGASdk.mm b/bindings/ios/MEGASdk.mm index b976275972..6183144096 100644 --- a/bindings/ios/MEGASdk.mm +++ b/bindings/ios/MEGASdk.mm @@ -2063,13 +2063,23 @@ - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString } - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString cancelToken:(MEGACancelToken *)cancelToken recursive:(BOOL)recursive order:(MEGASortOrderType)order { - return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order) cMemoryOwn:YES]; +// return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order) cMemoryOwn:YES]; + return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order, (int)MEGANodeFormatTypeUnknown, (int)MEGAFolderTargetTypeAll) cMemoryOwn:YES]; } - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString { return [[MEGANodeList alloc] initWithNodeList:self.megaApi->search((node != nil) ? [node getCPtr] : NULL, (searchString != nil) ? [searchString UTF8String] : NULL, YES) cMemoryOwn:YES]; } +- (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node + searchString:(nullable NSString *)searchString + cancelToken:(MEGACancelToken *)cancelToken + recursive:(BOOL)recursive + orderType:(MEGASortOrderType)orderType + nodeFormatType:(MEGANodeFormatType)nodeFormatType + folderTargetType:(MEGAFolderTargetType)folderTargetType { + return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)orderType, (int)nodeFormatType, (int)folderTargetType) cMemoryOwn:YES]; +} - (NSMutableArray *)recentActions { MegaRecentActionBucketList *megaRecentActionBucketList = self.megaApi->getRecentActions(); int count = megaRecentActionBucketList->size(); From 0420021cfe458ac52528e86049a9ef48acc68876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Tue, 1 Sep 2020 11:05:40 +0200 Subject: [PATCH 20/52] Avoid ambiguity of search() SWIG complains about two different interfaces whose call, due to the default params, is ambiguous. --- include/megaapi.h | 14 ++------------ src/megaapi.cpp | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index e7eca3d7ca..e64e9c596a 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14745,16 +14745,6 @@ class MegaApi * - MegaApi::ORDER_MODIFICATION_DESC = 8 * Sort by modification time of the original file, descending * - * - MegaApi::ORDER_ALPHABETICAL_ASC = 9 - * Same behavior than MegaApi::ORDER_DEFAULT_ASC - * - * - MegaApi::ORDER_ALPHABETICAL_DESC = 10 - * Same behavior than MegaApi::ORDER_DEFAULT_DESC - * - * @deprecated MegaApi::ORDER_ALPHABETICAL_ASC and MegaApi::ORDER_ALPHABETICAL_DESC - * are equivalent to MegaApi::ORDER_DEFAULT_ASC and MegaApi::ORDER_DEFAULT_DESC. - * They will be eventually removed. - * * - MegaApi::ORDER_PHOTO_ASC = 11 * Sort with photos first, then by date ascending * @@ -14769,7 +14759,7 @@ class MegaApi * * @param type Type of nodes requested in the search * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 + * - MegaApi::NODE_UNKNOWN = 0 --> all types * - MegaApi::NODE_PHOTO = 1 * - MegaApi::NODE_AUDIO = 2 * - MegaApi::NODE_VIDEO = 3 @@ -14785,7 +14775,7 @@ class MegaApi * * @return List of nodes that match with the search parameters */ - MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); + MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); /** * @brief Return a list of buckets, each bucket containing a list of recently added/modified nodes diff --git a/src/megaapi.cpp b/src/megaapi.cpp index ac309a5de5..d0fd37213d 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3773,7 +3773,7 @@ MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelT return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK); } -MegaNodeList* MegaApi::search(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) +MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) { return pImpl->search(n, searchString, cancelToken, recursive, order, type, target); } From 8ef2b6c319abe6619ded173a68d5c18977387a61 Mon Sep 17 00:00:00 2001 From: Piasy Xu Date: Wed, 2 Sep 2020 21:04:59 +0800 Subject: [PATCH 21/52] Add Java binding for searchByType --- bindings/java/nz/mega/sdk/MegaApiJava.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index f3f75e899d..c310be8422 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -9701,4 +9701,15 @@ public void getUserEmail(long handle, nz.mega.sdk.MegaRequestListenerInterface l public void cancelCreateAccount(MegaRequestListenerInterface listener){ megaApi.cancelCreateAccount(createDelegateRequestListener(listener)); } + + /** + * Search nodes by type. + * + * TODO: add parameter descriptions + */ + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken, boolean recursive, int order, int type, int target) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, + order, type, target)); + } } From 9bdfec47216fb865e515da32bc4d7f42c897a3d7 Mon Sep 17 00:00:00 2001 From: Piasy Xu Date: Fri, 4 Sep 2020 11:00:31 +0800 Subject: [PATCH 22/52] Add constants for Java binding --- bindings/java/nz/mega/sdk/MegaApiJava.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index c310be8422..7fe6c6a9f6 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -196,7 +196,12 @@ void runCallback(Runnable runnable) { public final static int HTTP_SERVER_ALLOW_CREATED_LOCAL_LINKS = MegaApi.HTTP_SERVER_ALLOW_CREATED_LOCAL_LINKS; public final static int HTTP_SERVER_ALLOW_LAST_LOCAL_LINK = MegaApi.HTTP_SERVER_ALLOW_LAST_LOCAL_LINK; - + public final static int TARGET_ROOTNODES = 3; + public final static int NODE_UNKNOWN = 0; + public final static int NODE_PHOTO = 1; + public final static int NODE_AUDIO = 2; + public final static int NODE_VIDEO = 3; + public final static int NODE_DOCUMENT = 4; MegaApi getMegaApi() { From 7282f59298a294ed095aedc53e07c48539750682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Fri, 4 Sep 2020 11:07:49 +0200 Subject: [PATCH 23/52] Adjust search for type rootnode It should not include nodes from Rubbish/Inbox, only nodes in the Cloud. --- include/megaapi.h | 4 ++-- src/megaapi_impl.cpp | 20 +++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index e64e9c596a..e823e819db 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -13232,7 +13232,7 @@ class MegaApi NODE_VIDEO, NODE_DOCUMENT,} nodefiletype_t; typedef enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, - TARGET_ROOTNODES, TARGET_ALL } searchtarget_t; + TARGET_ROOTNODE, TARGET_ALL } searchtarget_t; /** * @brief Get the number of child nodes @@ -14770,7 +14770,7 @@ class MegaApi * - TARGET_INSHARE = 0 * - TARGET_OUTSHARE = 1 * - TARGET_PUBLICLINK = 2 - * - TARGET_ROOTNODES = 3 + * - TARGET_ROOTNODE = 3 * - TARGET_ALL = 4 * * @return List of nodes that match with the search parameters diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 92ec9d51ef..48a3b698f3 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11451,18 +11451,16 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan return new MegaNodeListPrivate(); } - if (target == MegaApi::TARGET_ROOTNODES || target == MegaApi::TARGET_ALL) + if (target == MegaApi::TARGET_ROOTNODE || target == MegaApi::TARGET_ALL) { - // Search on rootnodes - for (unsigned int i = 0; i < (sizeof client->rootnodes / sizeof *client->rootnodes) - && !(cancelToken && cancelToken->isCancelled()); i++) - { - node = client->nodebyhandle(client->rootnodes[i]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - processTree(node, &searchProcessor, recursive, cancelToken); - node_vector& vNodes = searchProcessor.getResults(); - result.insert(result.end(), vNodes.begin(), vNodes.end()); - } + // Search on rootnode (cloud, excludes Inbox and Rubbish) + node = client->nodebyhandle(client->rootnodes[0]); + + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + processTree(node, &searchProcessor, recursive, cancelToken); + node_vector& vNodes = searchProcessor.getResults(); + + result.insert(result.end(), vNodes.begin(), vNodes.end()); } if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_ALL) From fda7735af047561e9fc136c6df1e87040e295d18 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Mon, 14 Sep 2020 16:34:16 +0200 Subject: [PATCH 24/52] Refactor SearchTreeProcessor members --- include/megaapi_impl.h | 8 ++++---- src/megaapi_impl.cpp | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 5aa16092c2..636bddcc79 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -1889,10 +1889,10 @@ class SearchTreeProcessor : public TreeProcessor vector &getResults(); protected: - MegaApi::nodefiletype_t type; - const char *search; - vector results; - MegaClient *client; + MegaApi::nodefiletype_t mType; + const char *mSearch; + vector mResults; + MegaClient *mClient; }; class OutShareProcessor : public TreeProcessor diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 48a3b698f3..e15410cb19 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11832,9 +11832,9 @@ MegaNode *MegaApiImpl::getNodeByCRC(const char *crc, MegaNode *parent) SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, MegaApi::nodefiletype_t type) { - this->search = search; - this->type = type; - this->client = client; + mSearch = search; + mType = type; + mClient = client; } #if defined(_WIN32) || defined(__APPLE__) @@ -11870,18 +11870,18 @@ bool SearchTreeProcessor::processNode(Node* node) return true; } - if (!search && (!client || (type < MegaApi::NODE_UNKNOWN || type > MegaApi::NODE_DOCUMENT))) + if (!mSearch && (!mClient || (mType < MegaApi::NODE_UNKNOWN || mType > MegaApi::NODE_DOCUMENT))) { // If no search string provided, client and type must be valid, otherwise return false return false; } - if (node->type <= FOLDERNODE && (!search || strcasestr(node->displayname(), search) != NULL)) + if (node->type <= FOLDERNODE && (!mSearch || strcasestr(node->displayname(), mSearch) != NULL)) { // If no search string provided (filter by node type), or search string match with node name if (isValidTypeNode(node)) { - results.push_back(node); + mResults.push_back(node); } } @@ -11891,21 +11891,21 @@ bool SearchTreeProcessor::processNode(Node* node) bool SearchTreeProcessor::isValidTypeNode(Node *node) { assert(node); - if (!client) + if (!mClient) { return true; } - switch (type) + switch (mType) { case MegaApi::NODE_PHOTO: - return client->nodeIsPhoto(node, false); + return mClient->nodeIsPhoto(node, false); case MegaApi::NODE_AUDIO: - return client->nodeIsAudio(node); + return mClient->nodeIsAudio(node); case MegaApi::NODE_VIDEO: - return client->nodeIsVideo(node); + return mClient->nodeIsVideo(node); case MegaApi::NODE_DOCUMENT: - return client->nodeIsDocument(node); + return mClient->nodeIsDocument(node); case MegaApi::NODE_UNKNOWN: default: return true; @@ -11914,7 +11914,7 @@ bool SearchTreeProcessor::isValidTypeNode(Node *node) vector &SearchTreeProcessor::getResults() { - return results; + return mResults; } SizeProcessor::SizeProcessor() From e274ca5cf4cd3a35e89e02fb5c2927a2e2471398 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Tue, 15 Sep 2020 10:24:34 +0200 Subject: [PATCH 25/52] Replace raw pointers by unique_ptr --- src/megaapi_impl.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index e15410cb19..ee5f0716f2 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10812,7 +10812,7 @@ MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCance if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_OUTSHARE) { // Search in inShares or outShares - ::mega::unique_ptr shares (target == MegaApi::TARGET_INSHARE + unique_ptr shares (target == MegaApi::TARGET_INSHARE ? getInSharesList(MegaApi::ORDER_NONE) : getOutShares(MegaApi::ORDER_NONE)); @@ -10885,7 +10885,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can } // inshares - MegaShareList *shares = getInSharesList(MegaApi::ORDER_NONE); + unique_ptr shares(getInSharesList(MegaApi::ORDER_NONE)); for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); @@ -10896,7 +10896,6 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can result.insert(result.end(), vNodes.begin(), vNodes.end()); } - delete shares; sortByComparatorFunction(result, order, *client); MegaNodeList *nodeList = new MegaNodeListPrivate(result.data(), int(result.size())); @@ -11466,7 +11465,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_ALL) { // Search on inshares - MegaShareList *shares = getInSharesList(MegaApi::ORDER_NONE); + unique_ptr shares(getInSharesList(MegaApi::ORDER_NONE)); for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); @@ -11477,13 +11476,12 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan result.insert(result.end(), vNodes.begin(), vNodes.end()); } - delete shares; } if (target == MegaApi::TARGET_OUTSHARE || target == MegaApi::TARGET_ALL) { // Search on outshares - MegaShareList *shares = getOutShares(MegaApi::ORDER_NONE); + unique_ptrshares (getOutShares(MegaApi::ORDER_NONE)); for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); @@ -11494,7 +11492,6 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan result.insert(result.end(), vNodes.begin(), vNodes.end()); } - delete shares; } if (target == MegaApi::TARGET_PUBLICLINK || target == MegaApi::TARGET_ALL) From 7ade84453b332d77a1ab12bafc90bdd467902675 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Tue, 15 Sep 2020 11:15:55 +0200 Subject: [PATCH 26/52] Remove unnecesary method searchInAllShares --- include/megaapi_impl.h | 2 -- src/megaapi.cpp | 6 ++-- src/megaapi_impl.cpp | 68 ------------------------------------------ 3 files changed, 3 insertions(+), 73 deletions(-) diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 636bddcc79..50bcbea0e7 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -2424,8 +2424,6 @@ class MegaApiImpl : public MegaApp bool processMegaTree(MegaNode* node, MegaTreeProcessor* processor, bool recursive = 1); MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); - MegaNodeList* searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target, int type = MegaApi::NODE_UNKNOWN); - MegaNode *createForeignFileNode(MegaHandle handle, const char *key, const char *name, m_off_t size, m_off_t mtime, MegaHandle parentHandle, const char *privateauth, const char *publicauth, const char *chatauth); MegaNode *createForeignFolderNode(MegaHandle handle, const char *name, MegaHandle parentHandle, diff --git a/src/megaapi.cpp b/src/megaapi.cpp index d0fd37213d..e21cf31e06 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3760,17 +3760,17 @@ MegaNodeList *MegaApi::search(const char *searchString, MegaCancelToken *cancelT MegaNodeList* MegaApi::searchOnInShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_INSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_INSHARE); } MegaNodeList* MegaApi::searchOnOutShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_OUTSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_OUTSHARE); } MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->searchInAllShares(searchString, cancelToken, order, MegaApi::TARGET_PUBLICLINK); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_PUBLICLINK); } MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index ee5f0716f2..55956272b1 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10776,74 +10776,6 @@ bool MegaApiImpl::processMegaTree(MegaNode* n, MegaTreeProcessor* processor, boo return result; } -MegaNodeList* MegaApiImpl::searchInAllShares(const char *searchString, MegaCancelToken *cancelToken, int order, int target, int type) -{ - if (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) - { - // If no search string and type is not valid - return new MegaNodeListPrivate(); - } - - if (type != MegaApi::NODE_UNKNOWN - && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) - { - return new MegaNodeListPrivate(); - } - - if (cancelToken && cancelToken->isCancelled()) - { - return new MegaNodeListPrivate(); - } - - if (target < MegaApi::TARGET_INSHARE || target > MegaApi::TARGET_PUBLICLINK) - { - return new MegaNodeListPrivate(); - } - - SdkMutexGuard g(sdkMutex); - - if (cancelToken && cancelToken->isCancelled()) - { - return new MegaNodeListPrivate(); - } - - node_vector result; - Node *node; - if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_OUTSHARE) - { - // Search in inShares or outShares - unique_ptr shares (target == MegaApi::TARGET_INSHARE - ? getInSharesList(MegaApi::ORDER_NONE) - : getOutShares(MegaApi::ORDER_NONE)); - - for (int i = 0; i < shares->size() && !(cancelToken && cancelToken->isCancelled()); i++) - { - node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - processTree(node, &searchProcessor, true, cancelToken); - vector& vNodes = searchProcessor.getResults(); - result.insert(result.end(), vNodes.begin(), vNodes.end()); - } - } - else - { - // Search in public links - for (auto it = client->mPublicLinks.begin(); it != client->mPublicLinks.end() - && !(cancelToken && cancelToken->isCancelled()); it++) - { - node = client->nodebyhandle(it->first); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); - processTree(node, &searchProcessor, true, cancelToken); - vector& vNodes = searchProcessor.getResults(); - result.insert(result.end(), vNodes.begin(), vNodes.end()); - } - } - - sortByComparatorFunction(result, order, *client); - MegaNodeList *nodeList = new MegaNodeListPrivate(result.data(), int(result.size())); - return nodeList; -} - MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { if (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) From 74cde92178705e259e7b02eb30e74fbe2d0f595c Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Tue, 15 Sep 2020 11:55:41 +0200 Subject: [PATCH 27/52] Move typedef nodefiletype_t into types --- include/mega/types.h | 6 ++++++ include/megaapi.h | 10 +++++----- include/megaapi_impl.h | 4 ++-- src/megaapi_impl.cpp | 16 ++++++++-------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/mega/types.h b/include/mega/types.h index f436fc0cbe..c7ce1136fc 100644 --- a/include/mega/types.h +++ b/include/mega/types.h @@ -271,6 +271,12 @@ typedef list file_list; // RUBBISH - rubbish bin typedef enum { TYPE_UNKNOWN = -1, FILENODE = 0, FOLDERNODE, ROOTNODE, INCOMINGNODE, RUBBISHNODE } nodetype_t; +// node file types: +typedef enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, NODE_VIDEO, NODE_DOCUMENT, } nodefiletype_t; + +// search target types +typedef enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, TARGET_ROOTNODE, TARGET_ALL, } searchtarget_t; + // node type key lengths const int FILENODEKEYLENGTH = 32; const int FOLDERNODEKEYLENGTH = 16; diff --git a/include/megaapi.h b/include/megaapi.h index e823e819db..fbd95f18d7 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -13228,11 +13228,11 @@ class MegaApi ORDER_VIDEO_ASC, ORDER_VIDEO_DESC, ORDER_LINK_CREATION_ASC, ORDER_LINK_CREATION_DESC,}; - typedef enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, - NODE_VIDEO, NODE_DOCUMENT,} nodefiletype_t; + enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, + NODE_VIDEO, NODE_DOCUMENT, }; - typedef enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, - TARGET_ROOTNODE, TARGET_ALL } searchtarget_t; + enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, + TARGET_ROOTNODE, TARGET_ALL, }; /** * @brief Get the number of child nodes @@ -14702,7 +14702,7 @@ class MegaApi * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC * * The search is case-insensitive. If the search string is not provided but type has any value - * defined at MegaApi::nodefiletype_t (except MegaApi::NODE_UNKNOWN), + * defined at nodefiletype_t (except NODE_UNKNOWN), * this method will return a list that contains nodes of the same type as provided. * * You take the ownership of the returned value. diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 50bcbea0e7..0877224cc1 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -1882,14 +1882,14 @@ class TreeProcessor class SearchTreeProcessor : public TreeProcessor { public: - SearchTreeProcessor(MegaClient *client, const char *search, MegaApi::nodefiletype_t type); + SearchTreeProcessor(MegaClient *client, const char *search, nodefiletype_t type); virtual bool processNode(Node *node); bool isValidTypeNode(Node *node); virtual ~SearchTreeProcessor() {} vector &getResults(); protected: - MegaApi::nodefiletype_t mType; + nodefiletype_t mType; const char *mSearch; vector mResults; MegaClient *mClient; diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 55956272b1..df6034a141 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10810,7 +10810,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(client->rootnodes[i]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); node_vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -10822,7 +10822,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11360,7 +11360,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } // searchString and nodeType (if provided), are considered in search - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); for (node_list::iterator it = node->children.begin(); it != node->children.end() && !(cancelToken && cancelToken->isCancelled()); ) { @@ -11387,7 +11387,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan // Search on rootnode (cloud, excludes Inbox and Rubbish) node = client->nodebyhandle(client->rootnodes[0]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, recursive, cancelToken); node_vector& vNodes = searchProcessor.getResults(); @@ -11402,7 +11402,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, recursive, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11418,7 +11418,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, recursive, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11433,7 +11433,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan && !(cancelToken && cancelToken->isCancelled()); it++) { node = client->nodebyhandle(it->first); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -11759,7 +11759,7 @@ MegaNode *MegaApiImpl::getNodeByCRC(const char *crc, MegaNode *parent) return NULL; } -SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, MegaApi::nodefiletype_t type) +SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, nodefiletype_t type) { mSearch = search; mType = type; From 2db8ad48b9d51af1d41025f827bdcd8a4e84ec2e Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Mon, 21 Sep 2020 17:09:31 +0200 Subject: [PATCH 28/52] Remove unnecesary checks --- src/megaapi_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index df6034a141..256fb5c8eb 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11410,7 +11410,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } } - if (target == MegaApi::TARGET_OUTSHARE || target == MegaApi::TARGET_ALL) + if (target == MegaApi::TARGET_OUTSHARE) { // Search on outshares unique_ptrshares (getOutShares(MegaApi::ORDER_NONE)); @@ -11426,7 +11426,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } } - if (target == MegaApi::TARGET_PUBLICLINK || target == MegaApi::TARGET_ALL) + if (target == MegaApi::TARGET_PUBLICLINK) { // Search on public links for (auto it = client->mPublicLinks.begin(); it != client->mPublicLinks.end() From 943cb1e1bdf2e7cbc526f1866e49d89cd27cf465 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Wed, 30 Sep 2020 09:14:56 +0200 Subject: [PATCH 29/52] Add new order types in searchByType documentation --- include/megaapi.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/megaapi.h b/include/megaapi.h index 73dbd2e846..581af544e5 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -15792,6 +15792,18 @@ class MegaApi * - MegaApi::ORDER_VIDEO_DESC = 14 * Sort with videos first, then by date descending * + * - MegaApi::ORDER_LABEL_ASC = 17 + * Sort by color label, ascending + * + * - MegaApi::ORDER_LABEL_DESC = 18 + * Sort by color label, descending + * + * - MegaApi::ORDER_FAV_ASC = 19 + * Sort nodes with favourite attr first + * + * - MegaApi::ORDER_FAV_DESC = 20 + * Sort nodes with favourite attr last + * * @param type Type of nodes requested in the search * Valid values for this parameter are: * - MegaApi::NODE_UNKNOWN = 0 --> all types From b439774d42d4810c33a098034b4520730bf743a2 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 30 Sep 2020 19:37:15 +0200 Subject: [PATCH 30/52] Do actually set syncsup to false after delayed initial scans It will in following loops be set to true right after after the subsequent checks. And with this change, we no longer avoid the initial syncdownrequired = true, once all initial scans have finished --- src/megaclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index afa912aa48..3c3765a352 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -2462,7 +2462,7 @@ void MegaClient::exec() if (sync->scan(&localPath, fa.get())) { - //syncsup = false; These syncs should not delay action packets + syncsup = false; sync->initializing = false; LOG_debug << "Initial delayed scan finished. New / modified files: " << sync->dirnotify->notifyq[DirNotify::DIREVENTS].size(); saveAndUpdateSyncConfig(&sync->getConfig(), sync->state, NO_SYNC_ERROR); From e60556b31203ade5166061c7a04053a0a61bd1b2 Mon Sep 17 00:00:00 2001 From: Gonzalo Toledano Date: Mon, 5 Oct 2020 19:54:32 +0200 Subject: [PATCH 31/52] Add Android Bindings for labels and favorites --- bindings/java/nz/mega/sdk/MegaApiJava.java | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index 16a5be5507..20bd2d315c 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -111,6 +111,8 @@ void runCallback(Runnable runnable) { public final static int NODE_ATTR_DURATION = MegaApi.NODE_ATTR_DURATION; public final static int NODE_ATTR_COORDINATES = MegaApi.NODE_ATTR_COORDINATES; + public final static int NODE_ATTR_LABEL = MegaApi.NODE_ATTR_LABEL; + public final static int NODE_ATTR_FAV = MegaApi.NODE_ATTR_FAV; public final static int PAYMENT_METHOD_BALANCE = MegaApi.PAYMENT_METHOD_BALANCE; public final static int PAYMENT_METHOD_PAYPAL = MegaApi.PAYMENT_METHOD_PAYPAL; @@ -185,6 +187,10 @@ void runCallback(Runnable runnable) { public final static int ORDER_VIDEO_DESC = MegaApi.ORDER_VIDEO_DESC; public final static int ORDER_LINK_CREATION_ASC = MegaApi.ORDER_LINK_CREATION_ASC; public final static int ORDER_LINK_CREATION_DESC = MegaApi.ORDER_LINK_CREATION_DESC; + public final static int ORDER_LABEL_ASC = MegaApi.ORDER_LABEL_ASC; + public final static int ORDER_LABEL_DESC = MegaApi.ORDER_LABEL_DESC; + public final static int ORDER_FAV_ASC = MegaApi.ORDER_FAV_ASC; + public final static int ORDER_FAV_DESC = MegaApi.ORDER_FAV_DESC; public final static int TCP_SERVER_DENY_ALL = MegaApi.TCP_SERVER_DENY_ALL; public final static int TCP_SERVER_ALLOW_ALL = MegaApi.TCP_SERVER_ALLOW_ALL; @@ -4171,6 +4177,121 @@ public void setNodeCoordinates(MegaNode node, double latitude, double longitude, megaApi.setNodeCoordinates(node, latitude, longitude, createDelegateRequestListener(listener)); } + /** + * Set node label as a node attribute. + * + * Valid values for label attribute are: + * - MegaNode::NODE_LBL_UNKNOWN = 0 + * - MegaNode::NODE_LBL_RED = 1 + * - MegaNode::NODE_LBL_ORANGE = 2 + * - MegaNode::NODE_LBL_YELLOW = 3 + * - MegaNode::NODE_LBL_GREEN = 4 + * - MegaNode::NODE_LBL_BLUE = 5 + * - MegaNode::NODE_LBL_PURPLE = 6 + * - MegaNode::NODE_LBL_GREY = 7 + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails() - Returns the label for the node + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * + * @param node Node that will receive the information. + * @param label Label of the node + * @param listener MegaRequestListener to track this request + */ + public void setNodeLabel(MegaNode node, int label, MegaRequestListenerInterface listener){ + megaApi.setNodeLabel(node, label, createDelegateRequestListener(listener)); + } + + /** + * Set node label as a node attribute. + * + * Valid values for label attribute are: + * - MegaNode::NODE_LBL_UNKNOWN = 0 + * - MegaNode::NODE_LBL_RED = 1 + * - MegaNode::NODE_LBL_ORANGE = 2 + * - MegaNode::NODE_LBL_YELLOW = 3 + * - MegaNode::NODE_LBL_GREEN = 4 + * - MegaNode::NODE_LBL_BLUE = 5 + * - MegaNode::NODE_LBL_PURPLE = 6 + * - MegaNode::NODE_LBL_GREY = 7 + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails() - Returns the label for the node + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * + * @param node Node that will receive the information. + * @param label Label of the node + */ + public void setNodeLabel(MegaNode node, int label){ + megaApi.setNodeLabel(node, label); + } + + /** + * Remove node label + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * + * @param node Node that will receive the information. + * @param listener MegaRequestListener to track this request + */ + public void resetNodeLabel(MegaNode node, MegaRequestListenerInterface listener){ + megaApi.resetNodeLabel(node, createDelegateRequestListener(listener)); + } + + /** + * Remove node label + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * + * @param node Node that will receive the information. + */ + public void resetNodeLabel(MegaNode node){ + megaApi.resetNodeLabel(node); + } + + /** + * Set node favourite as a node attribute. + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails() - Returns 1 if node is set as favourite, otherwise return 0 + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Favourite attribute + * + * @param node Node that will receive the information. + * @param favourite if YES set node as favourite, otherwise remove the attribute + * @param listener MegaRequestListener to track this request + */ + public void setNodeFavourite(MegaNode node, boolean favourite, MegaRequestListenerInterface listener){ + megaApi.setNodeFavourite(node, favourite, createDelegateRequestListener(listener)); + } + + /** + * Set node favourite as a node attribute. + * + * Valid data in the MEGARequest object received on callbacks: + * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails() - Returns 1 if node is set as favourite, otherwise return 0 + * - MegaRequest::getFlag() - Returns YES (official attribute) + * - MegaRequest::getParamType() - Returns MEGANode Favourite attribute + * + * @param node Node that will receive the information. + * @param favourite if YES set node as favourite, otherwise remove the attribute + */ + public void setNodeFavourite(MegaNode node, boolean favourite){ + megaApi.setNodeFavourite(node, favourite); + } + /** * Generate a public link of a file/folder in MEGA * From c1b46ef4dfbee08d87dfe2febab748b58b1c9473 Mon Sep 17 00:00:00 2001 From: matt weir Date: Tue, 6 Oct 2020 15:37:39 +1300 Subject: [PATCH 32/52] Fix for MegaApiImpl::putnodes_result for a moved versioned node The copy code copies the versions so there are multiple nodes in the array and the main node is the first one, not the last one. Almost all operations that use putnodes_result only affect one node. --- src/megaapi_impl.cpp | 4 ++-- tests/integration/SdkTest_test.cpp | 28 ++++++++++++++++++++++++++++ tests/integration/SdkTest_test.h | 8 ++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 2f93fb883b..6de2c39336 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -13659,8 +13659,8 @@ void MegaApiImpl::putnodes_result(const Error& inputErr, targettype_t t, vector< if (!e && t != USER_HANDLE) { - assert(!nn.empty() && nn.back().added && nn.back().mAddedHandle != UNDEF); - n = client->nodebyhandle(nn.back().mAddedHandle); + assert(!nn.empty() && nn.front().added && nn.front().mAddedHandle != UNDEF); + n = client->nodebyhandle(nn.front().mAddedHandle); if(n) { diff --git a/tests/integration/SdkTest_test.cpp b/tests/integration/SdkTest_test.cpp index 1b7c4907d8..76c0e5c76b 100644 --- a/tests/integration/SdkTest_test.cpp +++ b/tests/integration/SdkTest_test.cpp @@ -1687,6 +1687,34 @@ TEST_F(SdkTest, SdkTestTransfers) ASSERT_STREQ(filename1.data(), n1->getName()) << "Uploaded file with wrong name (error: " << mApi[0].lastError << ")"; + ASSERT_EQ(API_OK, doSetFileVersionsOption(0, false)); // false = not disabled + + // Upload a file over an existing one to make a version + { + ofstream f(filename1); + f << "edited"; + } + + ASSERT_EQ(API_OK, doStartUpload(0, filename1.c_str(), rootnode)); + + // Upload a file over an existing one to make a version + { + ofstream f(filename1); + f << "edited2"; + } + + ASSERT_EQ(API_OK, doStartUpload(0, filename1.c_str(), rootnode)); + + // copy a node with versions to a new name (exercises the multi node putndoes_result) + MegaNode* nodeToCopy1 = megaApi[0]->getNodeByPath(("/" + filename1).c_str()); + ASSERT_EQ(API_OK, doCopyNode(0, nodeToCopy1, rootnode, "some_other_name")); + + // put original filename1 back + fs::remove(filename1); + createFile(filename1); + ASSERT_EQ(API_OK, doStartUpload(0, filename1.c_str(), rootnode)); + n1 = megaApi[0]->getNodeByPath(("/" + filename1).c_str()); + // --- Get node by fingerprint (needs to be a file, not a folder) --- std::unique_ptr fingerprint{megaApi[0]->getFingerprint(n1)}; diff --git a/tests/integration/SdkTest_test.h b/tests/integration/SdkTest_test.h index 682df951bb..1a0af8de07 100644 --- a/tests/integration/SdkTest_test.h +++ b/tests/integration/SdkTest_test.h @@ -156,11 +156,11 @@ class SdkTest : public ::testing::Test, public MegaListener, MegaRequestListener string pwd; int lastError; int lastTransferError; - + // flags to monitor the completion of requests/transfers bool requestFlags[MegaRequest::TOTAL_OF_REQUEST_TYPES]; bool transferFlags[MegaTransfer::TYPE_LOCAL_HTTP_DOWNLOAD]; - + std::unique_ptr cr; std::unique_ptr tzDetails; std::unique_ptr accountDetails; @@ -286,6 +286,10 @@ class SdkTest : public ::testing::Test, public MegaListener, MegaRequestListener template int doRequestLogout(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->logout(args..., &rt); return rt.waitForResult(); } template int doRequestLocalLogout(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->localLogout(args..., &rt); return rt.waitForResult(); } template int doSetNodeDuration(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->setNodeDuration(args..., &rt); return rt.waitForResult(); } + template int doStartUpload(unsigned apiIndex, requestArgs... args) { TransferTracker tt(megaApi[apiIndex].get()); megaApi[apiIndex]->startUpload(args..., &tt); return tt.waitForResult(); } + template int doSetFileVersionsOption(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->setFileVersionsOption(args..., &rt); return rt.waitForResult(); } + template int doMoveNode(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->moveNode(args..., &rt); return rt.waitForResult(); } + template int doCopyNode(unsigned apiIndex, requestArgs... args) { RequestTracker rt(megaApi[apiIndex].get()); megaApi[apiIndex]->copyNode(args..., &rt); return rt.waitForResult(); } void createFile(string filename, bool largeFile = true); int64_t getFilesize(string filename); From b99c71798f1d8c069b6c776261170284cb2eb99a Mon Sep 17 00:00:00 2001 From: Javier Gomez Date: Tue, 6 Oct 2020 13:25:28 +0200 Subject: [PATCH 33/52] Fix Android binding methods documentation format Bindings for labels and favourites --- bindings/java/nz/mega/sdk/MegaApiJava.java | 104 +++++++++++---------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index 20bd2d315c..b1f3394261 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -4179,22 +4179,22 @@ public void setNodeCoordinates(MegaNode node, double latitude, double longitude, /** * Set node label as a node attribute. - * * Valid values for label attribute are: - * - MegaNode::NODE_LBL_UNKNOWN = 0 - * - MegaNode::NODE_LBL_RED = 1 - * - MegaNode::NODE_LBL_ORANGE = 2 - * - MegaNode::NODE_LBL_YELLOW = 3 - * - MegaNode::NODE_LBL_GREEN = 4 - * - MegaNode::NODE_LBL_BLUE = 5 - * - MegaNode::NODE_LBL_PURPLE = 6 - * - MegaNode::NODE_LBL_GREY = 7 - * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getNumDetails() - Returns the label for the node - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * - MegaNode::NODE_LBL_UNKNOWN = 0 + * - MegaNode::NODE_LBL_RED = 1 + * - MegaNode::NODE_LBL_ORANGE = 2 + * - MegaNode::NODE_LBL_YELLOW = 3 + * - MegaNode::NODE_LBL_GREEN = 4 + * - MegaNode::NODE_LBL_BLUE = 5 + * - MegaNode::NODE_LBL_PURPLE = 6 + * - MegaNode::NODE_LBL_GREY = 7 + * + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails - Returns the label for the node + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_LABEL * * @param node Node that will receive the information. * @param label Label of the node @@ -4206,22 +4206,22 @@ public void setNodeLabel(MegaNode node, int label, MegaRequestListenerInterface /** * Set node label as a node attribute. - * * Valid values for label attribute are: - * - MegaNode::NODE_LBL_UNKNOWN = 0 - * - MegaNode::NODE_LBL_RED = 1 - * - MegaNode::NODE_LBL_ORANGE = 2 - * - MegaNode::NODE_LBL_YELLOW = 3 - * - MegaNode::NODE_LBL_GREEN = 4 - * - MegaNode::NODE_LBL_BLUE = 5 - * - MegaNode::NODE_LBL_PURPLE = 6 - * - MegaNode::NODE_LBL_GREY = 7 - * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getNumDetails() - Returns the label for the node - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * - MegaNode::NODE_LBL_UNKNOWN = 0 + * - MegaNode::NODE_LBL_RED = 1 + * - MegaNode::NODE_LBL_ORANGE = 2 + * - MegaNode::NODE_LBL_YELLOW = 3 + * - MegaNode::NODE_LBL_GREEN = 4 + * - MegaNode::NODE_LBL_BLUE = 5 + * - MegaNode::NODE_LBL_PURPLE = 6 + * - MegaNode::NODE_LBL_GREY = 7 + * + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails - Returns the label for the node + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_LABEL * * @param node Node that will receive the information. * @param label Label of the node @@ -4233,10 +4233,11 @@ public void setNodeLabel(MegaNode node, int label){ /** * Remove node label * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_LABEL * * @param node Node that will receive the information. * @param listener MegaRequestListener to track this request @@ -4248,10 +4249,11 @@ public void resetNodeLabel(MegaNode node, MegaRequestListenerInterface listener) /** * Remove node label * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Label attribute + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_LABEL * * @param node Node that will receive the information. */ @@ -4262,14 +4264,15 @@ public void resetNodeLabel(MegaNode node){ /** * Set node favourite as a node attribute. * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getNumDetails() - Returns 1 if node is set as favourite, otherwise return 0 - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Favourite attribute + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails - Returns 1 if node is set as favourite, otherwise return 0 + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_FAV * * @param node Node that will receive the information. - * @param favourite if YES set node as favourite, otherwise remove the attribute + * @param favourite if true set node as favourite, otherwise remove the attribute * @param listener MegaRequestListener to track this request */ public void setNodeFavourite(MegaNode node, boolean favourite, MegaRequestListenerInterface listener){ @@ -4279,14 +4282,15 @@ public void setNodeFavourite(MegaNode node, boolean favourite, MegaRequestListen /** * Set node favourite as a node attribute. * - * Valid data in the MEGARequest object received on callbacks: - * - MegaRequest::getNodeHandle() - Returns the handle of the node that receive the attribute - * - MegaRequest::getNumDetails() - Returns 1 if node is set as favourite, otherwise return 0 - * - MegaRequest::getFlag() - Returns YES (official attribute) - * - MegaRequest::getParamType() - Returns MEGANode Favourite attribute + * The associated request type with this request is MegaRequest::TYPE_SET_ATTR_NODE + * Valid data in the MegaRequest object received on callbacks: + * - MegaRequest::getNodeHandle - Returns the handle of the node that receive the attribute + * - MegaRequest::getNumDetails - Returns 1 if node is set as favourite, otherwise return 0 + * - MegaRequest::getFlag - Returns true (official attribute) + * - MegaRequest::getParamType - Returns MegaApi::NODE_ATTR_FAV * * @param node Node that will receive the information. - * @param favourite if YES set node as favourite, otherwise remove the attribute + * @param favourite if true set node as favourite, otherwise remove the attribute */ public void setNodeFavourite(MegaNode node, boolean favourite){ megaApi.setNodeFavourite(node, favourite); From 2641e620b37e4fd2de9d6e891c998f94198edc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C4=83t=C4=83lin=20R=C4=83ceanu?= Date: Mon, 12 Oct 2020 13:22:14 +0300 Subject: [PATCH 34/52] Duplicate banner list when copying a Request --- include/megaapi_impl.h | 2 +- src/megaapi_impl.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 5cd4e09570..c07745dbea 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -1623,7 +1623,7 @@ class MegaBannerPrivate : public MegaBanner class MegaBannerListPrivate : public MegaBannerList { public: - MegaBannerList* copy() const override; + MegaBannerListPrivate* copy() const override; // "different" return type is Covariant const MegaBanner* get(int i) const override; int size() const override; void add(MegaBannerPrivate&&); diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 2f93fb883b..db326df50e 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -3257,6 +3257,7 @@ MegaRequestPrivate::MegaRequestPrivate(MegaRequestPrivate *request) this->folderInfo = request->getMegaFolderInfo() ? request->folderInfo->copy() : NULL; this->settings = request->getMegaPushNotificationSettings() ? request->settings->copy() : NULL; this->backgroundMediaUpload = NULL; + this->mBannerList.reset(request->mBannerList ? request->mBannerList->copy() : nullptr); } AccountDetails *MegaRequestPrivate::getAccountDetails() const @@ -4007,7 +4008,7 @@ const char* MegaBannerPrivate::getImageLocation() const return std::get<6>(mDetails).c_str(); } -MegaBannerList* MegaBannerListPrivate::copy() const +MegaBannerListPrivate* MegaBannerListPrivate::copy() const { return new MegaBannerListPrivate(*this); } From a58f4578de44e37737d1c8456c0c3ee717c28c5f Mon Sep 17 00:00:00 2001 From: Matt Weir Date: Tue, 13 Oct 2020 09:51:27 +1300 Subject: [PATCH 35/52] megacli: added `timelocal` command for setting/getting file modified times for test --- examples/megacli.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/examples/megacli.cpp b/examples/megacli.cpp index 419bbb5a08..247bf62b80 100644 --- a/examples/megacli.cpp +++ b/examples/megacli.cpp @@ -2924,6 +2924,74 @@ void exec_fingerprint(autocomplete::ACState& s) } } +void exec_timelocal(autocomplete::ACState& s) +{ + bool get = s.words[1].s == "get"; + auto localfilepath = LocalPath::fromPath(s.words[2].s, *client->fsaccess); + + if (get && s.words.size() != 3 || !get && s.words.size() != 4) + { + cout << "wrong number of arguments for : " << s.words[1].s << endl; + return; + } + + m_time_t set_time = 0; + + if (!get) + { + // similar to Transfers::complete() + + std::istringstream is(s.words[3].s); + std::tm tm_record; + is >> std::get_time(&tm_record, "%Y-%m-%d %H:%M:%S"); + + set_time = m_mktime(&tm_record); + + cout << "Setting mtime to " << set_time << endl; + + bool success = client->fsaccess->setmtimelocal(localfilepath, set_time); + if (!success) + { + cout << "setmtimelocal failed! Was it transient? " << client->fsaccess->transient_error << endl; + } + } + + // perform get in both cases + auto fa = client->fsaccess->newfileaccess(); + if (fa->fopen(localfilepath, true, false)) + { + FileFingerprint fp; + fp.genfingerprint(fa.get()); + if (fp.isvalid) + { + std::tm tm_record; + m_localtime(fp.mtime, &tm_record); + cout << "mtime for file is " << fp.mtime << ": " << std::put_time(&tm_record, "%Y-%m-%d %H:%M:%S") << endl; + + if (!get) + { + if (::mega::abs(set_time - fp.mtime) <= 2) + { + cout << "mtime read back is within 2 seconds, so success. Actual difference: " << ::mega::abs(set_time - fp.mtime) << endl; + } + else + { + cout << "ERROR Silent failure in setmtimelocal, difference is " << ::mega::abs(set_time - fp.mtime) << endl; + } + } + } + else + { + cout << "fingerprint generation failed: " << localfilepath.toPath(*client->fsaccess) << endl; + } + } + else + { + cout << "fopen failed: " << localfilepath.toPath(*client->fsaccess) << endl; + } + +} + MegaCLILogger gLogger; autocomplete::ACN autocompleteSyntax() @@ -3045,6 +3113,7 @@ autocomplete::ACN autocompleteSyntax() p->Add(exec_setmaxuploadspeed, sequence(text("setmaxuploadspeed"), opt(wholenumber(10000)))); p->Add(exec_handles, sequence(text("handles"), opt(either(text("on"), text("off"))))); p->Add(exec_httpsonly, sequence(text("httpsonly"), opt(either(text("on"), text("off"))))); + p->Add(exec_timelocal, sequence(text("mtimelocal"), either(text("set"), text("get")), localFSPath(), opt(param("datetime")))); p->Add(exec_mfac, sequence(text("mfac"), param("email"))); p->Add(exec_mfae, sequence(text("mfae"))); From ccf8f564f17e09c00820d83d67cf8b7ba8eceece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Thu, 15 Oct 2020 14:24:23 +0200 Subject: [PATCH 36/52] Use definition instead of hardcoded value This branch introduces the definition, so let's use it wherever it's hardcoded. --- src/megaclient.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index dc908c9953..7f9aae8aef 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -15323,7 +15323,7 @@ namespace action_bucket_compare const static string webclient_mime_audio_extensions = ".3ga.aac.adp.aif.aifc.aiff.au.caf.dra.dts.dtshd.ecelp4800.ecelp7470.ecelp9600.eol.flac.iff.kar.lvp.m2a.m3a.m3u.m4a.mid.midi.mka.mp2.mp2a.mp3.mp4a.mpga.oga.ogg.opus.pya.ra.ram.rip.rmi.rmp.s3m.sil.snd.spx.uva.uvva.wav.wax.weba.wma.xm."; const static string webclient_mime_document_extensions = ".ans.ascii.doc.docx.dotx.json.log.ods.odt.pages.pdf.ppc.pps.ppt.pptx.rtf.stc.std.stw.sti.sxc.sxd.sxi.sxm.sxw.txt.wpd.wps.xls.xlsx.xlt.xltm."; - bool nodeIsVideo(const Node *n, char ext[12], const MegaClient& mc) + bool nodeIsVideo(const Node *n, char ext[MAXEXTENSIONLEN], const MegaClient& mc) { if (n->hasfileattribute(fa_media) && n->nodekey().size() == FILENODEKEYLENGTH) { @@ -15351,17 +15351,17 @@ namespace action_bucket_compare return action_bucket_compare::webclient_mime_video_extensions.find(ext) != string::npos; } - bool nodeIsAudio(const Node *n, char ext[12]) + bool nodeIsAudio(const Node *n, char ext[MAXEXTENSIONLEN]) { return action_bucket_compare::webclient_mime_audio_extensions.find(ext) != string::npos; } - bool nodeIsDocument(const Node *n, char ext[12]) + bool nodeIsDocument(const Node *n, char ext[MAXEXTENSIONLEN]) { return action_bucket_compare::webclient_mime_document_extensions.find(ext) != string::npos; } - bool nodeIsPhoto(const Node *n, char ext[12], bool checkPreview) + bool nodeIsPhoto(const Node *n, char ext[MAXEXTENSIONLEN], bool checkPreview) { // evaluate according to the webclient rules, so that we get exactly the same bucketing. return action_bucket_compare::webclient_is_image_def.find(ext) != string::npos || @@ -15391,7 +15391,7 @@ namespace action_bucket_compare return a.time > b.time; } - bool getExtensionDotted(const Node* n, char ext[12], const MegaClient& mc) + bool getExtensionDotted(const Node* n, char ext[MAXEXTENSIONLEN], const MegaClient& mc) { auto localname = LocalPath::fromPath(n->displayname(), *mc.fsaccess); if (mc.fsaccess->getextension(localname, ext, MAXEXTENSIONLEN)) // plenty of buffer space left to append a '.' @@ -15407,7 +15407,7 @@ namespace action_bucket_compare bool MegaClient::nodeIsMedia(const Node *n, bool *isphoto, bool *isvideo) const { - char ext[12]; + char ext[MAXEXTENSIONLEN]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { bool a = action_bucket_compare::nodeIsPhoto(n, ext, true); @@ -15431,7 +15431,7 @@ bool MegaClient::nodeIsMedia(const Node *n, bool *isphoto, bool *isvideo) const bool MegaClient::nodeIsVideo(const Node *n) const { - char ext[12]; + char ext[MAXEXTENSIONLEN]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { return action_bucket_compare::nodeIsVideo(n, ext, *this); @@ -15441,7 +15441,7 @@ bool MegaClient::nodeIsVideo(const Node *n) const bool MegaClient::nodeIsPhoto(const Node *n, bool checkPreview) const { - char ext[12]; + char ext[MAXEXTENSIONLEN]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { return action_bucket_compare::nodeIsPhoto(n, ext, checkPreview); @@ -15451,7 +15451,7 @@ bool MegaClient::nodeIsPhoto(const Node *n, bool checkPreview) const bool MegaClient::nodeIsAudio(const Node *n) const { - char ext[12]; + char ext[MAXEXTENSIONLEN]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { return action_bucket_compare::nodeIsAudio(n, ext); @@ -15461,7 +15461,7 @@ bool MegaClient::nodeIsAudio(const Node *n) const bool MegaClient::nodeIsDocument(const Node *n) const { - char ext[12]; + char ext[MAXEXTENSIONLEN]; if (n->type == FILENODE && action_bucket_compare::getExtensionDotted(n, ext, *this)) { return action_bucket_compare::nodeIsDocument(n, ext); From ab6118b3808ef657745d0744593464b5b6b91e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Thu, 15 Oct 2020 14:44:28 +0200 Subject: [PATCH 37/52] Adjust new definitions to avoid clashes The `NODE_xxx` already exists. The new types defined in `types.h` are not required. --- include/mega/types.h | 6 ----- include/megaapi.h | 17 +++++++++----- include/megaapi_impl.h | 10 ++++----- src/megaapi.cpp | 6 ++--- src/megaapi_impl.cpp | 50 +++++++++++++++++++++--------------------- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/include/mega/types.h b/include/mega/types.h index 0b69d079f4..d5a28cf1ff 100644 --- a/include/mega/types.h +++ b/include/mega/types.h @@ -272,12 +272,6 @@ typedef list file_list; // RUBBISH - rubbish bin typedef enum { TYPE_UNKNOWN = -1, FILENODE = 0, FOLDERNODE, ROOTNODE, INCOMINGNODE, RUBBISHNODE } nodetype_t; -// node file types: -typedef enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, NODE_VIDEO, NODE_DOCUMENT, } nodefiletype_t; - -// search target types -typedef enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, TARGET_ROOTNODE, TARGET_ALL, } searchtarget_t; - typedef enum { LBL_UNKNOWN = 0, LBL_RED = 1, LBL_ORANGE = 2, LBL_YELLOW = 3, LBL_GREEN = 4, LBL_BLUE = 5, LBL_PURPLE = 6, LBL_GREY = 7, } nodelabel_t; diff --git a/include/megaapi.h b/include/megaapi.h index 581af544e5..add5a98797 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14141,11 +14141,18 @@ class MegaApi ORDER_LINK_CREATION_ASC, ORDER_LINK_CREATION_DESC, ORDER_LABEL_ASC, ORDER_LABEL_DESC, ORDER_FAV_ASC, ORDER_FAV_DESC,}; - enum { NODE_UNKNOWN = 0, NODE_PHOTO, NODE_AUDIO, - NODE_VIDEO, NODE_DOCUMENT, }; + enum { FILE_TYPE_UNKNOWN = 0, + FILE_TYPE_PHOTO, + FILE_TYPE_AUDIO, + FILE_TYPE_VIDEO, + FILE_TYPE_DOCUMENT, + }; - enum { TARGET_INSHARE = 0, TARGET_OUTSHARE, TARGET_PUBLICLINK, - TARGET_ROOTNODE, TARGET_ALL, }; + enum { SEARCH_TARGET_INSHARE = 0, + SEARCH_TARGET_OUTSHARE, + SEARCH_TARGET_PUBLICLINK, + SEARCH_TARGET_ROOTNODE, + SEARCH_TARGET_ALL, }; /** * @brief Get the number of child nodes @@ -15822,7 +15829,7 @@ class MegaApi * * @return List of nodes that match with the search parameters */ - MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = NODE_UNKNOWN, int target = TARGET_ALL); + MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = FILE_TYPE_UNKNOWN, int target = SEARCH_TARGET_ALL); /** * @brief Return a list of buckets, each bucket containing a list of recently added/modified nodes diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index ec5130d295..ec52002350 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -1963,14 +1963,14 @@ class TreeProcessor class SearchTreeProcessor : public TreeProcessor { public: - SearchTreeProcessor(MegaClient *client, const char *search, nodefiletype_t type); - virtual bool processNode(Node *node); + SearchTreeProcessor(MegaClient *client, const char *search, int type); + virtual bool processNode(Node* node); bool isValidTypeNode(Node *node); virtual ~SearchTreeProcessor() {} vector &getResults(); protected: - nodefiletype_t mType; + int mFileType; const char *mSearch; vector mResults; MegaClient *mClient; @@ -2514,9 +2514,9 @@ class MegaApiImpl : public MegaApp MegaRecentActionBucketList* getRecentActions(unsigned days = 90, unsigned maxnodes = 10000); - MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN, int target = MegaApi::TARGET_ALL); + MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_UNKNOWN, int target = MegaApi::SEARCH_TARGET_ALL); bool processMegaTree(MegaNode* node, MegaTreeProcessor* processor, bool recursive = 1); - MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::NODE_UNKNOWN); + MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_UNKNOWN); MegaNode *createForeignFileNode(MegaHandle handle, const char *key, const char *name, m_off_t size, m_off_t mtime, MegaHandle parentHandle, const char *privateauth, const char *publicauth, const char *chatauth); diff --git a/src/megaapi.cpp b/src/megaapi.cpp index 874f1cbb98..07fbcd8573 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3843,17 +3843,17 @@ MegaNodeList *MegaApi::search(const char *searchString, MegaCancelToken *cancelT MegaNodeList* MegaApi::searchOnInShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_INSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_INSHARE); } MegaNodeList* MegaApi::searchOnOutShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_OUTSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_OUTSHARE); } MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::NODE_UNKNOWN, MegaApi::TARGET_PUBLICLINK); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_PUBLICLINK); } MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 1bfeb8f47e..0d2c2f5147 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -11027,13 +11027,13 @@ bool MegaApiImpl::processMegaTree(MegaNode* n, MegaTreeProcessor* processor, boo MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *cancelToken, int order, int type) { - if (!searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) + if (!searchString && (type < MegaApi::FILE_TYPE_PHOTO || type > MegaApi::FILE_TYPE_DOCUMENT)) { // If no search string and type is not valid return new MegaNodeListPrivate(); } - if (type != MegaApi::NODE_UNKNOWN + if (type != MegaApi::FILE_TYPE_UNKNOWN && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) { return new MegaNodeListPrivate(); @@ -11059,7 +11059,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can && !(cancelToken && cancelToken->isCancelled()); i++) { node = client->nodebyhandle(client->rootnodes[i]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, true, cancelToken); node_vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -11071,7 +11071,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11575,13 +11575,13 @@ bool MegaApiImpl::processTree(Node* node, TreeProcessor* processor, bool recursi MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) { - if (!n && !searchString && (type < MegaApi::NODE_PHOTO || type > MegaApi::NODE_DOCUMENT)) + if (!n && !searchString && (type < MegaApi::FILE_TYPE_PHOTO || type > MegaApi::FILE_TYPE_DOCUMENT)) { // If node is not valid, and no search string, and type is not valid return new MegaNodeListPrivate(); } - if (type != MegaApi::NODE_UNKNOWN + if (type != MegaApi::FILE_TYPE_UNKNOWN && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) { return new MegaNodeListPrivate(); @@ -11610,7 +11610,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } // searchString and nodeType (if provided), are considered in search - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); for (node_list::iterator it = node->children.begin(); it != node->children.end() && !(cancelToken && cancelToken->isCancelled()); ) { @@ -11627,24 +11627,24 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan Node *node; // Target parameter is only considered if node is not provided - if (target < MegaApi::TARGET_INSHARE || target > MegaApi::TARGET_ALL) + if (target < MegaApi::SEARCH_TARGET_INSHARE || target > MegaApi::SEARCH_TARGET_ALL) { return new MegaNodeListPrivate(); } - if (target == MegaApi::TARGET_ROOTNODE || target == MegaApi::TARGET_ALL) + if (target == MegaApi::SEARCH_TARGET_ROOTNODE || target == MegaApi::SEARCH_TARGET_ALL) { // Search on rootnode (cloud, excludes Inbox and Rubbish) node = client->nodebyhandle(client->rootnodes[0]); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, recursive, cancelToken); node_vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); } - if (target == MegaApi::TARGET_INSHARE || target == MegaApi::TARGET_ALL) + if (target == MegaApi::SEARCH_TARGET_INSHARE || target == MegaApi::SEARCH_TARGET_ALL) { // Search on inshares unique_ptr shares(getInSharesList(MegaApi::ORDER_NONE)); @@ -11652,7 +11652,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, recursive, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11660,7 +11660,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } } - if (target == MegaApi::TARGET_OUTSHARE) + if (target == MegaApi::SEARCH_TARGET_OUTSHARE) { // Search on outshares unique_ptrshares (getOutShares(MegaApi::ORDER_NONE)); @@ -11668,7 +11668,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan { node = client->nodebyhandle(shares->get(i)->getNodeHandle()); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, recursive, cancelToken); vector& vNodes = searchProcessor.getResults(); @@ -11676,14 +11676,14 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan } } - if (target == MegaApi::TARGET_PUBLICLINK) + if (target == MegaApi::SEARCH_TARGET_PUBLICLINK) { // Search on public links for (auto it = client->mPublicLinks.begin(); it != client->mPublicLinks.end() && !(cancelToken && cancelToken->isCancelled()); it++) { node = client->nodebyhandle(it->first); - SearchTreeProcessor searchProcessor(client, searchString, static_cast(type)); + SearchTreeProcessor searchProcessor(client, searchString, type); processTree(node, &searchProcessor, true, cancelToken); vector& vNodes = searchProcessor.getResults(); result.insert(result.end(), vNodes.begin(), vNodes.end()); @@ -12009,10 +12009,10 @@ MegaNode *MegaApiImpl::getNodeByCRC(const char *crc, MegaNode *parent) return NULL; } -SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, nodefiletype_t type) +SearchTreeProcessor::SearchTreeProcessor(MegaClient *client, const char *search, int type) { mSearch = search; - mType = type; + mFileType = type; mClient = client; } @@ -12049,7 +12049,7 @@ bool SearchTreeProcessor::processNode(Node* node) return true; } - if (!mSearch && (!mClient || (mType < MegaApi::NODE_UNKNOWN || mType > MegaApi::NODE_DOCUMENT))) + if (!mSearch && (!mClient || (mFileType < MegaApi::FILE_TYPE_UNKNOWN || mFileType > MegaApi::FILE_TYPE_DOCUMENT))) { // If no search string provided, client and type must be valid, otherwise return false return false; @@ -12075,17 +12075,17 @@ bool SearchTreeProcessor::isValidTypeNode(Node *node) return true; } - switch (mType) + switch (mFileType) { - case MegaApi::NODE_PHOTO: + case MegaApi::FILE_TYPE_PHOTO: return mClient->nodeIsPhoto(node, false); - case MegaApi::NODE_AUDIO: + case MegaApi::FILE_TYPE_AUDIO: return mClient->nodeIsAudio(node); - case MegaApi::NODE_VIDEO: + case MegaApi::FILE_TYPE_VIDEO: return mClient->nodeIsVideo(node); - case MegaApi::NODE_DOCUMENT: + case MegaApi::FILE_TYPE_DOCUMENT: return mClient->nodeIsDocument(node); - case MegaApi::NODE_UNKNOWN: + case MegaApi::FILE_TYPE_UNKNOWN: default: return true; } From ca751584d95f560086ad5176fa0590cdab2bdb31 Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Thu, 15 Oct 2020 15:01:11 +0200 Subject: [PATCH 38/52] Update new types in documentation --- include/megaapi.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index add5a98797..9429695f70 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -15739,12 +15739,12 @@ class MegaApi * If node and searchString are not provided, and node type is not valid, this method will * return an empty list. * - * If parameter type is different of MegaApi::NODE_UNKNOWN, the following values for parameter + * If parameter type is different of MegaApi::FILE_TYPE_UNKNOWN, the following values for parameter * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC * * The search is case-insensitive. If the search string is not provided but type has any value - * defined at nodefiletype_t (except NODE_UNKNOWN), + * defined at nodefiletype_t (except FILE_TYPE_UNKNOWN), * this method will return a list that contains nodes of the same type as provided. * * You take the ownership of the returned value. @@ -15813,19 +15813,19 @@ class MegaApi * * @param type Type of nodes requested in the search * Valid values for this parameter are: - * - MegaApi::NODE_UNKNOWN = 0 --> all types - * - MegaApi::NODE_PHOTO = 1 - * - MegaApi::NODE_AUDIO = 2 - * - MegaApi::NODE_VIDEO = 3 - * - MegaApi::NODE_DOCUMENT = 4 + * - MegaApi::FILE_TYPE_UNKNOWN = 0 --> all types + * - MegaApi::FILE_TYPE_PHOTO = 1 + * - MegaApi::FILE_TYPE_AUDIO = 2 + * - MegaApi::FILE_TYPE_VIDEO = 3 + * - MegaApi::FILE_TYPE_DOCUMENT = 4 * * @param target Target type where this method will search * Valid values for this parameter are - * - TARGET_INSHARE = 0 - * - TARGET_OUTSHARE = 1 - * - TARGET_PUBLICLINK = 2 - * - TARGET_ROOTNODE = 3 - * - TARGET_ALL = 4 + * - SEARCH_TARGET_INSHARE = 0 + * - SEARCH_TARGET_OUTSHARE = 1 + * - SEARCH_TARGET_PUBLICLINK = 2 + * - SEARCH_TARGET_ROOTNODE = 3 + * - SEARCH_TARGET_ALL = 4 * * @return List of nodes that match with the search parameters */ From 2cd6125851284b0a65ae786db0ab23dd10806ca5 Mon Sep 17 00:00:00 2001 From: Lancy Date: Fri, 16 Oct 2020 12:12:09 +1300 Subject: [PATCH 39/52] feat(New Home): Fixed the build issue. #IOS-4145 --- bindings/ios/MEGASdk.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/ios/MEGASdk.mm b/bindings/ios/MEGASdk.mm index 25a40a6eb2..d625322788 100644 --- a/bindings/ios/MEGASdk.mm +++ b/bindings/ios/MEGASdk.mm @@ -2087,8 +2087,7 @@ - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString } - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString cancelToken:(MEGACancelToken *)cancelToken recursive:(BOOL)recursive order:(MEGASortOrderType)order { -// return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order) cMemoryOwn:YES]; - return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order, (int)MEGANodeFormatTypeUnknown, (int)MEGAFolderTargetTypeAll) cMemoryOwn:YES]; + return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)order) cMemoryOwn:YES]; } - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node searchString:(NSString *)searchString { @@ -2102,7 +2101,8 @@ - (MEGANodeList *)nodeListSearchForNode:(MEGANode *)node orderType:(MEGASortOrderType)orderType nodeFormatType:(MEGANodeFormatType)nodeFormatType folderTargetType:(MEGAFolderTargetType)folderTargetType { - return [MEGANodeList.alloc initWithNodeList:self.megaApi->search(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)orderType, (int)nodeFormatType, (int)folderTargetType) cMemoryOwn:YES]; + + return [MEGANodeList.alloc initWithNodeList:self.megaApi->searchByType(node ? [node getCPtr] : NULL, searchString.UTF8String, cancelToken ? [cancelToken getCPtr] : NULL, recursive, (int)orderType, (int)nodeFormatType, (int)folderTargetType) cMemoryOwn:YES]; } - (NSMutableArray *)recentActions { MegaRecentActionBucketList *megaRecentActionBucketList = self.megaApi->getRecentActions(); From d7d5a906fea03567b26a8a149b837635264adbed Mon Sep 17 00:00:00 2001 From: Matt Weir Date: Mon, 19 Oct 2020 18:20:42 +1300 Subject: [PATCH 40/52] fix: use committer when deletemissing() is called --- src/megaclient.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/megaclient.cpp b/src/megaclient.cpp index 3c3765a352..784ae28326 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -2675,6 +2675,8 @@ void MegaClient::exec() // scan for items that were deleted while the sync was stopped // FIXME: defer this until RETRY queue is processed sync->scanseqno++; + + DBTableTransactionCommitter committer(tctable); // just one db transaction to remove all the LocalNodes that get deleted sync->deletemissing(sync->localroot.get()); } } @@ -2873,6 +2875,7 @@ void MegaClient::exec() if (sync->fullscan) { // recursively delete all LocalNodes that were deleted (not moved or renamed!) + DBTableTransactionCommitter committer(tctable); // just one db transaction to remove all the LocalNodes that get deleted sync->deletemissing(sync->localroot.get()); sync->cachenodes(); } From 5fd3a04790b3e1ba0bf13c5c7e6ae8804270211c Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Andres Date: Mon, 19 Oct 2020 11:26:34 +0200 Subject: [PATCH 41/52] Rename FILE_TYPE_UNKNOWN to FILE_TYPE_DEFAULT to avoid clash at WinBase.h --- include/megaapi.h | 11 ++++++----- include/megaapi_impl.h | 4 ++-- src/megaapi.cpp | 6 +++--- src/megaapi_impl.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/megaapi.h b/include/megaapi.h index 9429695f70..ff7510334b 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -14141,7 +14141,8 @@ class MegaApi ORDER_LINK_CREATION_ASC, ORDER_LINK_CREATION_DESC, ORDER_LABEL_ASC, ORDER_LABEL_DESC, ORDER_FAV_ASC, ORDER_FAV_DESC,}; - enum { FILE_TYPE_UNKNOWN = 0, + + enum { FILE_TYPE_DEFAULT = 0, // FILE_TYPE_UNKNOWN already exists at WinBase.h FILE_TYPE_PHOTO, FILE_TYPE_AUDIO, FILE_TYPE_VIDEO, @@ -15739,12 +15740,12 @@ class MegaApi * If node and searchString are not provided, and node type is not valid, this method will * return an empty list. * - * If parameter type is different of MegaApi::FILE_TYPE_UNKNOWN, the following values for parameter + * If parameter type is different of MegaApi::FILE_TYPE_DEFAULT, the following values for parameter * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC * * The search is case-insensitive. If the search string is not provided but type has any value - * defined at nodefiletype_t (except FILE_TYPE_UNKNOWN), + * defined at nodefiletype_t (except FILE_TYPE_DEFAULT), * this method will return a list that contains nodes of the same type as provided. * * You take the ownership of the returned value. @@ -15813,7 +15814,7 @@ class MegaApi * * @param type Type of nodes requested in the search * Valid values for this parameter are: - * - MegaApi::FILE_TYPE_UNKNOWN = 0 --> all types + * - MegaApi::FILE_TYPE_DEFAULT = 0 --> all types * - MegaApi::FILE_TYPE_PHOTO = 1 * - MegaApi::FILE_TYPE_AUDIO = 2 * - MegaApi::FILE_TYPE_VIDEO = 3 @@ -15829,7 +15830,7 @@ class MegaApi * * @return List of nodes that match with the search parameters */ - MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = FILE_TYPE_UNKNOWN, int target = SEARCH_TARGET_ALL); + MegaNodeList* searchByType(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = ORDER_NONE, int type = FILE_TYPE_DEFAULT, int target = SEARCH_TARGET_ALL); /** * @brief Return a list of buckets, each bucket containing a list of recently added/modified nodes diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 909bd96acd..25e72a0f9c 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -2514,9 +2514,9 @@ class MegaApiImpl : public MegaApp MegaRecentActionBucketList* getRecentActions(unsigned days = 90, unsigned maxnodes = 10000); - MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_UNKNOWN, int target = MegaApi::SEARCH_TARGET_ALL); + MegaNodeList* search(MegaNode *node, const char *searchString, MegaCancelToken *cancelToken, bool recursive = true, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_DEFAULT, int target = MegaApi::SEARCH_TARGET_ALL); bool processMegaTree(MegaNode* node, MegaTreeProcessor* processor, bool recursive = 1); - MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_UNKNOWN); + MegaNodeList* search(const char* searchString, MegaCancelToken *cancelToken, int order = MegaApi::ORDER_NONE, int type = MegaApi::FILE_TYPE_DEFAULT); MegaNode *createForeignFileNode(MegaHandle handle, const char *key, const char *name, m_off_t size, m_off_t mtime, MegaHandle parentHandle, const char *privateauth, const char *publicauth, const char *chatauth); diff --git a/src/megaapi.cpp b/src/megaapi.cpp index 07fbcd8573..d565e0145f 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3843,17 +3843,17 @@ MegaNodeList *MegaApi::search(const char *searchString, MegaCancelToken *cancelT MegaNodeList* MegaApi::searchOnInShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_INSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_DEFAULT, MegaApi::SEARCH_TARGET_INSHARE); } MegaNodeList* MegaApi::searchOnOutShares(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_OUTSHARE); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_DEFAULT, MegaApi::SEARCH_TARGET_OUTSHARE); } MegaNodeList* MegaApi::searchOnPublicLinks(const char *searchString, MegaCancelToken *cancelToken, int order) { - return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_UNKNOWN, MegaApi::SEARCH_TARGET_PUBLICLINK); + return pImpl->search(nullptr, searchString, cancelToken, true, order, MegaApi::FILE_TYPE_DEFAULT, MegaApi::SEARCH_TARGET_PUBLICLINK); } MegaNodeList* MegaApi::searchByType(MegaNode *n, const char *searchString, MegaCancelToken *cancelToken, bool recursive, int order, int type, int target) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 59d6bcded8..1baafeedac 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -10985,7 +10985,7 @@ MegaNodeList *MegaApiImpl::search(const char *searchString, MegaCancelToken *can return new MegaNodeListPrivate(); } - if (type != MegaApi::FILE_TYPE_UNKNOWN + if (type != MegaApi::FILE_TYPE_DEFAULT && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) { return new MegaNodeListPrivate(); @@ -11533,7 +11533,7 @@ MegaNodeList* MegaApiImpl::search(MegaNode *n, const char* searchString, MegaCan return new MegaNodeListPrivate(); } - if (type != MegaApi::FILE_TYPE_UNKNOWN + if (type != MegaApi::FILE_TYPE_DEFAULT && (order < MegaApi::ORDER_NONE || order > MegaApi::ORDER_ALPHABETICAL_DESC)) { return new MegaNodeListPrivate(); @@ -12001,7 +12001,7 @@ bool SearchTreeProcessor::processNode(Node* node) return true; } - if (!mSearch && (!mClient || (mFileType < MegaApi::FILE_TYPE_UNKNOWN || mFileType > MegaApi::FILE_TYPE_DOCUMENT))) + if (!mSearch && (!mClient || (mFileType < MegaApi::FILE_TYPE_DEFAULT || mFileType > MegaApi::FILE_TYPE_DOCUMENT))) { // If no search string provided, client and type must be valid, otherwise return false return false; @@ -12037,7 +12037,7 @@ bool SearchTreeProcessor::isValidTypeNode(Node *node) return mClient->nodeIsVideo(node); case MegaApi::FILE_TYPE_DOCUMENT: return mClient->nodeIsDocument(node); - case MegaApi::FILE_TYPE_UNKNOWN: + case MegaApi::FILE_TYPE_DEFAULT: default: return true; } From d1cc567df081df2cb95e1ba195fd89beb29fb3a1 Mon Sep 17 00:00:00 2001 From: Yenel Date: Mon, 19 Oct 2020 15:37:59 +0200 Subject: [PATCH 42/52] Fix searchByType Android bindings --- bindings/java/nz/mega/sdk/MegaApiJava.java | 160 ++++++++++++++++++--- 1 file changed, 143 insertions(+), 17 deletions(-) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index 3401a720b3..2fc52f5a78 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -202,12 +202,17 @@ void runCallback(Runnable runnable) { public final static int HTTP_SERVER_ALLOW_CREATED_LOCAL_LINKS = MegaApi.HTTP_SERVER_ALLOW_CREATED_LOCAL_LINKS; public final static int HTTP_SERVER_ALLOW_LAST_LOCAL_LINK = MegaApi.HTTP_SERVER_ALLOW_LAST_LOCAL_LINK; - public final static int TARGET_ROOTNODES = 3; - public final static int NODE_UNKNOWN = 0; - public final static int NODE_PHOTO = 1; - public final static int NODE_AUDIO = 2; - public final static int NODE_VIDEO = 3; - public final static int NODE_DOCUMENT = 4; + public final static int FILE_TYPE_DEFAULT = MegaApi.FILE_TYPE_DEFAULT; + public final static int FILE_TYPE_PHOTO = MegaApi.FILE_TYPE_PHOTO; + public final static int FILE_TYPE_AUDIO = MegaApi.FILE_TYPE_AUDIO; + public final static int FILE_TYPE_VIDEO = MegaApi.FILE_TYPE_VIDEO; + public final static int FILE_TYPE_DOCUMENT = MegaApi.FILE_TYPE_DOCUMENT; + + public final static int SEARCH_TARGET_INSHARE = MegaApi.SEARCH_TARGET_INSHARE; + public final static int SEARCH_TARGET_OUTSHARE = MegaApi.SEARCH_TARGET_OUTSHARE; + public final static int SEARCH_TARGET_PUBLICLINK = MegaApi.SEARCH_TARGET_PUBLICLINK; + public final static int SEARCH_TARGET_ROOTNODE = MegaApi.SEARCH_TARGET_ROOTNODE; + public final static int SEARCH_TARGET_ALL = MegaApi.SEARCH_TARGET_ALL; MegaApi getMegaApi() { @@ -8496,6 +8501,138 @@ public ArrayList search(String searchString) { return nodeListToArray(megaApi.search(searchString)); } + /** + * Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore, or on the contrary search in a + * specific target (root nodes, inshares, outshares, public links) + * - Search recursively + * - Containing a search string in their name + * - Filter by the type of the node + * - Order the returned list + * + * If node is provided, it will be the parent node of the tree to explore, + * search string and/or nodeType can be added to search parameters + * + * If node and searchString are not provided, and node type is not valid, this method will + * return an empty list. + * + * If parameter type is different of MegaApi::FILE_TYPE_DEFAULT, the following values for parameter + * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, + * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at nodefiletype_t (except FILE_TYPE_DEFAULT), + * this method will return a list that contains nodes of the same type as provided. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param recursive True if you want to seach recursively in the node tree. + * False if you want to seach in the children of the node only + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * - MegaApi::ORDER_LABEL_ASC = 17 + * Sort by color label, ascending + * + * - MegaApi::ORDER_LABEL_DESC = 18 + * Sort by color label, descending + * + * - MegaApi::ORDER_FAV_ASC = 19 + * Sort nodes with favourite attr first + * + * - MegaApi::ORDER_FAV_DESC = 20 + * Sort nodes with favourite attr last + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::FILE_TYPE_DEFAULT = 0 --> all types + * - MegaApi::FILE_TYPE_PHOTO = 1 + * - MegaApi::FILE_TYPE_AUDIO = 2 + * - MegaApi::FILE_TYPE_VIDEO = 3 + * - MegaApi::FILE_TYPE_DOCUMENT = 4 + * + * @param target Target type where this method will search + * Valid values for this parameter are + * - SEARCH_TARGET_INSHARE = 0 + * - SEARCH_TARGET_OUTSHARE = 1 + * - SEARCH_TARGET_PUBLICLINK = 2 + * - SEARCH_TARGET_ROOTNODE = 3 + * - SEARCH_TARGET_ALL = 4 + * + * @return List of nodes that match with the search parameters + */ + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken, boolean recursive, int order, int type, int target) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, + order, type, target)); + } + + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken, boolean recursive, int order, int type) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, + order, type)); + } + + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken, boolean recursive, int order) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, + order)); + } + + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken, boolean recursive) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive)); + } + + public ArrayList searchByType(MegaNode node, String searchString, + MegaCancelToken cancelToken) { + return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken)); + } /** * Return a list of buckets, each bucket containing a list of recently added/modified nodes @@ -9888,15 +10025,4 @@ public void getUserEmail(long handle, nz.mega.sdk.MegaRequestListenerInterface l public void cancelCreateAccount(MegaRequestListenerInterface listener){ megaApi.cancelCreateAccount(createDelegateRequestListener(listener)); } - - /** - * Search nodes by type. - * - * TODO: add parameter descriptions - */ - public ArrayList searchByType(MegaNode node, String searchString, - MegaCancelToken cancelToken, boolean recursive, int order, int type, int target) { - return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, - order, type, target)); - } } From 8efa0508a7423bcc4c8a49fdc3e81ca203f74bd4 Mon Sep 17 00:00:00 2001 From: Yenel Date: Mon, 19 Oct 2020 16:02:34 +0200 Subject: [PATCH 43/52] Add used searchByType Android binding --- bindings/java/nz/mega/sdk/MegaApiJava.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index 2fc52f5a78..f7f17bf39b 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -8612,6 +8612,11 @@ public ArrayList searchByType(MegaNode node, String searchString, order, type, target)); } + public ArrayList searchByType(int order, int type, int target) { + return nodeListToArray(megaApi.searchByType(null, null, null, true, + order, type, target)); + } + public ArrayList searchByType(MegaNode node, String searchString, MegaCancelToken cancelToken, boolean recursive, int order, int type) { return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, From 3ce1f93e9becb9e19d24bf1cf43b793ba9e272af Mon Sep 17 00:00:00 2001 From: Yenel Date: Mon, 19 Oct 2020 16:39:14 +0200 Subject: [PATCH 44/52] Add methods documentation --- bindings/java/nz/mega/sdk/MegaApiJava.java | 313 +++++++++++++++++++++ 1 file changed, 313 insertions(+) diff --git a/bindings/java/nz/mega/sdk/MegaApiJava.java b/bindings/java/nz/mega/sdk/MegaApiJava.java index f7f17bf39b..9290a4aaa8 100644 --- a/bindings/java/nz/mega/sdk/MegaApiJava.java +++ b/bindings/java/nz/mega/sdk/MegaApiJava.java @@ -8612,28 +8612,341 @@ public ArrayList searchByType(MegaNode node, String searchString, order, type, target)); } + /** + * Allow to search nodes with the following options: + * - Search in a specific target (root nodes, inshares, outshares, public links) + * - Filter by the type of the node + * - Order the returned list + * + * If node type is not valid, this method will return an empty list. + * + * If parameter type is different of MegaApi::FILE_TYPE_DEFAULT, the following values for parameter + * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, + * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * The search is case-insensitive. If the type has any value defined at nodefiletype_t + * (except FILE_TYPE_DEFAULT), this method will return a list + * that contains nodes of the same type as provided. + * + * You take the ownership of the returned value. + * + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * - MegaApi::ORDER_LABEL_ASC = 17 + * Sort by color label, ascending + * + * - MegaApi::ORDER_LABEL_DESC = 18 + * Sort by color label, descending + * + * - MegaApi::ORDER_FAV_ASC = 19 + * Sort nodes with favourite attr first + * + * - MegaApi::ORDER_FAV_DESC = 20 + * Sort nodes with favourite attr last + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::FILE_TYPE_DEFAULT = 0 --> all types + * - MegaApi::FILE_TYPE_PHOTO = 1 + * - MegaApi::FILE_TYPE_AUDIO = 2 + * - MegaApi::FILE_TYPE_VIDEO = 3 + * - MegaApi::FILE_TYPE_DOCUMENT = 4 + * + * @param target Target type where this method will search + * Valid values for this parameter are + * - SEARCH_TARGET_INSHARE = 0 + * - SEARCH_TARGET_OUTSHARE = 1 + * - SEARCH_TARGET_PUBLICLINK = 2 + * - SEARCH_TARGET_ROOTNODE = 3 + * - SEARCH_TARGET_ALL = 4 + * + * @return List of nodes that match with the search parameters + */ public ArrayList searchByType(int order, int type, int target) { return nodeListToArray(megaApi.searchByType(null, null, null, true, order, type, target)); } + /** + * Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore + * - Search recursively + * - Containing a search string in their name + * - Filter by the type of the node + * - Order the returned list + * + * If node is provided, it will be the parent node of the tree to explore, + * search string and/or nodeType can be added to search parameters + * + * If node and searchString are not provided, and node type is not valid, this method will + * return an empty list. + * + * If parameter type is different of MegaApi::FILE_TYPE_DEFAULT, the following values for parameter + * order are invalid: MegaApi::ORDER_PHOTO_ASC, MegaApi::ORDER_PHOTO_DESC, + * MegaApi::ORDER_VIDEO_ASC, MegaApi::ORDER_VIDEO_DESC + * + * The search is case-insensitive. If the search string is not provided but type has any value + * defined at nodefiletype_t (except FILE_TYPE_DEFAULT), + * this method will return a list that contains nodes of the same type as provided. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param recursive True if you want to seach recursively in the node tree. + * False if you want to seach in the children of the node only + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * - MegaApi::ORDER_LABEL_ASC = 17 + * Sort by color label, ascending + * + * - MegaApi::ORDER_LABEL_DESC = 18 + * Sort by color label, descending + * + * - MegaApi::ORDER_FAV_ASC = 19 + * Sort nodes with favourite attr first + * + * - MegaApi::ORDER_FAV_DESC = 20 + * Sort nodes with favourite attr last + * + * @param type Type of nodes requested in the search + * Valid values for this parameter are: + * - MegaApi::FILE_TYPE_DEFAULT = 0 --> all types + * - MegaApi::FILE_TYPE_PHOTO = 1 + * - MegaApi::FILE_TYPE_AUDIO = 2 + * - MegaApi::FILE_TYPE_VIDEO = 3 + * - MegaApi::FILE_TYPE_DOCUMENT = 4 + * + * @return List of nodes that match with the search parameters + */ public ArrayList searchByType(MegaNode node, String searchString, MegaCancelToken cancelToken, boolean recursive, int order, int type) { return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, order, type)); } + /** + * Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore + * - Search recursively + * - Containing a search string in their name + * - Order the returned list + * + * If node is provided, it will be the parent node of the tree to explore, + * search string can be added to search parameters + * + * If node and searchString are not provided, this method will + * return an empty list. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param recursive True if you want to seach recursively in the node tree. + * False if you want to seach in the children of the node only + * @param order Order for the returned list + * Valid values for this parameter are: + * - MegaApi::ORDER_NONE = 0 + * Undefined order + * + * - MegaApi::ORDER_DEFAULT_ASC = 1 + * Folders first in alphabetical order, then files in the same order + * + * - MegaApi::ORDER_DEFAULT_DESC = 2 + * Files first in reverse alphabetical order, then folders in the same order + * + * - MegaApi::ORDER_SIZE_ASC = 3 + * Sort by size, ascending + * + * - MegaApi::ORDER_SIZE_DESC = 4 + * Sort by size, descending + * + * - MegaApi::ORDER_CREATION_ASC = 5 + * Sort by creation time in MEGA, ascending + * + * - MegaApi::ORDER_CREATION_DESC = 6 + * Sort by creation time in MEGA, descending + * + * - MegaApi::ORDER_MODIFICATION_ASC = 7 + * Sort by modification time of the original file, ascending + * + * - MegaApi::ORDER_MODIFICATION_DESC = 8 + * Sort by modification time of the original file, descending + * + * - MegaApi::ORDER_PHOTO_ASC = 11 + * Sort with photos first, then by date ascending + * + * - MegaApi::ORDER_PHOTO_DESC = 12 + * Sort with photos first, then by date descending + * + * - MegaApi::ORDER_VIDEO_ASC = 13 + * Sort with videos first, then by date ascending + * + * - MegaApi::ORDER_VIDEO_DESC = 14 + * Sort with videos first, then by date descending + * + * - MegaApi::ORDER_LABEL_ASC = 17 + * Sort by color label, ascending + * + * - MegaApi::ORDER_LABEL_DESC = 18 + * Sort by color label, descending + * + * - MegaApi::ORDER_FAV_ASC = 19 + * Sort nodes with favourite attr first + * + * - MegaApi::ORDER_FAV_DESC = 20 + * Sort nodes with favourite attr last + * + * @return List of nodes that match with the search parameters + */ public ArrayList searchByType(MegaNode node, String searchString, MegaCancelToken cancelToken, boolean recursive, int order) { return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive, order)); } + /** + * Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore + * - Search recursively + * - Containing a search string in their name + * + * If node is provided, it will be the parent node of the tree to explore, + * search string can be added to search parameters + * + * If node and searchString are not provided, this method will + * return an empty list. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * @param recursive True if you want to seach recursively in the node tree. + * False if you want to seach in the children of the node only + * + * @return List of nodes that match with the search parameters + */ public ArrayList searchByType(MegaNode node, String searchString, MegaCancelToken cancelToken, boolean recursive) { return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken, recursive)); } + /** + * Allow to search nodes with the following options: + * - Search given a parent node of the tree to explore + * - Containing a search string in their name + * + * If node is provided, it will be the parent node of the tree to explore, + * search string can be added to search parameters + * + * If node and searchString are not provided, this method will + * return an empty list. + * + * You take the ownership of the returned value. + * + * This function allows to cancel the processing at any time by passing a MegaCancelToken and calling + * to MegaCancelToken::setCancelFlag(true). If a valid object is passed, it must be kept alive until + * this method returns. + * + * @param node The parent node of the tree to explore + * @param searchString Search string. The search is case-insensitive + * @param cancelToken MegaCancelToken to be able to cancel the processing at any time. + * + * @return List of nodes that match with the search parameters + */ public ArrayList searchByType(MegaNode node, String searchString, MegaCancelToken cancelToken) { return nodeListToArray(megaApi.searchByType(node, searchString, cancelToken)); From ae5396e647e2d9aa212e6fef59db70a22f1ee417 Mon Sep 17 00:00:00 2001 From: Lancy <53881615+lancy-mega@users.noreply.github.com> Date: Mon, 19 Oct 2020 22:43:09 +0200 Subject: [PATCH 45/52] Update bindings/ios/MEGASdk.h Co-authored-by: Simon Wang <43154373+simonwng@users.noreply.github.com> --- bindings/ios/MEGASdk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/ios/MEGASdk.h b/bindings/ios/MEGASdk.h index f984012620..2bc1449544 100644 --- a/bindings/ios/MEGASdk.h +++ b/bindings/ios/MEGASdk.h @@ -87,7 +87,7 @@ typedef NS_ENUM (NSInteger, MEGAFolderTargetType) { MEGAFolderTargetTypeInShare = 0, MEGAFolderTargetTypeOutShare, MEGAFolderTargetTypePublicLink, - MEGAFolderTargetTypeRootNodes, + MEGAFolderTargetTypeRootNode, MEGAFolderTargetTypeAll, }; From 45946c369b264f2e4f99047a9c114ecdabecc8ae Mon Sep 17 00:00:00 2001 From: Simon Wang <43154373+simonwng@users.noreply.github.com> Date: Tue, 20 Oct 2020 07:44:09 +1100 Subject: [PATCH 46/52] Update bindings/ios/MEGASdk.h --- bindings/ios/MEGASdk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/ios/MEGASdk.h b/bindings/ios/MEGASdk.h index 2bc1449544..d3dc5f10db 100644 --- a/bindings/ios/MEGASdk.h +++ b/bindings/ios/MEGASdk.h @@ -7370,7 +7370,7 @@ typedef NS_ENUM(NSInteger, AffiliateType) { * - MEGAFolderTargetTypeInShare = 0 * - MEGAFolderTargetTypeOutShare = 1 * - MEGAFolderTargetTypePublicLink = 2 - * - MEGAFolderTargetTypeRootNodes = 3 + * - MEGAFolderTargetTypeRootNode = 3 * - MEGAFolderTargetTypeAll = 4 * * @return List of nodes that contain the desired string in their name. From fbdb3299f5e0d80ad700b73b0bbe838b51aaf04e Mon Sep 17 00:00:00 2001 From: Lancy Date: Tue, 20 Oct 2020 09:44:37 +1300 Subject: [PATCH 47/52] feat(New Home): Updated the enum in the comment. #IOS-4145 --- bindings/ios/MEGASdk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/ios/MEGASdk.h b/bindings/ios/MEGASdk.h index f984012620..7885709f16 100644 --- a/bindings/ios/MEGASdk.h +++ b/bindings/ios/MEGASdk.h @@ -7370,7 +7370,7 @@ typedef NS_ENUM(NSInteger, AffiliateType) { * - MEGAFolderTargetTypeInShare = 0 * - MEGAFolderTargetTypeOutShare = 1 * - MEGAFolderTargetTypePublicLink = 2 - * - MEGAFolderTargetTypeRootNodes = 3 + * - MEGAFolderTargetTypeRootNode = 3 * - MEGAFolderTargetTypeAll = 4 * * @return List of nodes that contain the desired string in their name. From d311ebddded57507a10e020cdd5b34df1c81b6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Tue, 20 Oct 2020 17:04:30 +0200 Subject: [PATCH 48/52] Update version number --- include/mega/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mega/version.h b/include/mega/version.h index 2f228b69e3..438a24da98 100644 --- a/include/mega/version.h +++ b/include/mega/version.h @@ -5,5 +5,5 @@ #define MEGA_MINOR_VERSION 7 #endif #ifndef MEGA_MICRO_VERSION -#define MEGA_MICRO_VERSION 4 +#define MEGA_MICRO_VERSION 6 #endif From 3bc3ddd54b746ef7d4c9ae5418d0a1a634cc4ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Thu, 22 Oct 2020 12:01:40 +0200 Subject: [PATCH 49/52] Fix target for movements When node is moved from cloud to inshare, and the file already exists at the target inshare's folder, the `putnodes_result()` is called directly from MegaApi, but the target is wrong. This commit considers the use case. --- src/megaapi_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 1baafeedac..f341eb9ed0 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -19366,7 +19366,8 @@ void MegaApiImpl::sendPendingRequests() // continue to complete the copy-delete client->restag = request->getTag(); vector emptyVec; - putnodes_result(API_OK, NODE_HANDLE, emptyVec); + targettype_t target = client->isForeignNode(newParent->nodehandle) ? USER_HANDLE : NODE_HANDLE; + putnodes_result(API_OK, target, emptyVec); break; } From 53c41df4a6d04aafe712690f570a87bb101c8c9a Mon Sep 17 00:00:00 2001 From: matt weir Date: Fri, 23 Oct 2020 16:33:06 +1300 Subject: [PATCH 50/52] Fix Move's call to putndoes_result by avoiding it `putnodes_result()` should really only be called back from an actual putnodes. In this instance, it was trying to rejoin the sequence of commands for a move, when the move turns out to be a copy, and needs to remove the old node. But, we can have much smaller and clearer code by calling `unlink()` directly and also avoid ambiguities with `putnodes_result()`, and be disentangled from it. All `putnodes_result()` does in this case, is skip through all the tests, and ultimately execute these same two lines. ^ Kudos to Matt, who proposed this cleaner solution --- src/megaapi_impl.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index f341eb9ed0..4f7a40d96d 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -19362,13 +19362,9 @@ void MegaApiImpl::sendPendingRequests() { if (node->isvalid && ovn->isvalid && *(FileFingerprint*)node == *(FileFingerprint*)ovn) { - e = API_OK; // there is already an identical node in the target folder - // continue to complete the copy-delete - client->restag = request->getTag(); - vector emptyVec; - targettype_t target = client->isForeignNode(newParent->nodehandle) ? USER_HANDLE : NODE_HANDLE; - putnodes_result(API_OK, target, emptyVec); - break; + request->setNodeHandle(UNDEF); + e = client->unlink(node, false, request->getTag()); + break; // request finishes now if error, otherwise on unlink_result } if (!client->versions_disabled) From ae35afe800a53a82a48a2ebdc49386552b39cd79 Mon Sep 17 00:00:00 2001 From: matt weir Date: Mon, 26 Oct 2020 13:51:45 +1300 Subject: [PATCH 51/52] When the ultoken arrives, include all outstanding chunk MACs in the mac-of-macs calculation --- include/mega/transfer.h | 2 +- src/file.cpp | 2 +- src/megaclient.cpp | 10 ++++------ src/transfer.cpp | 14 ++++---------- src/transferslot.cpp | 31 ++++++++++++++++++++++++------ src/utils.cpp | 1 + tests/integration/SdkTest_test.cpp | 6 ++++++ 7 files changed, 42 insertions(+), 24 deletions(-) diff --git a/include/mega/transfer.h b/include/mega/transfer.h index 37b3524909..4c3189d07f 100644 --- a/include/mega/transfer.h +++ b/include/mega/transfer.h @@ -96,7 +96,7 @@ struct MEGA_API Transfer : public FileFingerprint handletransfer_map::iterator faputcompletion_it; // upload result - byte *ultoken; + unique_ptr ultoken; // backlink to base MegaClient* client; diff --git a/src/file.cpp b/src/file.cpp index e95ae33a2f..b8070e7e42 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -298,7 +298,7 @@ void File::completed(Transfer* t, LocalNode* l) newnode->uploadhandle = t->uploadhandle; // reference to uploaded file - memcpy(newnode->uploadtoken, t->ultoken, sizeof newnode->uploadtoken); + memcpy(newnode->uploadtoken, t->ultoken.get(), sizeof newnode->uploadtoken); // file's crypto key newnode->nodekey.assign((char*)t->filekey, FILENODEKEYLENGTH); diff --git a/src/megaclient.cpp b/src/megaclient.cpp index 8da0da1ad7..1bf637b14f 100644 --- a/src/megaclient.cpp +++ b/src/megaclient.cpp @@ -14619,7 +14619,7 @@ bool MegaClient::updateSyncRemoteLocation(const SyncConfig *config, Node *n, boo if (!config) { LOG_err << "no config upon updateSyncRemotePath"; - return API_ENOENT; + return false; } assert(syncConfigs); @@ -15002,8 +15002,7 @@ bool MegaClient::startxfer(direction_t d, File* f, DBTableTransactionCommitter& { t->chunkmacs.clear(); t->progresscompleted = 0; - delete [] t->ultoken; - t->ultoken = NULL; + t->ultoken.reset(); t->pos = 0; } } @@ -15041,8 +15040,7 @@ bool MegaClient::startxfer(direction_t d, File* f, DBTableTransactionCommitter& t->tempurls.clear(); t->chunkmacs.clear(); t->progresscompleted = 0; - delete [] t->ultoken; - t->ultoken = NULL; + t->ultoken.reset(); t->pos = 0; } } @@ -15218,7 +15216,7 @@ Node* MegaClient::nodebyfingerprint(LocalNode* localNode) std::string localName = localNode->localname.toName(*fsaccess, localNode->sync->mFilesystemType); - + // Only compare metamac if the node doesn't already exist. node_vector::const_iterator remoteNode = std::find_if(remoteNodes->begin(), diff --git a/src/transfer.cpp b/src/transfer.cpp index 8f24d4a935..4494d98a7d 100644 --- a/src/transfer.cpp +++ b/src/transfer.cpp @@ -129,11 +129,6 @@ Transfer::~Transfer() client->asyncfopens--; } - if (ultoken) - { - delete [] ultoken; - } - if (finished) { if (type == GET && !localfilename.empty()) @@ -180,7 +175,7 @@ bool Transfer::serialize(string *d) { hasUltoken = 2; d->append((const char*)&hasUltoken, sizeof(char)); - d->append((const char*)ultoken, NewNode::UPLOADTOKENLEN); + d->append((const char*)ultoken.get(), NewNode::UPLOADTOKENLEN); } else { @@ -311,8 +306,8 @@ Transfer *Transfer::unserialize(MegaClient *client, string *d, transfer_map* tra if (hasUltoken) { - t->ultoken = new byte[NewNode::UPLOADTOKENLEN](); - memcpy(t->ultoken, ptr, ll); + t->ultoken.reset(new byte[NewNode::UPLOADTOKENLEN]()); + memcpy(t->ultoken.get(), ptr, ll); ptr += ll; } @@ -500,8 +495,7 @@ void Transfer::failed(const Error& e, DBTableTransactionCommitter& committer, ds { chunkmacs.clear(); progresscompleted = 0; - delete [] ultoken; - ultoken = NULL; + ultoken.reset(); pos = 0; if (slot && slot->fa && (slot->fa->mtime != mtime || slot->fa->size != size)) diff --git a/src/transferslot.cpp b/src/transferslot.cpp index 9fc0cfefc2..64509dc37c 100644 --- a/src/transferslot.cpp +++ b/src/transferslot.cpp @@ -598,19 +598,19 @@ void TransferSlot::doio(MegaClient* client, DBTableTransactionCommitter& committ LOG_debug << "Upload token received"; if (!transfer->ultoken) { - transfer->ultoken = new byte[NewNode::UPLOADTOKENLEN](); + transfer->ultoken.reset(new byte[NewNode::UPLOADTOKENLEN]()); } bool tokenOK = true; if (reqs[i]->in.data()[NewNode::UPLOADTOKENLEN - 1] == 1) { LOG_debug << "New style upload token"; - memcpy(transfer->ultoken, reqs[i]->in.data(), NewNode::UPLOADTOKENLEN); + memcpy(transfer->ultoken.get(), reqs[i]->in.data(), NewNode::UPLOADTOKENLEN); } else { LOG_debug << "Old style upload token: " << reqs[i]->in; - tokenOK = (Base64::atob(reqs[i]->in.data(), transfer->ultoken, NewNode::UPLOADTOKENLEN) + tokenOK = (Base64::atob(reqs[i]->in.data(), transfer->ultoken.get(), NewNode::UPLOADTOKENLEN) == NewNode::OLDUPLOADTOKENLEN); } @@ -619,11 +619,27 @@ void TransferSlot::doio(MegaClient* client, DBTableTransactionCommitter& committ errorcount = 0; transfer->failcount = 0; + // any other connections that have not reported back yet, or we haven't processed yet, + // must have completed also - make sure to include their chunk MACs in the mac-of-macs + for (int j = connections; j--; ) + { + if (j != i && reqs[j] && + (reqs[j]->status == REQ_INFLIGHT + || reqs[j]->status == REQ_SUCCESS + || reqs[j]->status == REQ_FAILURE)) // could be a network error getting the result + { + LOG_debug << "Including chunk MACs from incomplete/unprocessed (at this end) connection " << j; + transfer->progresscompleted += reqs[j]->size; + transfer->chunkmacs.finishedUploadChunks(static_cast(reqs[j].get())->mChunkmacs); + } + } + transfer->chunkmacs.finishedUploadChunks(static_cast(reqs[i].get())->mChunkmacs); + transfer->progresscompleted += reqs[i]->size; + assert(transfer->progresscompleted == transfer->size); updatecontiguousprogress(); - transfer->progresscompleted += reqs[i]->size; memcpy(transfer->filekey, transfer->transferkey.data(), sizeof transfer->transferkey); ((int64_t*)transfer->filekey)[2] = transfer->ctriv; ((int64_t*)transfer->filekey)[3] = macsmac(&transfer->chunkmacs); @@ -643,8 +659,7 @@ void TransferSlot::doio(MegaClient* client, DBTableTransactionCommitter& committ } else { - delete [] transfer->ultoken; - transfer->ultoken = NULL; + transfer->ultoken.reset(); } } @@ -1059,6 +1074,10 @@ void TransferSlot::doio(MegaClient* client, DBTableTransactionCommitter& committ m_off_t pos = posrange.first; unsigned size = (unsigned)(posrange.second - pos); + // No need to keep recopying already processed macs from prior uploads on this req[i] + // For uploads, these are always on chunk boundaries so no need to worry about partials. + static_cast(reqs[i].get())->mChunkmacs.clear(); + if (fa->asyncavailable()) { if (asyncIO[i]) diff --git a/src/utils.cpp b/src/utils.cpp index 3422e8c6d2..83d1c9224c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -345,6 +345,7 @@ int64_t chunkmac_map::macsmac(SymmCipher *cipher) m[0] ^= m[1]; m[1] = m[2] ^ m[3]; + // LOG_debug << "macsmac final: " << Base64Str(mac); return MemAccess::get((const char*)mac); } diff --git a/tests/integration/SdkTest_test.cpp b/tests/integration/SdkTest_test.cpp index 76c0e5c76b..c30061974b 100644 --- a/tests/integration/SdkTest_test.cpp +++ b/tests/integration/SdkTest_test.cpp @@ -784,6 +784,8 @@ void SdkTest::createFile(string filename, bool largeFile) if (largeFile) limit = 1000000 + rand() % 1000000; + //limit = 5494065 / 5; + for (int i = 0; i < limit; i++) { fprintf(fp, "test "); @@ -4086,6 +4088,7 @@ TEST_F(SdkTest, SdkTestOverquotaNonCloudraid) LOG_info << "___TEST SdkTestOverquotaNonCloudraid"; getAccountsForTest(2); + //for (int i = 0; i < 1000; ++i) { ASSERT_TRUE(DebugTestHook::resetForTests()) << "SDK test hooks are not enabled in release mode"; // make a file to download, and upload so we can pull it down @@ -4142,6 +4145,9 @@ TEST_F(SdkTest, SdkTestOverquotaNonCloudraid) ASSERT_LT(DebugTestHook::countdownToOverquota, originalcount); // there should have been more http activity after the wait ASSERT_TRUE(DebugTestHook::resetForTests()) << "SDK test hooks are not enabled in release mode"; + + //cout << "Passed round " << i << endl; } + } #endif From 82fdcb3ee062fe6fad712e094a5d22df445d72c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Hern=C3=A1ndez?= Date: Mon, 26 Oct 2020 09:05:48 +0100 Subject: [PATCH 52/52] Fix compilation transfer tests --- tests/unit/Transfer_test.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/unit/Transfer_test.cpp b/tests/unit/Transfer_test.cpp index 5cab4b04cb..9d6207d0f7 100644 --- a/tests/unit/Transfer_test.cpp +++ b/tests/unit/Transfer_test.cpp @@ -40,7 +40,7 @@ void checkTransfers(const mega::Transfer& exp, const mega::Transfer& act) exp.transferkey.data() + mega::SymmCipher::KEYLENGTH, act.transferkey.data())); ASSERT_EQ(exp.lastaccesstime, act.lastaccesstime); - ASSERT_TRUE(std::equal(exp.ultoken, exp.ultoken + mega::NewNode::UPLOADTOKENLEN, act.ultoken)); + ASSERT_TRUE(std::equal(exp.ultoken.get(), exp.ultoken.get() + mega::NewNode::UPLOADTOKENLEN, act.ultoken.get())); ASSERT_EQ(exp.tempurls, act.tempurls); ASSERT_EQ(exp.state, act.state); ASSERT_EQ(exp.priority, act.priority); @@ -64,8 +64,8 @@ TEST(Transfer, serialize_unserialize) tf.transferkey.data() + mega::SymmCipher::KEYLENGTH, 'Y'); tf.lastaccesstime = 3; - tf.ultoken = new mega::byte[mega::NewNode::UPLOADTOKENLEN]; - std::fill(tf.ultoken, tf.ultoken + mega::NewNode::UPLOADTOKENLEN, 'Z'); + tf.ultoken.reset(new mega::byte[mega::NewNode::UPLOADTOKENLEN]); + std::fill(tf.ultoken.get(), tf.ultoken.get() + mega::NewNode::UPLOADTOKENLEN, 'Z'); tf.tempurls = { "http://bar1.com", "http://bar2.com", @@ -102,8 +102,8 @@ TEST(Transfer, unserialize_32bit) tf.transferkey.data() + mega::SymmCipher::KEYLENGTH, 'Y'); tf.lastaccesstime = 3; - tf.ultoken = new mega::byte[mega::NewNode::UPLOADTOKENLEN]; - std::fill(tf.ultoken, tf.ultoken + mega::NewNode::UPLOADTOKENLEN, 'Z'); + tf.ultoken.reset(new mega::byte[mega::NewNode::UPLOADTOKENLEN]); + std::fill(tf.ultoken.get(), tf.ultoken.get() + mega::NewNode::UPLOADTOKENLEN, 'Z'); tf.tempurls = { "http://bar1.com", "http://bar2.com",