mirror of
https://github.com/Mibew/mibew.git
synced 2025-02-07 08:14:42 +03:00
Notification application (without options dialog)
git-svn-id: https://webim.svn.sourceforge.net/svnroot/webim/trunk@734 c66351dc-e62f-0410-b875-e3a5c0b9693f
This commit is contained in:
parent
ecb7d3643f
commit
01217e6b7d
@ -45,10 +45,14 @@ public class MibewAgent {
|
||||
return fThread.isOnline();
|
||||
}
|
||||
|
||||
private void logError(String message, Throwable th) {
|
||||
protected void logError(String message, Throwable th) {
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
public MibewAgentOptions getOptions() {
|
||||
return fOptions;
|
||||
}
|
||||
|
||||
private class MibewUpdateThread extends Thread {
|
||||
|
||||
private volatile boolean fExiting;
|
||||
@ -114,17 +118,21 @@ public class MibewAgent {
|
||||
});
|
||||
long maxTime = System.currentTimeMillis() + fOptions.getConnectionRefreshTimeout()*1000;
|
||||
|
||||
int errorsCount = 0;
|
||||
while(!fExiting && (System.currentTimeMillis() < maxTime)) {
|
||||
try {
|
||||
createdThreads.clear();
|
||||
mt.update();
|
||||
fListener.updated(mt.getThreads(), createdThreads.toArray(new MibewThread[createdThreads.size()]));
|
||||
} catch (Exception e) {
|
||||
errorsCount = 0;
|
||||
setOnline(true);
|
||||
} catch (Throwable th) {
|
||||
setOnline(false);
|
||||
interruptableSleep(fOptions.getPollingInterval() / 2);
|
||||
errorsCount++;
|
||||
logError("not updated", th);
|
||||
interruptableSleep(errorsCount < 10 ? fOptions.getPollingInterval() / 2 : fOptions.getPollingInterval() * 2);
|
||||
continue;
|
||||
}
|
||||
setOnline(true);
|
||||
interruptableSleep(fOptions.getPollingInterval());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.mibew.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author inspirer
|
||||
*/
|
||||
@ -8,8 +11,8 @@ public class MibewAgentOptions {
|
||||
private String fUrl;
|
||||
private String fLogin;
|
||||
private String fPassword;
|
||||
private int fConnectionRefreshTimeout = 900; // 15 minutes
|
||||
private int fPollingInterval = 3000; // 2 sec
|
||||
private int fConnectionRefreshTimeout = 900; // in seconds (15 minutes by default)
|
||||
private int fPollingInterval = 2000; // 2 sec (in milliseconds)
|
||||
|
||||
public MibewAgentOptions(String fUrl, String fLogin, String fPassword) {
|
||||
super();
|
||||
@ -37,4 +40,23 @@ public class MibewAgentOptions {
|
||||
public int getPollingInterval() {
|
||||
return fPollingInterval;
|
||||
}
|
||||
|
||||
private static String getProperty(Properties p, String name, String defaultValue) throws IOException {
|
||||
String result = p.getProperty(name);
|
||||
if(result == null || result.trim().length() == 0) {
|
||||
if(defaultValue != null) {
|
||||
return defaultValue;
|
||||
}
|
||||
throw new IOException("No '"+name+"' property");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MibewAgentOptions create(Properties p) throws IOException {
|
||||
String url = getProperty(p, "mibew.host", null);
|
||||
String login = getProperty(p, "mibew.login", null);
|
||||
String password = getProperty(p, "mibew.password", null);
|
||||
|
||||
return new MibewAgentOptions(url, login, password);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
package org.mibew.api;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* @author inspirer
|
||||
*/
|
||||
public class MibewThread {
|
||||
public class MibewThread implements Comparable<MibewThread> {
|
||||
|
||||
public final long fId;
|
||||
public String fState;
|
||||
public String fClientName = "";
|
||||
public String fAgent = "";
|
||||
public String fAddress = "";
|
||||
public String fFirstMessage = "";
|
||||
public boolean fCanOpen = false;
|
||||
public boolean fCanView = false;
|
||||
public boolean fCanBan = false;
|
||||
public String fStateText;
|
||||
private final long fId;
|
||||
private String fState;
|
||||
private String fClientName = "";
|
||||
private String fAgent = "";
|
||||
private String fAddress = "";
|
||||
private String fFirstMessage = "";
|
||||
private boolean fCanOpen = false;
|
||||
private boolean fCanView = false;
|
||||
private boolean fCanBan = false;
|
||||
private String fStateText;
|
||||
private long fWaitingTime;
|
||||
|
||||
public MibewThread(long id, String state) {
|
||||
fId = id;
|
||||
@ -34,5 +37,138 @@ public class MibewThread {
|
||||
fCanView = updated.fCanView;
|
||||
fCanBan = updated.fCanBan;
|
||||
fStateText = updated.fStateText;
|
||||
fWaitingTime = updated.fWaitingTime;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return fId;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return fState;
|
||||
}
|
||||
|
||||
public String getStateText() {
|
||||
return fStateText;
|
||||
}
|
||||
|
||||
public void setStateText(String stateText) {
|
||||
fStateText = stateText;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
fAddress = address;
|
||||
}
|
||||
|
||||
public String getAgent() {
|
||||
return fAgent;
|
||||
}
|
||||
|
||||
public void setAgent(String agent) {
|
||||
fAgent = agent;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return fClientName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
fClientName = clientName;
|
||||
}
|
||||
|
||||
public String getFirstMessage() {
|
||||
return fFirstMessage;
|
||||
}
|
||||
|
||||
public void setFirstMessage(String firstMessage) {
|
||||
fFirstMessage = firstMessage;
|
||||
}
|
||||
|
||||
public boolean isCanBan() {
|
||||
return fCanBan;
|
||||
}
|
||||
|
||||
public void setCanBan(boolean canBan) {
|
||||
fCanBan = canBan;
|
||||
}
|
||||
|
||||
public boolean isCanOpen() {
|
||||
return fCanOpen;
|
||||
}
|
||||
|
||||
public void setCanOpen(boolean canOpen) {
|
||||
fCanOpen = canOpen;
|
||||
}
|
||||
|
||||
public boolean isCanView() {
|
||||
return fCanView;
|
||||
}
|
||||
|
||||
public void setCanView(boolean canView) {
|
||||
fCanView = canView;
|
||||
}
|
||||
|
||||
public long getWaitingTime() {
|
||||
return fWaitingTime;
|
||||
}
|
||||
|
||||
public void setWaitingTime(long value) {
|
||||
fWaitingTime = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MibewThread o) {
|
||||
int res = index(this).compareTo(index(o));
|
||||
if(res != 0) {
|
||||
return res;
|
||||
}
|
||||
return getClientName().compareTo(o.getClientName());
|
||||
}
|
||||
|
||||
private Integer index(MibewThread th) {
|
||||
if("prio".equals(th.getState())) {
|
||||
return -1;
|
||||
}
|
||||
if("wait".equals(th.getState())) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean isChat = "chat".equals(getState());
|
||||
if(isChat) {
|
||||
sb.append("(chat) ");
|
||||
}
|
||||
sb.append(getClientName());
|
||||
if(!isCanOpen() && isCanView()) {
|
||||
sb.append(" (view only)");
|
||||
}
|
||||
if(!isChat) {
|
||||
sb.append(" - ");
|
||||
sb.append(formatWaitingTime((System.currentTimeMillis() - getWaitingTime())/1000));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String atLeast2(long i) {
|
||||
return i < 10 ? "0" + i : Long.toString(i);
|
||||
}
|
||||
|
||||
private static String formatWaitingTime(long time) {
|
||||
String s = atLeast2(time/60%60) + ":" + atLeast2(time%60);
|
||||
if(time >= 3600) {
|
||||
s = atLeast2(time/3600%24) + ":" + s;
|
||||
if(time >= 24*3600) {
|
||||
s = time/24/3600 + "d, " + s;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
@ -57,15 +57,15 @@ public class MibewTracker {
|
||||
|
||||
private void processUpdate(List<MibewThread> updated) {
|
||||
for (MibewThread mt : updated) {
|
||||
MibewThread existing = fThreads.get(mt.fId);
|
||||
boolean isClosed = mt.fState.equals("closed");
|
||||
MibewThread existing = fThreads.get(mt.getId());
|
||||
boolean isClosed = mt.getState().equals("closed");
|
||||
if (existing == null) {
|
||||
if (!isClosed) {
|
||||
fThreads.put(mt.fId, mt);
|
||||
fThreads.put(mt.getId(), mt);
|
||||
fListener.threadCreated(mt);
|
||||
}
|
||||
} else if (isClosed) {
|
||||
fThreads.remove(mt.fId);
|
||||
fThreads.remove(mt.getId());
|
||||
fListener.threadClosed(existing);
|
||||
} else {
|
||||
existing.updateFrom(mt);
|
||||
|
@ -48,10 +48,10 @@ public class UpdateHandler extends DefaultHandler {
|
||||
fCurrentThread = new MibewThread(id, stateid);
|
||||
|
||||
if(!stateid.equals("closed")) {
|
||||
fCurrentThread.fStateText = attributes.getValue("state");
|
||||
fCurrentThread.fCanOpen = booleanAttribute(attributes.getValue("canopen"));
|
||||
fCurrentThread.fCanView = booleanAttribute(attributes.getValue("canview"));
|
||||
fCurrentThread.fCanBan = booleanAttribute(attributes.getValue("canban"));
|
||||
fCurrentThread.setStateText(attributes.getValue("state"));
|
||||
fCurrentThread.setCanOpen(booleanAttribute(attributes.getValue("canopen")));
|
||||
fCurrentThread.setCanView(booleanAttribute(attributes.getValue("canview")));
|
||||
fCurrentThread.setCanBan(booleanAttribute(attributes.getValue("canban")));
|
||||
}
|
||||
|
||||
}
|
||||
@ -68,6 +68,14 @@ public class UpdateHandler extends DefaultHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
private long longValue(String value) throws SAXException {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch(NumberFormatException ex) {
|
||||
throw new SAXException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String name)
|
||||
throws SAXException {
|
||||
@ -99,13 +107,18 @@ public class UpdateHandler extends DefaultHandler {
|
||||
String subvar = fPath.peek();
|
||||
String value = new String(ch, start, length);
|
||||
if("name".equals(subvar)) {
|
||||
fCurrentThread.fClientName += value;
|
||||
fCurrentThread.setClientName(fCurrentThread.getClientName() + value);
|
||||
} else if("addr".equals(subvar)) {
|
||||
fCurrentThread.fAddress += value;
|
||||
fCurrentThread.setAddress(fCurrentThread.getAddress() + value);
|
||||
} else if("message".equals(subvar)) {
|
||||
fCurrentThread.fFirstMessage += value;
|
||||
fCurrentThread.setFirstMessage(fCurrentThread.getFirstMessage() + value);
|
||||
} else if("agent".equals(subvar)) {
|
||||
fCurrentThread.fAgent += value;
|
||||
fCurrentThread.setAgent(fCurrentThread.getAgent() + value);
|
||||
} else if("modified".equals(subvar)) {
|
||||
if(fCurrentThread.getWaitingTime() != 0) {
|
||||
throw new SAXException("error: waiting time is already set");
|
||||
}
|
||||
fCurrentThread.setWaitingTime(longValue(value) - fTime + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
@ -49,7 +49,7 @@ public class Application {
|
||||
@Override
|
||||
public void threadCreated(MibewThread thread) {
|
||||
try {
|
||||
chat.sendMessage(thread.fId + ": " + thread.fAddress + " " + thread.fClientName);
|
||||
chat.sendMessage(thread.getId() + ": " + thread.getAddress() + " " + thread.getClientName());
|
||||
} catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
5
src/mibewjava/org.mibew.notifier/src/mibew.ini
Normal file
5
src/mibewjava/org.mibew.notifier/src/mibew.ini
Normal file
@ -0,0 +1,5 @@
|
||||
# Mibew parameters
|
||||
|
||||
mibew.host=http://localhost:8080/webim/
|
||||
mibew.login=admin
|
||||
mibew.password=1
|
@ -0,0 +1,42 @@
|
||||
package org.mibew.notifier;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BrowserUtil {
|
||||
|
||||
static final String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "seamonkey", "galeon",
|
||||
"kazehakase", "mozilla", "netscape" };
|
||||
|
||||
/**
|
||||
* Bare Bones Browser Launch
|
||||
* Version 2.0 (May 26, 2009)
|
||||
* By Dem Pilafian
|
||||
* @param url
|
||||
*/
|
||||
public static void openURL(String url) throws IOException {
|
||||
String osName = System.getProperty("os.name");
|
||||
try {
|
||||
if (osName.startsWith("Mac OS")) {
|
||||
Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
|
||||
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class });
|
||||
openURL.invoke(null, new Object[] { url });
|
||||
} else if (osName.startsWith("Windows")) {
|
||||
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
|
||||
} else { // assume Unix or Linux
|
||||
boolean found = false;
|
||||
for (String browser : browsers)
|
||||
if (!found) {
|
||||
found = Runtime.getRuntime().exec(new String[] { "which", browser }).waitFor() == 0;
|
||||
if (found)
|
||||
Runtime.getRuntime().exec(new String[] { browser, url });
|
||||
}
|
||||
if (!found)
|
||||
throw new Exception(Arrays.toString(browsers));
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
throw new IOException("Error attempting to launch web browser\n" + th.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -2,12 +2,16 @@ package org.mibew.notifier;
|
||||
|
||||
import org.mibew.api.MibewAgent;
|
||||
import org.mibew.api.MibewAgentListener;
|
||||
import org.mibew.api.MibewAgentOptions;
|
||||
|
||||
public class ConsoleApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
MibewAgent agent = new MibewAgent(new MibewAgentOptions("http://localhost:8080/webim/", "admin", "1"), new MibewAgentListener() {
|
||||
Options options = new Options(args);
|
||||
if(!options.load()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MibewAgent agent = new MibewAgent(options.getAgentOptions(), new MibewAgentListener() {
|
||||
@Override
|
||||
protected void onlineStateChanged(boolean isOnline) {
|
||||
System.out.println("now " + (isOnline ? "online" : "offline"));
|
||||
|
@ -1,15 +1,20 @@
|
||||
package org.mibew.notifier;
|
||||
|
||||
import org.mibew.api.MibewAgent;
|
||||
import org.mibew.api.MibewAgentOptions;
|
||||
import org.mibew.notifier.Options.JOptions;
|
||||
|
||||
public class NotifyApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Options options = new JOptions(args);
|
||||
if(!options.load()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrayNotifier tn = new TrayNotifier();
|
||||
tn.init();
|
||||
|
||||
MibewAgent agent = new MibewAgent(new MibewAgentOptions("http://localhost:8080/webim/", "admin", "1"), tn);
|
||||
MibewAgent agent = new MibewAgent(options.getAgentOptions(), tn);
|
||||
agent.launch();
|
||||
|
||||
tn.setAgent(agent);
|
||||
|
@ -0,0 +1,55 @@
|
||||
package org.mibew.notifier;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.mibew.api.MibewAgentOptions;
|
||||
|
||||
public class Options {
|
||||
|
||||
private MibewAgentOptions agentOptions;
|
||||
private Properties myProperties;
|
||||
|
||||
public Options(String[] args) {
|
||||
}
|
||||
|
||||
public boolean load() {
|
||||
try {
|
||||
InputStream is = getClass().getClassLoader().getResourceAsStream("mibew.ini");
|
||||
if (is != null) {
|
||||
myProperties = new Properties();
|
||||
myProperties.load(is);
|
||||
agentOptions = MibewAgentOptions.create(myProperties);
|
||||
return true;
|
||||
} else {
|
||||
handleError("cannot find mibew.ini");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
handleError(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void handleError(String message) {
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
public MibewAgentOptions getAgentOptions() {
|
||||
return agentOptions;
|
||||
}
|
||||
|
||||
public static class JOptions extends Options {
|
||||
|
||||
public JOptions(String[] args) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleError(String message) {
|
||||
JOptionPane.showMessageDialog(null, message);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.mibew.notifier;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Image;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.MenuShortcut;
|
||||
@ -12,6 +13,11 @@ import java.awt.TrayIcon.MessageType;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.mibew.api.MibewAgent;
|
||||
import org.mibew.api.MibewAgentListener;
|
||||
@ -69,11 +75,20 @@ public class TrayNotifier extends MibewAgentListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updated(MibewThread[] all, MibewThread[] created) {
|
||||
PopupMenu pm = new PopupMenu();
|
||||
protected void updated(MibewThread[] all, final MibewThread[] created) {
|
||||
Arrays.sort(all);
|
||||
|
||||
final PopupMenu pm = new PopupMenu();
|
||||
boolean beforeChat = false;
|
||||
for(MibewThread mt : all) {
|
||||
MenuItem mi = new MenuItem(mt.fClientName);
|
||||
boolean isChat = "chat".equals(mt.getState());
|
||||
if(beforeChat && isChat) {
|
||||
pm.addSeparator();
|
||||
}
|
||||
MenuItem mi = new MenuItem(mt.toString());
|
||||
mi.addActionListener(new LinkActionListener(agent.getOptions().getUrl() + "operator/agent.php?thread=" + mt.getId()));
|
||||
pm.add(mi);
|
||||
beforeChat = !isChat;
|
||||
}
|
||||
if(all.length > 0) {
|
||||
pm.addSeparator();
|
||||
@ -81,16 +96,45 @@ public class TrayNotifier extends MibewAgentListener {
|
||||
MenuItem exitItem = new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X));
|
||||
exitItem.addActionListener(fExit);
|
||||
pm.add(exitItem);
|
||||
|
||||
try {
|
||||
EventQueue.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
trayIcon.setPopupMenu(pm);
|
||||
|
||||
if(created.length == 1) {
|
||||
trayIcon.displayMessage("New visitor", created[0].fClientName + "\n" + created[0].fFirstMessage, MessageType.INFO);
|
||||
trayIcon.displayMessage("New visitor", created[0].getClientName() + "\n" + created[0].getFirstMessage(), MessageType.INFO);
|
||||
} else if(created.length > 1) {
|
||||
trayIcon.displayMessage("New visitors", "New " + created.length + " visitors", MessageType.INFO);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
/* skip cycle */
|
||||
} catch (InvocationTargetException e) {
|
||||
/* hmm */
|
||||
}
|
||||
}
|
||||
|
||||
public void setAgent(MibewAgent agent) {
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
private static class LinkActionListener implements ActionListener {
|
||||
String link;
|
||||
|
||||
public LinkActionListener(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
BrowserUtil.openURL(link);
|
||||
} catch (IOException e1) {
|
||||
JOptionPane.showMessageDialog(null, e1.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user