Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sysgears.seleniumbundle.core.data.cloud

abstract class AbstractCloudService implements ICloudService {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sysgears.seleniumbundle.core.data.cloud

interface ICloudService {

void downloadFile(String remotePath, String localPath)

void downloadFiles(String remotePath, String localPath)

void uploadFile(String localPath, String remotePath)

void uploadFiles(String localPath, String remotePath)
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package com.sysgears.seleniumbundle.core.dropbox
package com.sysgears.seleniumbundle.core.data.cloud.dropbox

import com.dropbox.core.BadRequestException
import com.dropbox.core.DbxException
import com.dropbox.core.DbxRequestConfig
import com.dropbox.core.v2.DbxClientV2
import com.dropbox.core.v2.files.DeleteErrorException
import com.sysgears.seleniumbundle.core.conf.Config
import com.sysgears.seleniumbundle.core.data.cloud.AbstractCloudService
import com.sysgears.seleniumbundle.core.utils.FileHelper
import com.sysgears.seleniumbundle.core.utils.PathHelper
import groovy.util.logging.Slf4j

/**
* Client for Dropbox. Provides methods to work with Dropbox API.
*/
@Slf4j
class DropboxClient {
class DropboxCloudService extends AbstractCloudService {

/**
* Project properties.
Expand All @@ -32,75 +34,109 @@ class DropboxClient {
private final DbxClientV2 client

/**
* Creates an instance of a custom DropboxClient.
* Creates an instance of a custom DropboxCloudService.
*/
DropboxClient() {
DropboxCloudService() {
client = new DbxClientV2(config, conf.dropbox.accessToken as String)
}

/**
* Downloads a file from Dropbox.
*
* @param dropboxPath path to a file on Dropbox
* @param downloadPath path where to download the file
* @param remotePath path to a file on Dropbox
* @param localPath path to download the file to
*
* @throws IOException if any error occurs while downloading file from Dropbox
*/
void downloadFile(String dropboxPath, String downloadPath) throws IOException {
File file = new File(downloadPath)
@Override
void downloadFile(String remotePath, String localPath) throws IOException {
File file = new File(localPath)

file.getParentFile().mkdirs()
try {
client.files().download(dropboxPath).download(new FileOutputStream(file))
client.files().download(remotePath).download(new FileOutputStream(file))
} catch (BadRequestException e) {
log.error("Unable to download a file from $dropboxPath.", e)
throw new IOException("Unable to download a file from $dropboxPath, invalid request", e)
log.error("Unable to download a file from $remotePath.", e)
throw new IOException("Unable to download a file from $remotePath, invalid request", e)
} catch (IOException | DbxException e) {
log.error("Unable to download a file from $dropboxPath.", e)
throw new IOException("Unable to download a file from $dropboxPath.", e)
log.error("Unable to download a file from $remotePath.", e)
throw new IOException("Unable to download a file from $remotePath.", e)
}
}

/**
* Downloads all files stored in remote path on Dropbox.
*
* @param remotePath path to files on Dropbox
* @param localPath local path to download the files to
*/
@Override
void downloadFiles(String remotePath, String localPath) {
getDropboxPaths().each {
downloadFile(it, localPath + it - remotePath)
}
}

/**
* Uploads a file to Dropbox.
*
* @param dropboxPath path for saving a file on Dropbox
* @param uploadPath local path to a file
* @param localPath local path to a file
* @param remotePath path for saving a file on Dropbox
*
* @throws IOException if any error occurs while uploading file to Dropbox
*/
void uploadFile(String dropboxPath, String uploadPath) throws IOException {
dropboxPath = PathHelper.convertToUnixLike(dropboxPath)
log.info("uploading $dropboxPath")
@Override
void uploadFile(String localPath, String remotePath) throws IOException {
remotePath = PathHelper.convertToUnixLike(remotePath)

// delete is a workaround due to issues with "withMode(WriteMode.OVERWRITE)"
deleteFile(remotePath)

try {
client.files().uploadBuilder("$dropboxPath").uploadAndFinish(new FileInputStream(uploadPath))
client.files().uploadBuilder("/$remotePath").uploadAndFinish(new FileInputStream(localPath))
} catch (BadRequestException e) {
log.error("Unable to upload a file from $uploadPath.", e)
throw new IOException("Unable to upload a file from $uploadPath, invalid request", e)
log.error("Unable to upload a file from $localPath.", e)
throw new IOException("Unable to upload a file from $localPath, invalid request", e)
} catch (IOException | DbxException e) {
log.error("Unable to upload a file from $uploadPath.", e)
throw new IOException("Unable to upload a file from $uploadPath.", e)
log.error("Unable to upload a file from $localPath.", e)
throw new IOException("Unable to upload a file from $localPath.", e)
}
}

/**
* Uploads all files stored in local path to Dropbox.
*
* @param localPath path to local directory
* @param remotePath path for saving files on Dropbox
*/
@Override
void uploadFiles(String localPath, String remotePath) {

FileHelper.getFiles(localPath).each {
uploadFile(it.path, remotePath + it.path - localPath)
}
}

/**
* Deletes file saved in Dropbox path.
*
* @param dropboxPath path to the file to be deleted
* @param remotePath path to the file to be deleted
*
* @throws IOException if any error occurs while deleting file on Dropbox
*/
void deleteFile(String dropboxPath) throws IOException {
dropboxPath = PathHelper.convertToUnixLike(dropboxPath)
void deleteFile(String remotePath) throws IOException {
remotePath = PathHelper.convertToUnixLike(remotePath)

try {
client.files().deleteV2("$dropboxPath")
client.files().deleteV2("/$remotePath")
} catch (DeleteErrorException ignored) {
// exception is thrown if there is no file of given path
} catch (BadRequestException e) {
log.error("Unable to delete a file from $dropboxPath.", e)
throw new IOException("Unable to delete a file from $dropboxPath, invalid request", e)
log.error("Unable to delete a file from $remotePath.", e)
throw new IOException("Unable to delete a file from $remotePath, invalid request", e)
} catch (DbxException e) {
log.error("Unable to delete a file from $dropboxPath.", e)
throw new IOException("Unable to delete a file from $dropboxPath.", e)
log.error("Unable to delete a file from $remotePath.", e)
throw new IOException("Unable to delete a file from $remotePath.", e)
}
}

Expand All @@ -112,6 +148,7 @@ class DropboxClient {
* @throws IOException if any error occurs while getting Dropbox paths
*/
List<String> getDropboxPaths() throws IOException {

try {
client.files().listFolderBuilder("").withRecursive(true).start().getEntries().collect {
it.getPathLower()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.sysgears.seleniumbundle.core.uicomparison.commands

import com.sysgears.seleniumbundle.core.command.AbstractCommand
import com.sysgears.seleniumbundle.core.conf.Config
import com.sysgears.seleniumbundle.core.data.cloud.ICloudService
import com.sysgears.seleniumbundle.core.implicitinit.annotations.ImplicitInit
import com.sysgears.seleniumbundle.core.utils.ClassFinder
import org.apache.commons.io.FilenameUtils

/**
* Class which provides the method to download screenshots from Dropbox.
*/
class DownloadFromCommand extends AbstractCommand {

/**
* Name of cloud service to be used.
*/
@ImplicitInit(pattern = "googledrive|dropbox", isRequired = true)
private String service

/**
* Category of the downloaded screenshots.
*/
@ImplicitInit(pattern = "baseline|difference|actual", isRequired = true)
private List<String> categories

/**
* Instance of Cloud Client to be used by the command.
*/
private ICloudService serviceInstance

/**
* Creates an instance of DownloadFromCommand.
*
* @param arguments map that contains command arguments
* @param conf project properties
*
* @throws IllegalArgumentException is thrown in case a value is missing for a mandatory parameter or
* the value doesn't match the validation pattern
*/
DownloadFromCommand(Map<String, List<String>> arguments, Config conf) throws IllegalArgumentException {
super(arguments, conf)

serviceInstance = ClassFinder.findCloudService(service, conf)
}

/**
* Executes the command.
*/
@Override
void execute() {
categories.each { category ->
serviceInstance.downloadFiles(category, FilenameUtils.separatorsToSystem(conf.ui.path."$category"))
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.sysgears.seleniumbundle.core.uicomparison.commands

import com.sysgears.seleniumbundle.core.command.AbstractCommand
import com.sysgears.seleniumbundle.core.conf.Config
import com.sysgears.seleniumbundle.core.data.cloud.ICloudService
import com.sysgears.seleniumbundle.core.implicitinit.annotations.ImplicitInit
import com.sysgears.seleniumbundle.core.utils.ClassFinder
import org.apache.commons.io.FilenameUtils

/**
* Class which provides the method to upload screenshots to Dropbox.
*/
class UploadToCommand extends AbstractCommand {

/**
* Name of cloud service to be used.
*/
@ImplicitInit(pattern = "googledrive|dropbox", isRequired = true)
String service

/**
* Category of the uploaded screenshots.
*/
@ImplicitInit(pattern = "baseline|difference|actual", isRequired = true)
private List<String> categories

/**
* Instance of Cloud Client to be used by the command.
*/
private ICloudService serviceInstance

/**
* Creates an instance of UploadToCommand.
*
* @param @param arguments the map with arguments of the command
* @param conf project properties
*
* @throws IllegalArgumentException is thrown in case a value is missing for a mandatory parameter or
* the value doesn't match the validation pattern
*/
UploadToCommand(Map<String, List<String>> arguments, Config conf) throws IllegalArgumentException {
super(arguments, conf)

serviceInstance = ClassFinder.findCloudService(service, conf)
}

/**
* Executes the command.
*/
@Override
void execute() throws IOException {
categories.each { category ->

serviceInstance.uploadFiles(category, FilenameUtils.separatorsToSystem(conf.ui.path."$category"))
}
}
}
Loading