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.regex.Matcher; 023import java.util.regex.Pattern; 024 025import joptsimple.OptionParser; 026import joptsimple.OptionSet; 027import joptsimple.OptionSpec; 028 029import org.syncany.operations.OperationResult; 030import org.syncany.operations.watch.WatchOperation; 031import org.syncany.operations.watch.WatchOperationOptions; 032 033public class WatchCommand extends Command { 034 public static final Pattern ANNOUNCEMENTS_PATTERN = Pattern.compile("([^:]+):(\\d+)"); 035 public static final int ANNOUNCEMENTS_PATTERN_GROUP_HOST = 1; 036 public static final int ANNOUNCEMENTS_PATTERN_GROUP_PORT = 2; 037 038 @Override 039 public CommandScope getRequiredCommandScope() { 040 return CommandScope.INITIALIZED_LOCALDIR; 041 } 042 043 @Override 044 public boolean canExecuteInDaemonScope() { 045 return false; 046 } 047 048 @Override 049 public int execute(String[] operationArgs) throws Exception { 050 WatchOperationOptions operationOptions = parseOptions(operationArgs); 051 new WatchOperation(config, operationOptions).execute(); 052 053 return 0; 054 } 055 056 @Override 057 public WatchOperationOptions parseOptions(String[] operationArgs) throws Exception { 058 WatchOperationOptions operationOptions = new WatchOperationOptions(); 059 060 OptionParser parser = new OptionParser(); 061 OptionSpec<Integer> optionInterval = parser.acceptsAll(asList("i", "interval")).withRequiredArg().ofType(Integer.class); 062 OptionSpec<Void> optionNoAnnouncements = parser.acceptsAll(asList("N", "no-announcements")); 063 OptionSpec<String> optionAnnouncements = parser.acceptsAll(asList("a", "announce")).withRequiredArg(); 064 OptionSpec<Void> optionNoWatcher = parser.acceptsAll(asList("W", "no-watcher")); 065 OptionSpec<Integer> optionSettleDelay = parser.acceptsAll(asList("s", "delay")).withRequiredArg().ofType(Integer.class); 066 067 OptionSet options = parser.parse(operationArgs); 068 069 // --interval 070 if (options.has(optionInterval)) { 071 operationOptions.setInterval(options.valueOf(optionInterval)*1000); 072 } 073 074 // Conflicting options: --no-announcements and --announce=<..> 075 if (options.has(optionNoAnnouncements) && options.has(optionAnnouncements)) { 076 throw new Exception("Options --no-announcements and --announce in conflict with one another."); 077 } 078 079 // --no-announcements 080 if (options.has(optionNoAnnouncements)) { 081 operationOptions.setAnnouncements(false); 082 } 083 084 // --announce=<host>:<port> 085 if (options.has(optionAnnouncements)) { 086 operationOptions.setAnnouncements(true); 087 088 String announcementsStr = options.valueOf(optionAnnouncements); 089 Matcher matcher = ANNOUNCEMENTS_PATTERN.matcher(announcementsStr); 090 091 if (!matcher.matches()) { 092 throw new Exception("Invalid argument for --announcements, expected pattern: "+ANNOUNCEMENTS_PATTERN.pattern()); 093 } 094 095 String announcementsHost = matcher.group(ANNOUNCEMENTS_PATTERN_GROUP_HOST); 096 int announcementsPort = Integer.parseInt(matcher.group(ANNOUNCEMENTS_PATTERN_GROUP_PORT)); 097 098 operationOptions.setAnnouncementsHost(announcementsHost); 099 operationOptions.setAnnouncementsPort(announcementsPort); 100 } 101 102 // --delay=<sec> 103 if (options.has(optionSettleDelay)) { 104 operationOptions.setSettleDelay(options.valueOf(optionSettleDelay)*1000); 105 } 106 107 // --no-watcher 108 if (options.has(optionNoWatcher)) { 109 operationOptions.setWatcher(false); 110 } 111 112 return operationOptions; 113 } 114 115 @Override 116 public void printResults(OperationResult result) { 117 // Nothing. 118 } 119}