예제 #1
0
wxTreeListItem SFTPTreeView::DoAddFolder(const wxTreeListItem& parent, const wxString& path)
{
    try {
        m_sftp->CreateDir(path);
        SFTPAttribute::Ptr_t attr = m_sftp->Stat(path);
        // Update the UI
        MyClientData* newCd = new MyClientData(path);
        newCd->SetIsFolder(true);
        newCd->SetInitialized(false);

        wxTreeListItem child = m_treeListCtrl->AppendItem(
            parent, newCd->GetFullName(), m_bmpLoader.GetMimeImageId(FileExtManager::TypeFolder), wxNOT_FOUND, newCd);

        if(IsTypeColumnShown()) {
            m_treeListCtrl->SetItemText(child, GetTypeColumnIndex(), attr->GetTypeAsString());
        }
        if(IsSizeColumnShown()) {
            m_treeListCtrl->SetItemText(child, GetSizeColumnIndex(), wxString() << attr->GetSize());
        }
        m_treeListCtrl->AppendItem(child, "<dummy>");
        m_treeListCtrl->SetSortColumn(0);
        return child;

    } catch(clException& e) {
        ::wxMessageBox(e.What(), "SFTP", wxICON_ERROR | wxOK | wxCENTER);
    }
    return wxTreeListItem();
}
예제 #2
0
wxTreeListItem SFTPTreeView::DoAddFile(const wxTreeListItem& parent, const wxString& path)
{
    try {
        m_sftp->Write("", path);
        SFTPAttribute::Ptr_t attr = m_sftp->Stat(path);
        // Update the UI
        MyClientData* newFile = new MyClientData(path);
        newFile->SetIsFolder(false);
        newFile->SetInitialized(false);

        wxTreeListItem child = m_treeListCtrl->AppendItem(
            parent,
            newFile->GetFullName(),
            m_bmpLoader.GetMimeImageId(FileExtManager::GetType(path, FileExtManager::TypeText)),
            wxNOT_FOUND,
            newFile);

        m_treeListCtrl->SetItemText(child, 1, attr->GetTypeAsString());
        m_treeListCtrl->SetItemText(child, 2, wxString() << attr->GetSize());
        m_treeListCtrl->SetSortColumn(0);
        return child;

    } catch(clException& e) {
        ::wxMessageBox(e.What(), "SFTP", wxICON_ERROR | wxOK | wxCENTER);
    }
    return wxTreeListItem();
}
예제 #3
0
bool SFTPTreeView::DoExpandItem(const wxTreeItemId& item)
{
    MyClientData* cd = GetItemData(item);
    CHECK_PTR_RET_FALSE(cd);

    // already initialized this folder before?
    if(cd->IsInitialized()) { return true; }

    // get list of files and populate the tree
    SFTPAttribute::List_t attributes;
    try {
        attributes = m_sftp->List(cd->GetFullPath(), clSFTP::SFTP_BROWSE_FILES | clSFTP::SFTP_BROWSE_FOLDERS);

    } catch(clException& e) {
        ::wxMessageBox(e.What(), "SFTP", wxOK | wxICON_ERROR | wxCENTER, EventNotifier::Get()->TopFrame());
        return false;
    }

    // Remove the dummy item and replace it with real items
    wxTreeItemIdValue cookie;
    wxTreeItemId dummyItem = m_treeCtrl->GetFirstChild(item, cookie);
    m_treeCtrl->Delete(dummyItem);
    cd->SetInitialized(true);

    int nNumOfRealChildren = 0;
    SFTPAttribute::List_t::iterator iter = attributes.begin();
    for(; iter != attributes.end(); ++iter) {
        SFTPAttribute::Ptr_t attr = (*iter);
        if(attr->GetName() == "." || attr->GetName() == "..") continue;

        ++nNumOfRealChildren;
        // determine the icon index
        int imgIdx = wxNOT_FOUND;
        if(attr->IsFolder()) {
            imgIdx = m_bmpLoader->GetMimeImageId(FileExtManager::TypeFolder);

        } else {
            imgIdx = m_bmpLoader->GetMimeImageId(attr->GetName());
        }

        if(imgIdx == wxNOT_FOUND) { imgIdx = m_bmpLoader->GetMimeImageId(FileExtManager::TypeText); }

        wxString path;
        path << cd->GetFullPath() << "/" << attr->GetName();
        while(path.Replace("//", "/")) {}

        MyClientData* childClientData = new MyClientData(path);
        childClientData->SetIsFolder(attr->IsFolder());

        wxTreeItemId child = m_treeCtrl->AppendItem(item, attr->GetName(), imgIdx, imgIdx, childClientData);
        // if its type folder, add a fake child item
        if(attr->IsFolder()) { m_treeCtrl->AppendItem(child, "<dummy>"); }
    }

    return nNumOfRealChildren > 0;
}
예제 #4
0
void clSFTP::Read(const wxString& remotePath, wxMemoryBuffer& buffer) throw(clException)
{
    if(!m_sftp) {
        throw clException("SFTP is not initialized");
    }

    sftp_file file = sftp_open(m_sftp, remotePath.mb_str(wxConvUTF8).data(), O_RDONLY, 0);
    if(file == NULL) {
        throw clException(wxString() << _("Failed to open remote file: ") << remotePath << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }

    SFTPAttribute::Ptr_t fileAttr = Stat(remotePath);
    if(!fileAttr) {
        throw clException(wxString() << _("Could not stat file:") << remotePath << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }
    wxInt64 fileSize = fileAttr->GetSize();
    if(fileSize == 0) return;

    // Allocate buffer for the file content
    char pBuffer[65536]; // buffer

    // Read the entire file content
    wxInt64 bytesLeft = fileSize;
    wxInt64 bytesRead = 0;
    while(bytesLeft > 0) {
        wxInt64 nbytes = sftp_read(file, pBuffer, sizeof(pBuffer));
        bytesRead += nbytes;
        bytesLeft -= nbytes;
        buffer.AppendData(pBuffer, nbytes);
    }

    if(bytesRead != fileSize) {
        sftp_close(file);
        buffer.Clear();
        throw clException(wxString() << _("Could not read file:") << remotePath << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }
    sftp_close(file);
}
bool SFTPAttribute::Compare(SFTPAttribute::Ptr_t one, SFTPAttribute::Ptr_t two)
{
    if ( one->IsFolder() && !two->IsFolder() ) {
        return true;

    } else if ( !one->IsFolder() && two->IsFolder() ) {
        return false;

    } else {
        return one->GetName() < two->GetName();
    }
}
void SFTPWorkerThread::ProcessRequest(ThreadRequest* request)
{
    SFTPThreadRequet* req = dynamic_cast<SFTPThreadRequet*>(request);
    // Check if we need to open an ssh connection
    wxString currentAccout = m_sftp ? m_sftp->GetAccount() : "";
    wxString requestAccount = req->GetAccount().GetAccountName();

    if(currentAccout.IsEmpty() || currentAccout != requestAccount) {
        m_sftp.reset(NULL);
        DoConnect(req);
    }

    if(req->GetDirection() == SFTPThreadRequet::kConnect) {
        // Nothing more to be done here
        // Disconnect
        m_sftp.reset(NULL);
        return;
    }

    wxString msg;
    wxString accountName = req->GetAccount().GetAccountName();
    if(m_sftp && m_sftp->IsConnected()) {

        try {

            msg.Clear();
            if(req->GetDirection() == SFTPThreadRequet::kUpload) {
                DoReportStatusBarMessage(wxString() << _("Uploading file: ") << req->GetRemoteFile());
                SFTPAttribute::Ptr_t attr(new SFTPAttribute(NULL));
                attr->SetPermissions(req->GetPermissions());
                m_sftp->CreateRemoteFile(req->GetRemoteFile(), wxFileName(req->GetLocalFile()), attr);
                msg << "Successfully uploaded file: " << req->GetLocalFile() << " -> " << req->GetRemoteFile();
                DoReportMessage(accountName, msg, SFTPThreadMessage::STATUS_OK);
                DoReportStatusBarMessage("");

            } else if(req->GetDirection() == SFTPThreadRequet::kDownload ||
                      req->GetDirection() == SFTPThreadRequet::kDownloadAndOpenContainingFolder ||
                      req->GetDirection() == SFTPThreadRequet::kDownloadAndOpenWithDefaultApp) {
                DoReportStatusBarMessage(wxString() << _("Downloading file: ") << req->GetRemoteFile());
                wxMemoryBuffer buffer;
                SFTPAttribute::Ptr_t fileAttr = m_sftp->Read(req->GetRemoteFile(), buffer);
                wxFFile fp(req->GetLocalFile(), "w+b");
                if(fp.IsOpened()) {
                    fp.Write(buffer.GetData(), buffer.GetDataLen());
                    fp.Close();
                }

                msg << "Successfully downloaded file: " << req->GetLocalFile() << " <- " << req->GetRemoteFile();
                DoReportMessage(accountName, msg, SFTPThreadMessage::STATUS_OK);
                DoReportStatusBarMessage("");

                // We should also notify the parent window about download completed
                if(req->GetDirection() == SFTPThreadRequet::kDownload) {
                    SFTPClientData cd;
                    cd.SetLocalPath(req->GetLocalFile());
                    cd.SetRemotePath(req->GetRemoteFile());
                    cd.SetPermissions(fileAttr ? fileAttr->GetPermissions() : 0);
                    m_plugin->CallAfter(&SFTP::FileDownloadedSuccessfully, cd);

                } else if(req->GetDirection() == SFTPThreadRequet::kDownloadAndOpenContainingFolder) {
                    m_plugin->CallAfter(&SFTP::OpenContainingFolder, req->GetLocalFile());

                } else {
                    m_plugin->CallAfter(&SFTP::OpenWithDefaultApp, req->GetLocalFile());
                }
            }

        } catch(clException& e) {

            msg.Clear();
            msg << "SFTP error: " << e.What();
            DoReportMessage(accountName, msg, SFTPThreadMessage::STATUS_ERROR);
            DoReportStatusBarMessage(msg);
            m_sftp.reset(NULL);

            // Requeue our request
            if(req->GetRetryCounter() == 0) {
                msg.Clear();
                msg << "Retrying to upload file: " << req->GetRemoteFile();
                DoReportMessage(req->GetAccount().GetAccountName(), msg, SFTPThreadMessage::STATUS_NONE);

                // first time trying this request, requeue it
                SFTPThreadRequet* retryReq = static_cast<SFTPThreadRequet*>(req->Clone());
                retryReq->SetRetryCounter(1);
                Add(retryReq);
            }
        }
    }
}