├── src
├── .idea
│ ├── .name
│ ├── copyright
│ │ └── profiles_settings.xml
│ ├── ant.xml
│ ├── encodings.xml
│ ├── vcs.xml
│ ├── inspectionProfiles
│ │ ├── profiles_settings.xml
│ │ └── Project_Default.xml
│ ├── libraries
│ │ └── swt.xml
│ ├── modules.xml
│ ├── compiler.xml
│ ├── runConfigurations
│ │ └── MibewTray.xml
│ ├── misc.xml
│ └── uiDesigner.xml
├── org.mibew.jabber
│ ├── resources
│ │ ├── Mibew Notifier.app
│ │ │ └── Contents
│ │ │ │ ├── PkgInfo
│ │ │ │ ├── MacOS
│ │ │ │ └── MibewNotifier
│ │ │ │ ├── Resources
│ │ │ │ └── mibew.icns
│ │ │ │ └── Info.plist
│ │ ├── images
│ │ │ └── mibew.gif
│ │ ├── packdmg.sh
│ │ └── build.xml
│ ├── libs
│ │ ├── smack.jar
│ │ ├── smackx.jar
│ │ ├── smackx-debug.jar
│ │ └── smackx-jingle.jar
│ ├── src
│ │ ├── mibew-sample.ini
│ │ └── org
│ │ │ └── mibew
│ │ │ └── jabber
│ │ │ ├── Parameters.java
│ │ │ └── Application.java
│ ├── .classpath
│ └── .project
├── org.mibew.notifier
│ ├── libs
│ │ ├── src.zip
│ │ ├── swt.jar
│ │ └── swt-debug.jar
│ ├── src
│ │ └── org
│ │ │ └── mibew
│ │ │ └── notifier
│ │ │ ├── tray_on.png
│ │ │ ├── tray_off.png
│ │ │ ├── ConsoleApp.java
│ │ │ ├── NotifyApp.java
│ │ │ ├── BrowserUtil.java
│ │ │ ├── Options.java
│ │ │ └── MibewTray.java
│ ├── .project
│ ├── .classpath
│ └── org.mibew.notifier.iml
└── org.mibew.api
│ ├── src
│ └── org
│ │ └── mibew
│ │ └── api
│ │ ├── MibewAgentListener.java
│ │ ├── MibewTrackerListener.java
│ │ ├── Utils.java
│ │ ├── handlers
│ │ ├── LoginHandler.java
│ │ └── UpdateHandler.java
│ │ ├── MibewResponse.java
│ │ ├── MibewAgentOptions.java
│ │ ├── MibewTracker.java
│ │ ├── MibewThread.java
│ │ ├── MibewAgent.java
│ │ └── MibewConnection.java
│ ├── .classpath
│ ├── .project
│ └── org.mibew.api.iml
├── .gitignore
├── .gitattributes
├── README.md
└── LICENSE
/src/.idea/.name:
--------------------------------------------------------------------------------
1 | mibew
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | src/.idea/workspace.xml
3 | src/org.mibew.notifier/resources/
4 | mibew.ini
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/libs/smack.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/libs/smack.jar
--------------------------------------------------------------------------------
/src/org.mibew.notifier/libs/src.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.notifier/libs/src.zip
--------------------------------------------------------------------------------
/src/org.mibew.notifier/libs/swt.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.notifier/libs/swt.jar
--------------------------------------------------------------------------------
/src/org.mibew.jabber/libs/smackx.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/libs/smackx.jar
--------------------------------------------------------------------------------
/src/org.mibew.jabber/libs/smackx-debug.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/libs/smackx-debug.jar
--------------------------------------------------------------------------------
/src/org.mibew.notifier/libs/swt-debug.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.notifier/libs/swt-debug.jar
--------------------------------------------------------------------------------
/src/org.mibew.jabber/libs/smackx-jingle.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/libs/smackx-jingle.jar
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/images/mibew.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/resources/images/mibew.gif
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/tray_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.notifier/src/org/mibew/notifier/tray_on.png
--------------------------------------------------------------------------------
/src/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/tray_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.notifier/src/org/mibew/notifier/tray_off.png
--------------------------------------------------------------------------------
/src/.idea/ant.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/MacOS/MibewNotifier:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/MacOS/MibewNotifier
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/Resources/mibew.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mibew/java/master/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/Resources/mibew.icns
--------------------------------------------------------------------------------
/src/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.php text
2 | *.pl text
3 | properties text
4 | *.html text
5 | *.css text
6 | *.tpl text
7 | *.xml text
8 | *.java text
9 | *.sh eol=lf
10 | *.txt text
11 | .project text
12 | .classpath text
13 | .buildpath text
14 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/src/mibew-sample.ini:
--------------------------------------------------------------------------------
1 | #
2 | # Configuration file for Mibew-to-jabber gate
3 | #
4 |
5 | jabber.host=jabber.org
6 | jabber.login=webim_notifier
7 | jabber.password=123
8 |
9 | jabber.admin=yourmail@jabber.org
10 |
--------------------------------------------------------------------------------
/src/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewAgentListener.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | public abstract class MibewAgentListener {
4 |
5 | protected void onlineStateChanged(boolean isOnline) {
6 | }
7 |
8 | protected void updated(MibewThread[] all, MibewThread[] created) {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/packdmg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -rf *.dmg
4 | hdiutil create mibew-notifier-temp.dmg -volname "Mibew Notifier 1.0" -fs HFS+ -srcfolder "Mibew Notifier.app"
5 | hdiutil convert "mibew-notifier-temp.dmg" -format UDZO -imagekey zlib-level=9 -o "mibew-1.0.0.dmg"
6 | rm mibew-notifier-temp.dmg
7 |
--------------------------------------------------------------------------------
/src/org.mibew.api/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/.idea/libraries/swt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewTrackerListener.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 |
4 | /**
5 | * @author inspirer
6 | */
7 | public abstract class MibewTrackerListener {
8 |
9 | public void threadCreated(MibewThread thread) {
10 | }
11 |
12 | public void threadChanged(MibewThread thread) {
13 | }
14 |
15 | public void threadClosed(MibewThread thread) {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/org.mibew.api/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.mibew.api
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.mibew.jabber
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.mibew.notifier
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/org.mibew.api/org.mibew.api.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/org.mibew.notifier.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/ConsoleApp.java:
--------------------------------------------------------------------------------
1 | package org.mibew.notifier;
2 |
3 | import org.mibew.api.MibewAgent;
4 | import org.mibew.api.MibewAgentListener;
5 |
6 | public class ConsoleApp {
7 |
8 | public static void main(String[] args) {
9 | Options options = new Options(args);
10 | if(!options.load()) {
11 | return;
12 | }
13 |
14 | MibewAgent agent = new MibewAgent(options.getAgentOptions(), new MibewAgentListener() {
15 | @Override
16 | protected void onlineStateChanged(boolean isOnline) {
17 | System.out.println("now " + (isOnline ? "online" : "offline"));
18 | }
19 | });
20 | agent.launch();
21 | try {
22 | Thread.sleep(3500);
23 | } catch (InterruptedException e) {
24 | }
25 |
26 | agent.stop();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mibew Java applications
2 |
3 | Mibew Java applications is a package of applications written in Java and designed
4 | to work with Mibew Messenger live support application.
5 |
6 | Mibew Java applications should be treated as separate applications tied
7 | to 1.6.x branch of Mibew Messenger by technology as well as by ideology.
8 |
9 | ## Terms of Use
10 |
11 | Mibew Java applications is a part of the Mibew project and licensed under the
12 | terms of [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
13 |
14 | ## Other repositories of the Mibew project
15 |
16 | 1. [Mibew Messenger core repository](https://github.com/Mibew/mibew)
17 | 2. [Mibew Messenger i18n repository](https://github.com/Mibew/i18n)
18 | 3. [Mibew Messenger design repository](https://github.com/Mibew/design)
19 | 4. [Mibew Tray repository](https://github.com/Mibew/tray)
20 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/Utils.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.security.MessageDigest;
5 | import java.security.NoSuchAlgorithmException;
6 |
7 | /**
8 | * @author inspirer
9 | */
10 | public class Utils {
11 |
12 | private static final String HEX_DIGITS = "0123456789abcdef";
13 |
14 | public static String md5(String string) throws NoSuchAlgorithmException, UnsupportedEncodingException {
15 | return md5(string.getBytes("utf-8"));
16 | }
17 |
18 | private static String md5(byte[] string) throws NoSuchAlgorithmException {
19 | MessageDigest md = MessageDigest.getInstance( "MD5" );
20 | md.update(string);
21 | byte[] digest = md.digest();
22 | StringBuilder sb = new StringBuilder();
23 | for ( byte b : digest ) {
24 | sb.append(HEX_DIGITS.charAt((b&0xff)>>4));
25 | sb.append(HEX_DIGITS.charAt(b&0xf));
26 | }
27 | return sb.toString();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/NotifyApp.java:
--------------------------------------------------------------------------------
1 | package org.mibew.notifier;
2 |
3 | import org.eclipse.swt.widgets.Display;
4 | import org.eclipse.swt.widgets.Shell;
5 | import org.mibew.api.MibewAgent;
6 | import org.mibew.notifier.Options.JOptions;
7 |
8 | public class NotifyApp {
9 |
10 | public static void main(String[] args) {
11 | Display display = new Display();
12 | Shell shell = new Shell(display);
13 |
14 | Options options = new JOptions(shell, args);
15 | if (!options.load()) {
16 | return;
17 | }
18 |
19 | MibewTray tray = new MibewTray();
20 | MibewAgent agent = new MibewAgent(options.getAgentOptions(), tray);
21 | agent.launch();
22 |
23 | tray.initTray(display, shell, agent);
24 |
25 | while (!shell.isDisposed()) {
26 | if (!display.readAndDispatch())
27 | display.sleep();
28 | }
29 | tray.dispose();
30 | agent.stop();
31 | display.dispose();
32 | System.exit(0);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/handlers/LoginHandler.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api.handlers;
2 |
3 | import java.util.Stack;
4 |
5 | import org.xml.sax.Attributes;
6 | import org.xml.sax.SAXException;
7 | import org.xml.sax.helpers.DefaultHandler;
8 |
9 | /**
10 | * @author inspirer
11 | */
12 | public class LoginHandler extends DefaultHandler {
13 |
14 | private Stack fPath = new Stack();
15 | private String status = "";
16 |
17 | @Override
18 | public void startElement(String uri, String localName, String name,
19 | Attributes attributes) throws SAXException {
20 | fPath.push(name);
21 | }
22 |
23 | @Override
24 | public void endElement(String uri, String localName, String name)
25 | throws SAXException {
26 | fPath.pop();
27 | }
28 |
29 | @Override
30 | public void characters(char[] ch, int start, int length) throws SAXException {
31 | String current = fPath.peek();
32 | if(fPath.size() != 2 || !current.equals("status") || !fPath.get(0).equals("login")) {
33 | throw new SAXException("unexpected characters");
34 | }
35 | status += new String(ch,start,length);
36 | }
37 |
38 | public String getStatus() {
39 | return status;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/.idea/runConfigurations/MibewTray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewResponse.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.io.Reader;
7 |
8 | /**
9 | * @author inspirer
10 | */
11 | public class MibewResponse {
12 |
13 | public int code;
14 | public byte[] response;
15 |
16 | public MibewResponse(int code, byte[] response) {
17 | this.code = code;
18 | this.response = response;
19 | }
20 |
21 | public int getCode() {
22 | return code;
23 | }
24 |
25 | public byte[] getResponse() {
26 | return response;
27 | }
28 |
29 | public String getResponseText() {
30 | try {
31 | Reader r = new InputStreamReader(new ByteArrayInputStream(response), "UTF-8");
32 | StringBuilder sb = new StringBuilder();
33 | char[] c = new char[1024];
34 | int size = 0;
35 | while((size = r.read(c)) != -1) {
36 | sb.append(c, 0, size);
37 | }
38 | return sb.toString();
39 | } catch(IOException ex) {
40 | return "";
41 | }
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return
47 | "Response code: " + code + "\n" +
48 | "Text: " + getResponseText();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/src/org/mibew/jabber/Parameters.java:
--------------------------------------------------------------------------------
1 | package org.mibew.jabber;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.Properties;
6 |
7 | /**
8 | * @author inspirer
9 | */
10 | public class Parameters {
11 |
12 | private final String[] fArguments;
13 |
14 | public String fJabberServer;
15 | public String fJabberLogin;
16 | public String fJabberPassword;
17 |
18 | public String fJabberAdmin;
19 |
20 | public Parameters(String[] args) {
21 | this.fArguments = args;
22 | }
23 |
24 | private String getProperty(Properties p, String name) throws IOException {
25 | String result = p.getProperty(name);
26 | if(result == null || result.trim().length() == 0) {
27 | throw new IOException("No '"+name+"' property");
28 | }
29 | return result;
30 | }
31 |
32 | public boolean load() {
33 | try {
34 | InputStream is = getClass().getClassLoader().getResourceAsStream("mibew.ini");
35 | if(is != null) {
36 | Properties p = new Properties();
37 | p.load(is);
38 |
39 | fJabberServer = getProperty(p, "jabber.host");
40 | fJabberLogin = getProperty(p, "jabber.login");
41 | fJabberPassword = getProperty(p, "jabber.password");
42 | fJabberAdmin = getProperty(p, "jabber.admin");
43 |
44 | return true;
45 | }
46 | } catch (IOException e) {
47 | System.err.println(e.getMessage());
48 | return false;
49 | }
50 |
51 | System.err.println("Cannot find mibew.ini");
52 | return false;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/BrowserUtil.java:
--------------------------------------------------------------------------------
1 | package org.mibew.notifier;
2 |
3 | import java.io.IOException;
4 | import java.lang.reflect.Method;
5 | import java.util.Arrays;
6 |
7 | public class BrowserUtil {
8 |
9 | static final String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "seamonkey", "galeon",
10 | "kazehakase", "mozilla", "netscape" };
11 |
12 | /**
13 | * Bare Bones Browser Launch
14 | * Version 2.0 (May 26, 2009)
15 | * By Dem Pilafian
16 | * @param url
17 | */
18 | public static void openURL(String url) throws IOException {
19 | String osName = System.getProperty("os.name");
20 | try {
21 | if (osName.startsWith("Mac OS")) {
22 | Class> fileMgr = Class.forName("com.apple.eio.FileManager");
23 | Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class });
24 | openURL.invoke(null, new Object[] { url });
25 | } else if (osName.startsWith("Windows")) {
26 | Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
27 | } else { // assume Unix or Linux
28 | boolean found = false;
29 | for (String browser : browsers)
30 | if (!found) {
31 | found = Runtime.getRuntime().exec(new String[] { "which", browser }).waitFor() == 0;
32 | if (found)
33 | Runtime.getRuntime().exec(new String[] { browser, url });
34 | }
35 | if (!found)
36 | throw new Exception(Arrays.toString(browsers));
37 | }
38 | } catch (Throwable th) {
39 | throw new IOException("Error attempting to launch web browser\n" + th.toString());
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | http://www.w3.org/1999/xhtml
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/Mibew Notifier.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleName
6 | Mibew Notifier
7 | CFBundleIdentifier
8 | org.mibew.notifier
9 | CFBundleVersion
10 | 100.0
11 | CFBundleAllowMixedLocalizations
12 | true
13 | CFBundleExecutable
14 | MibewNotifier
15 | CFBundleDevelopmentRegion
16 | English
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleGetInfoString
24 | Mibew Notifier 1.0, build 17 Jan, 2010
25 | CFBundleInfoDictionaryVersion
26 | 6.0
27 | CFBundleIconFile
28 | mibew.icns
29 | Java
30 |
31 | WorkingDirectory
32 | $APP_PACKAGE/Contents/Resources/Java
33 | VMOptions
34 | -Xms16mm
35 | MainClass
36 | org.mibew.trayapp.NotifyApp
37 | JVMVersion
38 | 1.6+
39 | ClassPath
40 |
41 | $JAVAROOT/org.mibew.notifier.jar
42 | $JAVAROOT/smackx.jar
43 | $JAVAROOT/smackx-jingle.jar
44 | $JAVAROOT/smackx-debug.jar
45 | $JAVAROOT/smack.jar
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewAgentOptions.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 |
6 | /**
7 | * @author inspirer
8 | */
9 | public class MibewAgentOptions {
10 |
11 | private String fUrl;
12 | private String fLogin;
13 | private String fPassword;
14 | private int fConnectionRefreshTimeout = 900; // in seconds (15 minutes by default)
15 | private int fPollingInterval = 2000; // 2 sec (in milliseconds)
16 |
17 | public MibewAgentOptions(String fUrl, String fLogin, String fPassword) {
18 | super();
19 | this.fUrl = fUrl;
20 | this.fLogin = fLogin;
21 | this.fPassword = fPassword;
22 | }
23 |
24 | public String getLogin() {
25 | return fLogin;
26 | }
27 |
28 | public String getPassword() {
29 | return fPassword;
30 | }
31 |
32 | public String getUrl() {
33 | return fUrl;
34 | }
35 |
36 | public int getConnectionRefreshTimeout() {
37 | return fConnectionRefreshTimeout;
38 | }
39 |
40 | public int getPollingInterval() {
41 | return fPollingInterval;
42 | }
43 |
44 | private static String getProperty(Properties p, String name, String defaultValue) throws IOException {
45 | String result = p.getProperty(name);
46 | if(result == null) {
47 | if(defaultValue != null) {
48 | return defaultValue;
49 | }
50 | throw new IOException("No '"+name+"' property");
51 | }
52 | return result;
53 | }
54 |
55 | public static MibewAgentOptions create(Properties p) throws IOException {
56 | String url = getProperty(p, "mibew.host", null);
57 | String login = getProperty(p, "mibew.login", null);
58 | String password = getProperty(p, "mibew.password", null);
59 |
60 | return new MibewAgentOptions(url, login, password);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/Options.java:
--------------------------------------------------------------------------------
1 | package org.mibew.notifier;
2 |
3 | import org.eclipse.swt.SWT;
4 | import org.eclipse.swt.widgets.MessageBox;
5 | import org.eclipse.swt.widgets.Shell;
6 | import org.mibew.api.MibewAgentOptions;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.util.Properties;
11 |
12 | public class Options {
13 |
14 | private MibewAgentOptions agentOptions;
15 | private Properties myProperties;
16 |
17 | public Options(String[] args) {
18 | }
19 |
20 | public boolean load() {
21 | try {
22 | InputStream is = getClass().getClassLoader().getResourceAsStream("mibew.ini");
23 | if (is != null) {
24 | myProperties = new Properties();
25 | myProperties.load(is);
26 | agentOptions = MibewAgentOptions.create(myProperties);
27 | return true;
28 | } else {
29 | handleError("cannot find mibew.ini");
30 | }
31 | } catch (IOException e) {
32 | handleError(e.getMessage());
33 | }
34 | return false;
35 | }
36 |
37 | protected void handleError(String message) {
38 | System.err.println(message);
39 | }
40 |
41 | public MibewAgentOptions getAgentOptions() {
42 | return agentOptions;
43 | }
44 |
45 | public static class JOptions extends Options {
46 |
47 | private final Shell fShell;
48 |
49 | public JOptions(Shell shell, String[] args) {
50 | super(args);
51 | fShell = shell;
52 | }
53 |
54 | @Override
55 | protected void handleError(final String message) {
56 | MessageBox messageBox = new MessageBox(fShell, SWT.OK | SWT.ICON_ERROR);
57 | messageBox.setText("Options error"); //$NON-NLS-1$
58 | messageBox.setMessage(message);
59 | messageBox.open();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/src/org/mibew/jabber/Application.java:
--------------------------------------------------------------------------------
1 | package org.mibew.jabber;
2 |
3 | import java.io.IOException;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 | import javax.xml.parsers.ParserConfigurationException;
7 |
8 | import org.jivesoftware.smack.Chat;
9 | import org.jivesoftware.smack.MessageListener;
10 | import org.jivesoftware.smack.XMPPConnection;
11 | import org.jivesoftware.smack.XMPPException;
12 | import org.jivesoftware.smack.packet.Message;
13 | import org.mibew.api.MibewConnection;
14 | import org.mibew.api.MibewThread;
15 | import org.mibew.api.MibewTracker;
16 | import org.mibew.api.MibewTrackerListener;
17 | import org.xml.sax.SAXException;
18 |
19 | /**
20 | * @author inspirer
21 | */
22 | public class Application {
23 |
24 | public static void main(String[] args) throws NoSuchAlgorithmException, IOException, XMPPException, InterruptedException, ParserConfigurationException, SAXException {
25 | System.out.println("Mibew Jabber transport application");
26 |
27 | Parameters p = new Parameters(args);
28 | if(!p.load()) {
29 | return;
30 | }
31 |
32 | XMPPConnection connection = new XMPPConnection(p.fJabberServer);
33 | connection.connect();
34 | connection.login(p.fJabberLogin, p.fJabberPassword);
35 | final Chat chat = connection.getChatManager().createChat(p.fJabberAdmin, new MessageListener() {
36 |
37 | public void processMessage(Chat chat, Message message) {
38 | System.out.println("Received message: " + message.getThread() + " " + message.getBody());
39 | }
40 | });
41 |
42 | MibewConnection conn = new MibewConnection("http://localhost:8080/webim/", "admin", "1");
43 | if(!conn.connect()) {
44 | System.err.println("Wrong server, login or password.");
45 | return;
46 | }
47 | MibewTracker mt = new MibewTracker(conn, new MibewTrackerListener(){
48 |
49 | @Override
50 | public void threadCreated(MibewThread thread) {
51 | try {
52 | chat.sendMessage(thread.getId() + ": " + thread.getAddress() + " " + thread.getClientName());
53 | } catch (XMPPException e) {
54 | e.printStackTrace();
55 | }
56 | }
57 |
58 | });
59 | //mt.track();
60 |
61 | connection.disconnect();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/org.mibew.jabber/resources/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewTracker.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 | import java.util.Collection;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | import javax.xml.parsers.ParserConfigurationException;
11 | import javax.xml.parsers.SAXParser;
12 | import javax.xml.parsers.SAXParserFactory;
13 |
14 | import org.mibew.api.handlers.UpdateHandler;
15 | import org.xml.sax.SAXException;
16 |
17 | /**
18 | * @author inspirer
19 | */
20 | public class MibewTracker {
21 |
22 | private final MibewConnection fConnection;
23 | private final MibewTrackerListener fListener;
24 | private long fSince = 0;
25 | private long fLastUpdate = 0;
26 |
27 | private final Map fThreads;
28 |
29 | public MibewTracker(MibewConnection conn, MibewTrackerListener listener) {
30 | this.fConnection = conn;
31 | this.fListener = listener;
32 | this.fThreads = new HashMap();
33 | }
34 |
35 | public void update() throws IOException, SAXException, ParserConfigurationException {
36 | MibewResponse response = fConnection.request("operator/update.php", "since=" + fSince);
37 | SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
38 | UpdateHandler handler = new UpdateHandler();
39 | sp.parse(new ByteArrayInputStream(response.getResponse()), handler);
40 | handleResponse(response, handler);
41 | }
42 |
43 | private void handleResponse(MibewResponse response, UpdateHandler handler) throws IOException {
44 | if (handler.getResponse() == UpdateHandler.UPD_ERROR) {
45 | throw new IOException("Update error: " + handler.getMessage());
46 | } else if (handler.getResponse() == UpdateHandler.UPD_SUCCESS) {
47 | fSince = handler.getRevision();
48 | fLastUpdate = handler.getTime();
49 | List threads = handler.getThreads();
50 | if (threads != null && threads.size() > 0) {
51 | processUpdate(threads);
52 | }
53 | } else {
54 | throw new IOException("Update error: " + response.getResponseText());
55 | }
56 | }
57 |
58 | private void processUpdate(List updated) {
59 | for (MibewThread mt : updated) {
60 | MibewThread existing = fThreads.get(mt.getId());
61 | boolean isClosed = mt.getState().equals("closed");
62 | if (existing == null) {
63 | if (!isClosed) {
64 | fThreads.put(mt.getId(), mt);
65 | fListener.threadCreated(mt);
66 | }
67 | } else if (isClosed) {
68 | fThreads.remove(mt.getId());
69 | fListener.threadClosed(existing);
70 | } else {
71 | existing.updateFrom(mt);
72 | fListener.threadChanged(existing);
73 | }
74 | }
75 | }
76 |
77 | public long getLastUpdate() {
78 | return fLastUpdate;
79 | }
80 |
81 | public MibewThread[] getThreads() {
82 | Collection values = fThreads.values();
83 | return values.toArray(new MibewThread[values.size()]);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewThread.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 |
4 | /**
5 | * @author inspirer
6 | */
7 | public class MibewThread implements Comparable {
8 |
9 | private final long fId;
10 | private String fState;
11 | private String fClientName = "";
12 | private String fAgent = "";
13 | private String fAddress = "";
14 | private String fFirstMessage = "";
15 | private boolean fCanOpen = false;
16 | private boolean fCanView = false;
17 | private boolean fCanBan = false;
18 | private String fStateText;
19 | private long fWaitingTime;
20 |
21 | public MibewThread(long id, String state) {
22 | fId = id;
23 | fState = state;
24 | }
25 |
26 | public void updateFrom(MibewThread updated) {
27 | if(fId != updated.fId) {
28 | throw new IllegalArgumentException("different threads");
29 | }
30 | fState = updated.fState;
31 | fClientName = updated.fClientName;
32 | fAgent = updated.fAgent;
33 | fAddress = updated.fAddress;
34 | fFirstMessage = updated.fFirstMessage;
35 | fCanOpen = updated.fCanOpen;
36 | fCanView = updated.fCanView;
37 | fCanBan = updated.fCanBan;
38 | fStateText = updated.fStateText;
39 | fWaitingTime = updated.fWaitingTime;
40 | }
41 |
42 | public long getId() {
43 | return fId;
44 | }
45 |
46 | public String getState() {
47 | return fState;
48 | }
49 |
50 | public String getStateText() {
51 | return fStateText;
52 | }
53 |
54 | public void setStateText(String stateText) {
55 | fStateText = stateText;
56 | }
57 |
58 | public String getAddress() {
59 | return fAddress;
60 | }
61 |
62 | public void setAddress(String address) {
63 | fAddress = address;
64 | }
65 |
66 | public String getAgent() {
67 | return fAgent;
68 | }
69 |
70 | public void setAgent(String agent) {
71 | fAgent = agent;
72 | }
73 |
74 | public String getClientName() {
75 | return fClientName;
76 | }
77 |
78 | public void setClientName(String clientName) {
79 | fClientName = clientName;
80 | }
81 |
82 | public String getFirstMessage() {
83 | return fFirstMessage;
84 | }
85 |
86 | public void setFirstMessage(String firstMessage) {
87 | fFirstMessage = firstMessage;
88 | }
89 |
90 | public boolean isCanBan() {
91 | return fCanBan;
92 | }
93 |
94 | public void setCanBan(boolean canBan) {
95 | fCanBan = canBan;
96 | }
97 |
98 | public boolean isCanOpen() {
99 | return fCanOpen;
100 | }
101 |
102 | public void setCanOpen(boolean canOpen) {
103 | fCanOpen = canOpen;
104 | }
105 |
106 | public boolean isCanView() {
107 | return fCanView;
108 | }
109 |
110 | public void setCanView(boolean canView) {
111 | fCanView = canView;
112 | }
113 |
114 | public long getWaitingTime() {
115 | return fWaitingTime;
116 | }
117 |
118 | public void setWaitingTime(long value) {
119 | fWaitingTime = value;
120 | }
121 |
122 | public int compareTo(MibewThread o) {
123 | int res = index(this).compareTo(index(o));
124 | if(res != 0) {
125 | return res;
126 | }
127 | return getClientName().compareTo(o.getClientName());
128 | }
129 |
130 | private Integer index(MibewThread th) {
131 | if("prio".equals(th.getState())) {
132 | return -1;
133 | }
134 | if("wait".equals(th.getState())) {
135 | return 0;
136 | }
137 | return 1;
138 | }
139 |
140 | @Override
141 | public String toString() {
142 | StringBuilder sb = new StringBuilder();
143 | boolean isChat = "chat".equals(getState());
144 | if(isChat) {
145 | sb.append("(chat) ");
146 | }
147 | sb.append(getClientName());
148 | if(!isCanOpen() && isCanView()) {
149 | sb.append(" (view only)");
150 | }
151 | if(!isChat) {
152 | sb.append(" - ");
153 | sb.append(formatWaitingTime((System.currentTimeMillis() - getWaitingTime())/1000));
154 | }
155 | return sb.toString();
156 | }
157 |
158 | private static String atLeast2(long i) {
159 | return i < 10 ? "0" + i : Long.toString(i);
160 | }
161 |
162 | private static String formatWaitingTime(long time) {
163 | String s = atLeast2(time/60%60) + ":" + atLeast2(time%60);
164 | if(time >= 3600) {
165 | s = atLeast2(time/3600%24) + ":" + s;
166 | if(time >= 24*3600) {
167 | s = time/24/3600 + "d, " + s;
168 | }
169 | }
170 | return s;
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewAgent.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.MalformedURLException;
5 | import java.security.NoSuchAlgorithmException;
6 | import java.util.LinkedList;
7 | import java.util.List;
8 |
9 | import javax.xml.parsers.ParserConfigurationException;
10 |
11 | import org.xml.sax.SAXException;
12 |
13 | /**
14 | * @author inspirer
15 | */
16 | public class MibewAgent {
17 |
18 | private final MibewAgentOptions fOptions;
19 | private final MibewAgentListener fListener;
20 | private final MibewUpdateThread fThread;
21 | private volatile boolean started;
22 |
23 | public MibewAgent(MibewAgentOptions options, MibewAgentListener listener) {
24 | fOptions = options;
25 | fListener = listener;
26 | fThread = new MibewUpdateThread();
27 | started = false;
28 | }
29 |
30 | public synchronized void launch() {
31 | if(!started) {
32 | fThread.start();
33 | started = true;
34 | }
35 | }
36 |
37 | public synchronized void stop() {
38 | if(started) {
39 | fThread.disconnect();
40 | started = false;
41 | }
42 | }
43 |
44 | public boolean isOnline() {
45 | return fThread.isOnline();
46 | }
47 |
48 | protected void logError(String message, Throwable th) {
49 | System.err.println(message);
50 | }
51 |
52 | public MibewAgentOptions getOptions() {
53 | return fOptions;
54 | }
55 |
56 | private class MibewUpdateThread extends Thread {
57 |
58 | private volatile boolean fExiting;
59 | private volatile boolean isOnline = false;
60 | private final Object fSync = new Object();
61 |
62 | public MibewUpdateThread() {
63 | setName("Mibew Connection thread");
64 | fExiting = false;
65 | }
66 |
67 | public void disconnect() {
68 | synchronized (fSync) {
69 | fExiting = true;
70 | fSync.notifyAll();
71 | }
72 | }
73 |
74 | @Override
75 | public void run() {
76 | while(!fExiting) {
77 | try {
78 | connectAndTrack();
79 | } catch(InterruptedException ex) {
80 | /* ignore */
81 | } catch(Throwable th) {
82 | logError(th.getMessage(), th);
83 | }
84 | }
85 | setOnline(false);
86 | }
87 |
88 | private void setOnline(boolean online) {
89 | if(isOnline != online) {
90 | isOnline = online;
91 | fListener.onlineStateChanged(online);
92 | }
93 | }
94 |
95 | public boolean isOnline() {
96 | return isOnline;
97 | }
98 |
99 | private void connectAndTrack() throws InterruptedException, UnsupportedEncodingException, NoSuchAlgorithmException, MalformedURLException, ParserConfigurationException, SAXException {
100 | setOnline(false);
101 | MibewConnection conn = new MibewConnection(fOptions.getUrl(), fOptions.getLogin(), fOptions.getPassword()) {
102 | @Override
103 | protected void handleError(String message, Exception ex) {
104 | logError(message, ex);
105 | }
106 | };
107 | if(!conn.connect()) {
108 | logError("Wrong server, login or password.", null);
109 | interruptableSleep(fOptions.getPollingInterval() * 3);
110 | return;
111 | }
112 | final List createdThreads = new LinkedList();
113 | MibewTracker mt = new MibewTracker(conn, new MibewTrackerListener(){
114 | @Override
115 | public void threadCreated(MibewThread thread) {
116 | createdThreads.add(thread);
117 | }
118 | });
119 | long maxTime = System.currentTimeMillis() + fOptions.getConnectionRefreshTimeout()*1000;
120 |
121 | int errorsCount = 0;
122 | while(!fExiting && (System.currentTimeMillis() < maxTime)) {
123 | try {
124 | createdThreads.clear();
125 | mt.update();
126 | fListener.updated(mt.getThreads(), createdThreads.toArray(new MibewThread[createdThreads.size()]));
127 | errorsCount = 0;
128 | setOnline(true);
129 | } catch (Throwable th) {
130 | setOnline(false);
131 | errorsCount++;
132 | logError("not updated", th);
133 | interruptableSleep(errorsCount < 10 ? fOptions.getPollingInterval() / 2 : fOptions.getPollingInterval() * 2);
134 | continue;
135 | }
136 | interruptableSleep(fOptions.getPollingInterval());
137 | }
138 |
139 | conn.disconnect();
140 | }
141 |
142 | private void interruptableSleep(long millis) throws InterruptedException {
143 | synchronized (fSync ) {
144 | if(fExiting) {
145 | return;
146 | }
147 | fSync.wait(millis);
148 | }
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/MibewConnection.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.io.UnsupportedEncodingException;
9 | import java.net.HttpURLConnection;
10 | import java.net.MalformedURLException;
11 | import java.net.URL;
12 | import java.net.URLEncoder;
13 | import java.security.NoSuchAlgorithmException;
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.Map.Entry;
18 | import java.util.regex.Matcher;
19 | import java.util.regex.Pattern;
20 |
21 | import javax.xml.parsers.ParserConfigurationException;
22 | import javax.xml.parsers.SAXParser;
23 | import javax.xml.parsers.SAXParserFactory;
24 |
25 | import org.mibew.api.handlers.LoginHandler;
26 |
27 | /**
28 | * @author inspirer
29 | */
30 | public class MibewConnection {
31 |
32 | private static final int REQUEST_TIMEOUT = 5000;
33 |
34 | private final String fUrl;
35 |
36 | private final Map fCookies;
37 |
38 | /**
39 | * @param url Ex: http://yourserver.com/webim/
40 | * @param login admin
41 | * @param password operators password
42 | */
43 | public MibewConnection(String url, String login, String password)
44 | throws UnsupportedEncodingException, NoSuchAlgorithmException,
45 | MalformedURLException {
46 | this.fUrl = url;
47 | this.fCookies = new HashMap();
48 | this.fCookies.put("webim_lite", URLEncoder.encode(login + "," + Utils.md5(Utils.md5(password)), "UTF-8"));
49 | }
50 |
51 | /**
52 | * Connects to the server and tries to login, returns true if successful.
53 | */
54 | public boolean connect() throws ParserConfigurationException {
55 | try {
56 | MibewResponse response = request("operator/autologin.php", "");
57 | SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
58 | LoginHandler handler = new LoginHandler();
59 | sp.parse(new ByteArrayInputStream(response.getResponse()), handler);
60 | String status = handler.getStatus();
61 | return status.equals("OK");
62 | } catch(Exception e) {
63 | handleError(e.getMessage(), e);
64 | return false;
65 | }
66 | }
67 |
68 | public void disconnect() {
69 | }
70 |
71 | /**
72 | * Request server.
73 | * @param suburl ex: operator/update.php
74 | * @param urlParameters post content
75 | */
76 | public final synchronized MibewResponse request(String suburl, String urlParameters) throws IOException {
77 | HttpURLConnection connection = null;
78 |
79 | try {
80 | connection = (HttpURLConnection) new URL(fUrl+suburl).openConnection();
81 | connection.setConnectTimeout(REQUEST_TIMEOUT);
82 | connection.setReadTimeout(REQUEST_TIMEOUT);
83 |
84 | connection.setRequestMethod("POST");
85 | connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
86 | connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
87 | if(fCookies.size() > 0) {
88 | StringBuilder sb = new StringBuilder();
89 | for(Entry cookie : fCookies.entrySet()) {
90 | if(sb.length() > 0) {
91 | sb.append("; ");
92 | }
93 | sb.append(cookie.getKey()+"="+cookie.getValue());
94 | }
95 | connection.addRequestProperty("Cookie", sb.toString());
96 | }
97 |
98 |
99 | connection.setUseCaches(false);
100 | connection.setDoInput(true);
101 | connection.setDoOutput(true);
102 |
103 | // create request
104 | DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
105 | wr.writeBytes(urlParameters);
106 | wr.flush();
107 | wr.close();
108 |
109 | // read response
110 | InputStream is = connection.getInputStream();
111 | int len = connection.getContentLength();
112 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(len < 256 ? 256 : len);
113 | byte b[] = new byte[1024];
114 | int size = 0;
115 | while((size=is.read(b)) >= 0) {
116 | buffer.write(b, 0, size);
117 | }
118 | is.close();
119 |
120 | // load cookies
121 | List cookies = connection.getHeaderFields().get("Set-Cookie");
122 | if(cookies != null) {
123 | for(String cookie : cookies) {
124 | Matcher matcher = COOKIESET.matcher(cookie);
125 | if(matcher.find()) {
126 | String name = matcher.group(1);
127 | String value = matcher.group(2);
128 | fCookies.put(name, value);
129 | }
130 | }
131 | }
132 | return new MibewResponse(connection.getResponseCode(), buffer.toByteArray());
133 | } catch (Exception e) {
134 | if(e instanceof IOException) {
135 | throw (IOException)e;
136 | }
137 | throw new IOException("cannot connect: " + e.getMessage());
138 | } finally {
139 | if (connection != null) {
140 | connection.disconnect();
141 | }
142 | }
143 | }
144 |
145 | protected void handleError(String message, Exception ex) {
146 | System.err.println(message);
147 | }
148 |
149 | private static Pattern COOKIESET = Pattern.compile("\\A(\\w+)=([^;]+);");
150 | }
151 |
--------------------------------------------------------------------------------
/src/org.mibew.notifier/src/org/mibew/notifier/MibewTray.java:
--------------------------------------------------------------------------------
1 | package org.mibew.notifier;
2 |
3 | import org.eclipse.swt.SWT;
4 | import org.eclipse.swt.graphics.Image;
5 | import org.eclipse.swt.widgets.*;
6 | import org.eclipse.swt.widgets.Event;
7 | import org.eclipse.swt.widgets.Menu;
8 | import org.eclipse.swt.widgets.MenuItem;
9 | import org.mibew.api.MibewAgent;
10 | import org.mibew.api.MibewAgentListener;
11 | import org.mibew.api.MibewThread;
12 |
13 | import java.awt.*;
14 | import java.io.IOException;
15 |
16 | public class MibewTray extends MibewAgentListener {
17 |
18 | private volatile boolean isStopped = false;
19 |
20 | private Image fImageOn;
21 | private Image fImageOff;
22 | private TrayItem fItem;
23 | private Menu fMenu;
24 | private MibewAgent fAgent;
25 |
26 | void initTray(Display display, Shell shell, MibewAgent agent) {
27 | fAgent = agent;
28 | fImageOn = new Image(display, getClass().getClassLoader().getResourceAsStream("org/mibew/notifier/tray_on.png"));
29 | fImageOff = new Image(display, getClass().getClassLoader().getResourceAsStream("org/mibew/notifier/tray_off.png"));
30 |
31 | final Tray tray = display.getSystemTray();
32 | if (tray == null) {
33 | System.out.println("The system tray is not available");
34 | } else {
35 | fItem = new TrayItem(tray, SWT.NONE);
36 | fItem.setToolTipText("SWT TrayItem");
37 | fItem.addListener(SWT.Show, new Listener() {
38 | public void handleEvent(Event event) {
39 | System.out.println("show");
40 | }
41 | });
42 | fItem.addListener(SWT.Hide, new Listener() {
43 | public void handleEvent(Event event) {
44 | System.out.println("hide");
45 | }
46 | });
47 | fMenu = new Menu(shell, SWT.POP_UP);
48 | for (int i = 0; i < 8; i++) {
49 | MenuItem mi = new MenuItem(fMenu, SWT.PUSH);
50 | mi.setText("Item" + i);
51 | mi.addListener(SWT.Selection, new Listener() {
52 | public void handleEvent(Event event) {
53 | System.out.println("selection " + event.widget);
54 | }
55 | });
56 | }
57 | Listener listener = new Listener() {
58 | public void handleEvent(Event event) {
59 | fMenu.setVisible(true);
60 | }
61 | };
62 | fItem.addListener(SWT.MenuDetect, listener);
63 | fItem.addListener(SWT.Selection, listener);
64 | fItem.setImage(fImageOff);
65 | }
66 | shell.setBounds(50, 50, 300, 200);
67 | //shell.open();
68 | }
69 |
70 | @Override
71 | protected synchronized void onlineStateChanged(final boolean isOnline) {
72 | if(isStopped)
73 | return;
74 |
75 | Display.getDefault().asyncExec(new Runnable() {
76 | public void run() {
77 | if(isStopped)
78 | return;
79 |
80 | fItem.setImage(isOnline ? fImageOn : fImageOff);
81 | }
82 | });
83 | }
84 |
85 | @Override
86 | protected synchronized void updated(final MibewThread[] all, final MibewThread[] created) {
87 | if(isStopped)
88 | return;
89 |
90 | Display.getDefault().asyncExec(new Runnable() {
91 | public void run() {
92 | if(isStopped)
93 | return;
94 |
95 | for (MenuItem menuItem : fMenu.getItems()) {
96 | menuItem.dispose();
97 | }
98 | for(MibewThread m : all) {
99 | MenuItem mi = new MenuItem(fMenu, SWT.PUSH);
100 | mi.setText(m.getClientName());
101 | mi.addListener(SWT.Selection, new LinkActionListener(null, fAgent.getOptions().getUrl() + "operator/agent.php?thread=" + m.getId()));
102 | }
103 |
104 | if(created.length == 1) {
105 | fItem.setToolTipText(created[0].getClientName() + "\n" + created[0].getFirstMessage());
106 | } else if(created.length > 1) {
107 | fItem.setToolTipText("New " + created.length + " visitors");
108 | }
109 |
110 | }
111 | });
112 | }
113 |
114 | synchronized void dispose() {
115 | isStopped = true;
116 | fItem.dispose();
117 | fImageOn.dispose();
118 | fImageOff.dispose();
119 | }
120 |
121 | private static class LinkActionListener implements Listener {
122 | private final Shell shell;
123 | private final String link;
124 |
125 | public LinkActionListener(Shell shell, String link) {
126 | this.shell = shell;
127 | this.link = link;
128 | }
129 |
130 | public void handleEvent(Event event) {
131 | try {
132 | BrowserUtil.openURL(link);
133 | } catch (IOException e1) {
134 | MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
135 | messageBox.setText("Browser error"); //$NON-NLS-1$
136 | messageBox.setMessage(e1.getMessage());
137 | messageBox.open();
138 | }
139 | }
140 | }}
141 |
--------------------------------------------------------------------------------
/src/org.mibew.api/src/org/mibew/api/handlers/UpdateHandler.java:
--------------------------------------------------------------------------------
1 | package org.mibew.api.handlers;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Stack;
6 |
7 | import org.mibew.api.MibewThread;
8 | import org.xml.sax.Attributes;
9 | import org.xml.sax.SAXException;
10 | import org.xml.sax.helpers.DefaultHandler;
11 |
12 | /**
13 | * @author inspirer
14 | */
15 | public class UpdateHandler extends DefaultHandler {
16 |
17 | public static final int UPD_ERROR = 1;
18 | public static final int UPD_SUCCESS = 2;
19 |
20 | private static final int STATE_READING_THREADS = 1;
21 |
22 | private int fResponse = 0;
23 | private String fMessage = "";
24 | private long fRevision;
25 | private long fTime;
26 | private List fUpdated;
27 |
28 | private int state = 0;
29 |
30 | private Stack fPath = new Stack();
31 | private MibewThread fCurrentThread;
32 |
33 | @Override
34 | public void startElement(String uri, String localName, String name,
35 | Attributes attributes) throws SAXException {
36 | try {
37 | if (fPath.size() == 0) {
38 | if (name.equals("error")) {
39 | fResponse = UPD_ERROR;
40 | } else if (name.equals("update")) {
41 | fResponse = UPD_SUCCESS;
42 | } else {
43 | throw new SAXException("unknown root element: " + name);
44 | }
45 | } else if(fResponse == UPD_SUCCESS) {
46 | if(fPath.size() == 1) {
47 | if (name.equals("threads")) {
48 | fTime = Long.parseLong(attributes.getValue("time"));
49 | fRevision = Long.parseLong(attributes.getValue("revision"));
50 | fUpdated = new ArrayList();
51 | state = STATE_READING_THREADS;
52 | }
53 | /* ignore others for compatibility reasons */
54 | }
55 | if (fPath.size() == 2 && state == STATE_READING_THREADS && name.equals("thread")) {
56 | long id = Long.parseLong(attributes.getValue("id"));
57 | String stateid = attributes.getValue("stateid");
58 | fCurrentThread = new MibewThread(id, stateid);
59 |
60 | if(!stateid.equals("closed")) {
61 | fCurrentThread.setStateText(attributes.getValue("state"));
62 | fCurrentThread.setCanOpen(booleanAttribute(attributes.getValue("canopen")));
63 | fCurrentThread.setCanView(booleanAttribute(attributes.getValue("canview")));
64 | fCurrentThread.setCanBan(booleanAttribute(attributes.getValue("canban")));
65 | }
66 |
67 | }
68 | }
69 | } catch (NumberFormatException ex) {
70 | throw new SAXException(ex.getMessage());
71 | }
72 | fPath.push(name);
73 | }
74 |
75 | private boolean booleanAttribute(String value) {
76 | if(value != null && value.equals("true")) {
77 | return true;
78 | }
79 | return false;
80 | }
81 |
82 | private long longValue(String value) throws SAXException {
83 | try {
84 | return Long.parseLong(value);
85 | } catch(NumberFormatException ex) {
86 | throw new SAXException(ex);
87 | }
88 | }
89 |
90 | @Override
91 | public void endElement(String uri, String localName, String name)
92 | throws SAXException {
93 | fPath.pop();
94 | if (fResponse == UPD_SUCCESS && fPath.size() == 2 && state == STATE_READING_THREADS && name.equals("thread")) {
95 | fUpdated.add(fCurrentThread);
96 | fCurrentThread = null;
97 | } else if(fPath.size() == 1 && state == STATE_READING_THREADS) {
98 | state = 0;
99 | }
100 | }
101 |
102 | @Override
103 | public void characters(char[] ch, int start, int length)
104 | throws SAXException {
105 | if (fResponse == UPD_ERROR) {
106 | String current = fPath.peek();
107 | if (fPath.size() != 2 || !current.equals("descr")) {
108 | throw new SAXException("unexpected characters");
109 | }
110 | fMessage += new String(ch, start, length);
111 | } else if (fResponse == UPD_SUCCESS && fCurrentThread != null) {
112 | if(fCurrentThread == null || fPath.size() != 4) {
113 | throw new SAXException("unknown characters");
114 | }
115 |
116 | String subvar = fPath.peek();
117 | String value = new String(ch, start, length);
118 | if("name".equals(subvar)) {
119 | fCurrentThread.setClientName(fCurrentThread.getClientName() + value);
120 | } else if("addr".equals(subvar)) {
121 | fCurrentThread.setAddress(fCurrentThread.getAddress() + value);
122 | } else if("message".equals(subvar)) {
123 | fCurrentThread.setFirstMessage(fCurrentThread.getFirstMessage() + value);
124 | } else if("agent".equals(subvar)) {
125 | fCurrentThread.setAgent(fCurrentThread.getAgent() + value);
126 | } else if("modified".equals(subvar)) {
127 | if(fCurrentThread.getWaitingTime() != 0) {
128 | throw new SAXException("error: waiting time is already set");
129 | }
130 | fCurrentThread.setWaitingTime(longValue(value) - fTime + System.currentTimeMillis());
131 | }
132 |
133 | // TODO
134 |
135 | } else {
136 | throw new SAXException("unexpected characters: no root");
137 | }
138 | }
139 |
140 | public int getResponse() {
141 | return fResponse;
142 | }
143 |
144 | public String getMessage() {
145 | return fMessage;
146 | }
147 |
148 | public long getTime() {
149 | return fTime;
150 | }
151 |
152 | public long getRevision() {
153 | return fRevision;
154 | }
155 |
156 | public List getThreads() {
157 | return fUpdated;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------