Skip to content
This repository has been archived by the owner on Jul 26, 2022. It is now read-only.

Commit

Permalink
Unity tray (appindicator) with Python script via WebSocket connection
Browse files Browse the repository at this point in the history
  • Loading branch information
binwiederhier committed Jan 1, 2014
1 parent 6ad7f9c commit d772bda
Show file tree
Hide file tree
Showing 11 changed files with 440 additions and 247 deletions.
3 changes: 2 additions & 1 deletion syncany-daemon/src/main/java/org/syncany/daemon/Daemon.java
Expand Up @@ -113,7 +113,8 @@ public static Daemon getInstance() {
return instance;
}

@Subscribe public void update(WatchEvent event){
@Subscribe
public void update(WatchEvent event){
Map<String, Command> map = getCommands();

String id = event.getId();
Expand Down
Expand Up @@ -15,12 +15,12 @@


public class DaemonCommandHandler {
private static Logger log = Logger.getLogger(DaemonCommandHandler.class.getSimpleName());
private static Logger logger = Logger.getLogger(DaemonCommandHandler.class.getSimpleName());

private static String handleStopWatch(Map<String, Object> parameters) {
Map<String, Command> commands = Daemon.getInstance().getCommands();
String id = (String)parameters.get("id");
log.log(Level.INFO, "Stop watching folder with id {1}", new Object[]{id});
logger.log(Level.INFO, "Stop watching folder with id {1}", new Object[]{id});
Command cl = commands.get(id);
if (cl instanceof WatchCommand){
WatchCommand wc = (WatchCommand)cl;
Expand All @@ -32,7 +32,7 @@ private static String handleStopWatch(Map<String, Object> parameters) {
private static String handleWatch(Map<String, Object> parameters) {
Map<String, Command> commands = Daemon.getInstance().getCommands();
String localDir = (String)parameters.get("localfolder");
log.log(Level.INFO, "Watching folder {0}", localDir);
logger.log(Level.INFO, "Watching folder {0}", localDir);

WatchCommand wc = new WatchCommand(localDir, 3);
commands.put(wc.getId(), wc);
Expand Down Expand Up @@ -100,11 +100,7 @@ private static void handleGetWatchedFolders() {

public static void handle(String message) {
Map<String, Object> params = JsonHelper.fromStringToMap(message);
handle(params);
}

public static void handle(Map<String, Object> params) {
String action = ((String)params.get("action")).toLowerCase();
String action = ((String) params.get("action")).toLowerCase();

switch (action){
case "get_watched":
Expand All @@ -125,6 +121,10 @@ public static void handle(Map<String, Object> params) {
case "quit":
handleQuit(params);
break;
default:
logger.log(Level.WARNING, "Unknown action received; returning message: "+action);
WSServer.sendToAll(message);
break;
}
}
}
Expand Up @@ -45,8 +45,8 @@ public void onOpen(WebSocket conn, ClientHandshake handshake) {

@Override
public void onMessage(WebSocket conn, String message) {
log.fine("Received from "+conn.getRemoteSocketAddress().toString() + ": " + message);
DaemonCommandHandler.handle(message);
log.fine(conn.getRemoteSocketAddress().toString() + ": " + message);
}

@Override
Expand Down
15 changes: 13 additions & 2 deletions syncany-gui/src/main/java/org/syncany/gui/Launcher.java
Expand Up @@ -26,6 +26,7 @@
import org.syncany.gui.config.ApplicationConfiguration;
import org.syncany.gui.config.ApplicationConfigurationTO;
import org.syncany.gui.config.ProxyController;
import org.syncany.gui.messaging.WSClient;
import org.syncany.util.I18n;

import com.google.common.eventbus.EventBus;
Expand All @@ -51,14 +52,24 @@ public static EventBus getEventBus() {

public static void main(String[] args) {
startDaemon();
startGUI();
startWebSocketClient();
startGUI();
}

private static void startDaemon(){
daemon = new Daemon();
daemon.start(true);
}

private static void startWebSocketClient() {
try {
new WSClient().startWebSocketConnection();
}
catch (Exception e) {
throw new RuntimeException("Cannot start websocket client.", e);
}
}

private static void startGUI(){
Display.setAppName("Syncany");
applicationConfiguration = null;
Expand Down
182 changes: 20 additions & 162 deletions syncany-gui/src/main/java/org/syncany/gui/MainGUI.java
@@ -1,32 +1,16 @@
package org.syncany.gui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Logger;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
import org.syncany.gui.messaging.ClientCommandFactory;
import org.syncany.gui.messaging.InterfaceUpdate;
import org.syncany.gui.settings.SettingsDialog;
import org.syncany.gui.wizard.WizardDialog;
import org.syncany.util.EnvironmentUtil;
import org.syncany.gui.tray.TrayIcon;
import org.syncany.gui.tray.TrayIconFactory;

import com.google.common.eventbus.Subscribe;

Expand All @@ -37,161 +21,35 @@ public class MainGUI {
private Display display = Display.getDefault();
private Shell shell;

private Menu menu;
private List<MenuItem> items = new ArrayList<>();
private TrayIcon tray;

private TrayItem item;

public void open() {
shell = new Shell();
installSystemTray();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private boolean isUnity() {
if (!EnvironmentUtil.isLinux()) {
return false;
}
else {
ProcessBuilder processBuilder = new ProcessBuilder("/bin/ps", "--no-headers", "-C", "unity-panel-service");

try {
Process process = processBuilder.start();

BufferedReader processReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

boolean isUnity = processReader.readLine() != null;

process.destroy();
processReader.close();

return isUnity;
}
catch (IOException e) {
throw new RuntimeException("Unable to determine Linux desktop environment.", e);
}
}
}

private void updateTray(Map<String, Map<String, String>> folders) {
for (MenuItem mi : items) {
mi.dispose();
}

items.clear();

for (String key : folders.keySet()) {
MenuItem mi = new MenuItem(menu, SWT.PUSH);
mi.setText(folders.get(key).get("folder") + " [" + folders.get(key).get("status") + "]");
items.add(mi);
}
}
shell = new Shell();
tray = new TrayIconFactory(shell).createTrayIcon();

private void installSystemTray() {
if (isUnity()) {
installUnitySystemTray();
}
else {
installDefaultSystemTray();
}
}

private void installUnitySystemTray() {
new Thread(new Runnable() {
// Temporary
final TrayIcon finalTray = tray;
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
ProcessBuilder processBuilder = new ProcessBuilder("src/main/python/unitytray.py", "src/main/resources/images", "All folders in sync");
processBuilder.start();
}
catch (IOException e) {
throw new RuntimeException("Unable to determine Linux desktop environment.", e);
}
}
}).start();
}

private void installDefaultSystemTray() {
Tray tray = Display.getDefault().getSystemTray();

if (tray != null) {
item = new TrayItem(tray, SWT.NONE);

if (EnvironmentUtil.isUnixLikeOperatingSystem()) {
Image image = SWTResourceManager.getImage("/images/tray/tray.png");
item.setImage(image);
public void run() {
finalTray.updateStatusText(""+new Date());
}
else {
Image image = SWTResourceManager.getResizedImage("/images/tray/tray.png", 16, 16);
item.setImage(image);
}

menu = new Menu(shell, SWT.POP_UP);

MenuItem connectItem = new MenuItem(menu, SWT.PUSH);
connectItem.setText("New connection");
connectItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
WizardDialog wd = new WizardDialog(shell, SWT.APPLICATION_MODAL);
wd.open();
}
});

MenuItem settingsItem = new MenuItem(menu, SWT.PUSH);
settingsItem.setText("Settings");
settingsItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SettingsDialog wd = new SettingsDialog(shell, SWT.APPLICATION_MODAL);
wd.open();
}
});

MenuItem quitMenu = new MenuItem(menu, SWT.PUSH);
quitMenu.setText("Exit");
quitMenu.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
shell.dispose();
display.dispose();

ClientCommandFactory.closeWebSocketClient();
Launcher.daemon.shutdown();
}
});

Listener showMenuListener = new Listener() {
public void handleEvent(Event event) {
menu.setVisible(true);
}
};

item.addListener(SWT.MenuDetect, showMenuListener);

if (!EnvironmentUtil.isLinux()) {
// Tray icon popup menu positioning in Linux is off,
// Disable it for now.
item.addListener(SWT.Selection, showMenuListener);
}, 1000, 5000);

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}

@Subscribe
public void updateInterface(InterfaceUpdate update) {
log.info("Update Interface Event");
updateTray(update.getData());
tray.updateFolders(update.getData());
}

/**
* @return the clientIdentification
*/
public static String getClientIdentification() {
return clientIdentification;
}
Expand Down
Expand Up @@ -39,7 +39,7 @@
*/
public class WSClient {
private static final Logger log = Logger.getLogger(WSClient.class.getSimpleName());
private static final String DEFAULT_WS_SERVER = "ws://localhost:8887";
public static final String DEFAULT_WS_SERVER = "ws://localhost:8887";

private String location;
private WebSocketClient client;
Expand All @@ -50,7 +50,7 @@ public WSClient() throws URISyntaxException {

public WSClient(String location) throws URISyntaxException {
this.location = location;
client = createClient();
this.client = createClient();
}

private WebSocketClient createClient() throws URISyntaxException{
Expand Down

0 comments on commit d772bda

Please sign in to comment.