borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java
@@ -11,8 +11,7 @@ import de.micromata.borgbutler.json.borg.BorgFilesystemItem; import de.micromata.borgbutler.utils.DirUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +25,6 @@ import java.awt.*; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.List; @Path("/archives") @@ -60,6 +58,7 @@ * @param mode Flat (default) or tree. * @param currentDirectory The current displayed directory (only files and directories contained will be returned). * @param maxResultSize maximum number of file items to return (default is 50). * @param diffArchiveId If given, the differences between archiveId and diffArchiveId will be returned. * @param force If false (default), non cached file lists will not be loaded by borg. * @param prettyPrinter If true then the json output will be in pretty format. * @return Repository (including list of archives) as json string. @@ -70,6 +69,7 @@ @QueryParam("mode") String mode, @QueryParam("currentDirectory") String currentDirectory, @QueryParam("maxResultSize") String maxResultSize, @QueryParam("diffArchiveId") String diffArchiveId, @QueryParam("force") boolean force, @QueryParam("prettyPrinter") boolean prettyPrinter) { int maxSize = NumberUtils.toInt(maxResultSize, 50); @@ -83,6 +83,9 @@ if (items == null) { return "[{\"mode\": \"notLoaded\"}]"; } if (StringUtils.isNotBlank(diffArchiveId)) { log.info("Diff between archives not yet supported."); } return JsonUtils.toJson(items, prettyPrinter); } @@ -92,7 +95,6 @@ /** * @param archiveId * @param fileNumber The fileNumber of the file or directory in the archive served by BorgButler's * {@link #getArchiveFileLIst(String, String, String, boolean, boolean)} */ public Response restore(@QueryParam("archiveId") String archiveId, @QueryParam("fileNumber") int fileNumber) { log.info("Requesting file #" + fileNumber + " of archive '" + archiveId + "'."); @@ -137,14 +139,14 @@ } } public void openFileBrowser(File directory) { private void openFileBrowser(File directory) { if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE_FILE_DIR)) { Desktop.getDesktop().browseFileDirectory(directory); } } private Response handleRestoredFiles(BorgRepoConfig repoConfig, Archive archive) { // Todo: Handle download from single files as well as download of zip archive (if BorgButler runs remote). // Todo: Handle download of single files as well as download of zip archive (if BorgButler runs remote). return null; /* File file = path.toFile(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); borgbutler-webapp/src/components/views/archives/ArchiveView.jsx
@@ -101,6 +101,7 @@ <TabPane tabId={'1'}> <FileListPanel archiveId={archive.id} archiveShortInfoList={archive.archiveShortInfoList} /> </TabPane> <TabPane tabId={'2'}> borgbutler-webapp/src/components/views/archives/FileListFilter.jsx
@@ -1,11 +1,29 @@ import React from 'react'; import PropTypes from 'prop-types'; import {FormButton, FormInput, FormLabel, FormSelect, FormOption} from '../../general/forms/FormComponents'; import {FormButton, FormInput, FormLabel, FormOption, FormSelect} from '../../general/forms/FormComponents'; import {IconRefresh} from '../../general/IconComponents'; import I18n from '../../general/translation/I18n'; function FileListFilter({reload, changeFilter, filter}) { function FileListFilter({reload, changeFilter, filter, currentArchiveId, archiveShortInfoList}) { let archiveOptions = archiveShortInfoList .map(archive => { //if (archiveId === archive) let label = archive.time; if (archive.fileListAlreadyCached) { label = `${archive.time} ✓` } let disabled = undefined; if (archive.id === currentArchiveId) { disabled = 'true'; } return <FormOption value={archive.id} label={label} disabled={disabled} key={archive.id} /> }); return ( <form onSubmit={reload} @@ -29,20 +47,29 @@ name={'mode'} onChange={changeFilter} > <FormOption value={'tree'} /> <FormOption value={'flat'} /> <FormOption value={'tree'}/> <FormOption value={'flat'}/> </FormSelect> <FormSelect value={filter.maxSize} name={'maxSize'} onChange={changeFilter} hint={<I18n name={'common.limitsResultSize'} />} hint={<I18n name={'common.limitsResultSize'}/>} > <FormOption value={'50'} /> <FormOption value={'100'} /> <FormOption value={'500'} /> <FormOption value={'1000'} /> <FormOption value={'10000'} /> <FormOption value={'50'}/> <FormOption value={'100'}/> <FormOption value={'500'}/> <FormOption value={'1000'}/> <FormOption value={'10000'}/> </FormSelect> <FormSelect value={filter.diffArchive} name={'diffArchive'} onChange={changeFilter} hint={'Show differences between current archive and this selected archive.'} > <FormOption value={''} label={'Select diff archive'}/> {archiveOptions} </FormSelect> <FormButton type={'submit'} bsStyle={'primary'}> <IconRefresh/> @@ -57,7 +84,9 @@ search: PropTypes.string, maxSize: PropTypes.oneOf(['50', '100', '500', '1000', '10000']), }).isRequired, reload: PropTypes.func.isRequired reload: PropTypes.func.isRequired, currentArchiveId: PropTypes.string, archiveShortInfoList: PropTypes.array }; export default FileListFilter; borgbutler-webapp/src/components/views/archives/FileListPanel.jsx
@@ -5,7 +5,7 @@ import FileListTable from "./FileListTable"; import FileListFilter from "./FileListFilter"; class ArchiveView extends React.Component { class FileListPanel extends React.Component { state = { isFetching: false, activeTab: '1', @@ -14,7 +14,8 @@ search: '', mode: 'tree', currentDirectory: '', maxSize: '50' maxSize: '50', diffArchive: '' } }; @@ -55,7 +56,8 @@ searchString: this.state.filter.search, mode: this.state.filter.mode, currentDirectory: this.state.filter.currentDirectory, maxResultSize: this.state.filter.maxSize maxResultSize: this.state.filter.maxSize, diffArchive: this.state.filter.diffArchive }), { method: 'GET', headers: { @@ -126,6 +128,8 @@ event.preventDefault(); this.fetchArchiveFileList(); }} currentArchiveId={this.props.archiveId} archiveShortInfoList={this.props.archiveShortInfoList} /> {breadcrumb} <FileListTable @@ -149,4 +153,4 @@ } } export default ArchiveView; export default FileListPanel;