1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
|
#ifndef CLSFTPMANAGER_HPP
#define CLSFTPMANAGER_HPP
#if USE_SFTP
#include "cl_command_event.h"
#include "cl_sftp.h"
#include "codelite_exports.h"
#include "sync_queue.h"
#include <atomic>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <wx/event.h>
#include <wx/msgqueue.h>
#include <wx/string.h>
#include <wx/thread.h>
#include <wx/timer.h>
class IEditor;
class SFTPClientData;
class WXDLLIMPEXP_SDK clSFTPManager : public wxEvtHandler
{
protected:
struct saved_file {
wxString local_path;
wxString remote_path;
wxString account_name;
};
protected:
std::unordered_map<wxString, std::pair<SSHAccountInfo, clSFTP::Ptr_t>> m_connections;
wxTimer* m_timer = nullptr;
bool m_eventsConnected = true;
std::thread* m_worker_thread = nullptr;
SyncQueue<std::function<void()>> m_q;
std::atomic_bool m_shutdown;
wxString m_lastError;
std::unordered_map<wxString, saved_file> m_downloadedFileToAccount;
protected:
std::pair<SSHAccountInfo, clSFTP::Ptr_t> GetConnectionPair(const wxString& account) const;
clSFTP::Ptr_t GetConnectionPtr(const wxString& account) const;
size_t GetAllConnectionsPtr(std::vector<clSFTP::Ptr_t>& connections) const;
clSFTP::Ptr_t GetConnectionPtrAddIfMissing(const wxString& account);
protected:
void OnGoingDown(clCommandEvent& event);
void OnFileSaved(clCommandEvent& event);
SFTPClientData* GetSFTPClientData(IEditor* editor);
void OnTimer(wxTimerEvent& event);
bool DoSyncDownload(const wxString& remotePath, const wxString& localPath, const wxString& accountName);
/**
* @brief read file from the remote target. Once the file is read, an event is fired
*/
void DoAsyncReadFile(const wxString& remotePath, const wxString& accountName, wxEvtHandler* sink);
bool DoSyncReadFile(const wxString& remotePath, const wxString& accountName, wxMemoryBuffer* content);
void StartWorkerThread();
void StopWorkerThread();
void OnSaveCompleted(clCommandEvent& e);
void OnSaveError(clCommandEvent& e);
void DoAsyncSaveFile(const wxString& localPath, const wxString& remotePath, const wxString& accountName,
bool delete_local, wxEvtHandler* sink);
bool DoSyncSaveFile(const wxString& localPath, const wxString& remotePath, const wxString& accountName,
bool delete_local);
public:
clSFTPManager();
virtual ~clSFTPManager();
static clSFTPManager& Get();
void Release();
/**
* @brief return true if this file was downloaded via the sftp manager
* @param filepath path the local file
* @param account [output] the account this file belongs to
* @param remote_path [output] the file's remote path
* @return true if filepath was downloaded via the sftp manager
*/
bool IsRemoteFile(const wxString& filepath, wxString* account, wxString* remote_path) const;
/**
* @brief add new connection to the manager. if a connection for this account already exists and 'replace' is set to
* true, replace it
*/
bool AddConnection(const SSHAccountInfo& account, bool replace = false);
/**
* @brief open remote file in an editor and return a pointer to the editor
* @param path file path on the remote machine
* @param accountName the account name to use
*/
IEditor* OpenFile(const wxString& path, const wxString& accountName);
IEditor* OpenFile(const wxString& path, const SSHAccountInfo& accountInfo);
/**
* @brief download file, but do not open it in a an editor. Optionally, allow the user set the local file name
* @return return the *local* file path
*/
wxFileName Download(const wxString& path, const wxString& accountName,
const wxString& localFileName = wxEmptyString);
/**
* @brief save file remotely. this function is async
* @param localPath file on the local machine
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @param sink callback object for save file events
*/
void AsyncSaveFile(const wxString& localPath, const wxString& remotePath, const wxString& accountName,
wxEvtHandler* sink = nullptr);
/**
* @brief write file content. this function is async
* @param content of the file
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @param sink callback object for save file events.
* @event wxEVT_SFTP_FILE_READ event
*/
void AsyncWriteFile(const wxString& content, const wxString& remotePath, const wxString& accountName,
wxEvtHandler* sink = nullptr);
/**
* @brief read file content. this function is async
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @param sink callback object for completion
*/
void AsyncReadFile(const wxString& remotePath, const wxString& accountName, wxEvtHandler* sink);
/**
* @brief read file content. this function is async
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @param sink callback object for completion
*/
bool AwaitReadFile(const wxString& remotePath, const wxString& accountName, wxMemoryBuffer* content);
/**
* @brief save file remotely. this function is sync
* @param localPath file on the local machine
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @param sink callback object for save file events
* @return true on success or false
*/
bool AwaitSaveFile(const wxString& localPath, const wxString& remotePath, const wxString& accountName);
/**
* @brief write file content. this function is sync
* @param content of the file
* @param remotePath file path on the remote machine
* @param accountName the account name to use
* @return true on success or false
*/
bool AwaitWriteFile(const wxString& content, const wxString& remotePath, const wxString& accountName);
/**
* @brief delete a connection
* if promptUser is set to true and any un-saved files belonged to the connection
* are opened, the user is prompted to save them
*/
bool DeleteConnection(const wxString& accountName, bool promptUser = false);
/**
* @brief list entries in a given folder for a given account
* @param path
* @return
*/
SFTPAttribute::List_t List(const wxString& path, const SSHAccountInfo& accountInfo);
/**
* @brief create new file with a given path
*/
bool NewFile(const wxString& path, const SSHAccountInfo& accountInfo);
/**
* @brief create a new folder with a given path
*/
bool NewFolder(const wxString& path, const SSHAccountInfo& accountInfo);
/**
* @brief rename a file/directory
* @param oldpath
* @param newpath
*/
bool Rename(const wxString& oldpath, const wxString& newpath, const SSHAccountInfo& accountInfo);
/**
* @brief delere a directory
*/
bool DeleteDir(const wxString& fullpath, const SSHAccountInfo& accountInfo);
/**
* @brief unlink a file
*/
bool UnlinkFile(const wxString& fullpath, const SSHAccountInfo& accountInfo);
/**
* @brief check if a file with a given path exists
*/
bool IsFileExists(const wxString& fullpath, const SSHAccountInfo& accountInfo);
/**
* @brief check if a directory with a given path exists
*/
bool IsDirExists(const wxString& fullpath, const SSHAccountInfo& accountInfo);
/**
* @brief return the remote path for a local file
*/
bool GetRemotePath(const wxString& local_path, const wxString& accountName, wxString& remote_path);
/**
* @brief return the local path for a remote path
*/
bool GetLocalPath(const wxString& remote_path, const wxString& accountName, wxString& local_path);
/**
* @brief return the last error occurred
*/
const wxString& GetLastError() const { return m_lastError; }
/**
* @brief clear last error captured
*/
void ClearLastError() { m_lastError.clear(); }
};
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_SDK, wxEVT_SFTP_ASYNC_SAVE_COMPLETED, clCommandEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_SDK, wxEVT_SFTP_ASYNC_SAVE_ERROR, clCommandEvent);
#endif
#endif // CLSFTPMANAGER_HPP
|