001/* 002 * Syncany, www.syncany.org 003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package org.syncany.cli; 019 020import static java.util.Arrays.asList; 021 022import java.util.ArrayList; 023import java.util.Collections; 024import java.util.List; 025 026import joptsimple.OptionParser; 027import joptsimple.OptionSet; 028import joptsimple.OptionSpec; 029 030import org.syncany.operations.ChangeSet; 031import org.syncany.operations.OperationResult; 032import org.syncany.operations.daemon.messages.DownDownloadFileSyncExternalEvent; 033import org.syncany.operations.daemon.messages.LsRemoteStartSyncExternalEvent; 034import org.syncany.operations.down.DownOperation; 035import org.syncany.operations.down.DownOperationOptions; 036import org.syncany.operations.down.DownOperationOptions.DownConflictStrategy; 037import org.syncany.operations.down.DownOperationResult; 038import org.syncany.operations.down.DownOperationResult.DownResultCode; 039 040import com.google.common.eventbus.Subscribe; 041 042public class DownCommand extends Command { 043 @Override 044 public CommandScope getRequiredCommandScope() { 045 return CommandScope.INITIALIZED_LOCALDIR; 046 } 047 048 @Override 049 public boolean canExecuteInDaemonScope() { 050 return false; 051 } 052 053 @Override 054 public int execute(String[] operationArgs) throws Exception { 055 DownOperationOptions operationOptions = parseOptions(operationArgs); 056 DownOperationResult operationResult = new DownOperation(config, operationOptions).execute(); 057 058 printResults(operationResult); 059 060 return 0; 061 } 062 063 public DownOperationOptions parseOptions(String[] operationArguments) { 064 DownOperationOptions operationOptions = new DownOperationOptions(); 065 066 OptionParser parser = new OptionParser(); 067 parser.allowsUnrecognizedOptions(); 068 069 OptionSpec<String> optionConflictStrategy = parser.acceptsAll(asList("C", "conflict-strategy")).withRequiredArg(); 070 OptionSpec<Void> optionNoApply = parser.acceptsAll(asList("A", "no-apply")); 071 072 OptionSet options = parser.parse(operationArguments); 073 074 // --conflict-strategy=<strategy> 075 if (options.has(optionConflictStrategy)) { 076 String conflictStrategyStr = options.valueOf(optionConflictStrategy).toUpperCase(); 077 operationOptions.setConflictStrategy(DownConflictStrategy.valueOf(conflictStrategyStr)); 078 } 079 080 // --no-apply 081 if (options.has(optionNoApply)) { 082 operationOptions.setApplyChanges(false); 083 } 084 085 return operationOptions; 086 } 087 088 @Override 089 public void printResults(OperationResult operationResult) { 090 DownOperationResult concreteOperationResult = (DownOperationResult) operationResult; 091 092 if (concreteOperationResult.getResultCode() == DownResultCode.OK_WITH_REMOTE_CHANGES) { 093 ChangeSet changeSet = concreteOperationResult.getChangeSet(); 094 095 if (changeSet.hasChanges()) { 096 List<String> newFiles = new ArrayList<String>(changeSet.getNewFiles()); 097 List<String> changedFiles = new ArrayList<String>(changeSet.getChangedFiles()); 098 List<String> deletedFiles = new ArrayList<String>(changeSet.getDeletedFiles()); 099 100 Collections.sort(newFiles); 101 Collections.sort(changedFiles); 102 Collections.sort(deletedFiles); 103 104 for (String newFile : newFiles) { 105 out.println("A "+newFile); 106 } 107 108 for (String changedFile : changedFiles) { 109 out.println("M "+changedFile); 110 } 111 112 for (String deletedFile : deletedFiles) { 113 out.println("D "+deletedFile); 114 } 115 } 116 else { 117 out.println(concreteOperationResult.getDownloadedUnknownDatabases().size() + " database file(s) processed."); 118 } 119 120 out.println("Sync down finished."); 121 } 122 else { 123 out.println("Sync down skipped, no remote changes."); 124 } 125 } 126 127 @Subscribe 128 public void onLsRemoteStartEventReceived(LsRemoteStartSyncExternalEvent syncEvent) { 129 out.printr("Checking remote changes ..."); 130 } 131 132 @Subscribe 133 public void onSyncEventReceived(DownDownloadFileSyncExternalEvent syncEvent) { 134 String fileDescription = syncEvent.getFileDescription(); 135 int currentFileIndex = syncEvent.getCurrentFileIndex(); 136 int maxFileCount = syncEvent.getMaxFileCount(); 137 138 out.printr("Downloading " + fileDescription + " "+ currentFileIndex + "/" + maxFileCount + " ..."); 139 } 140}