Browse Source

Add Freedesktop Notifications plugin (Fixes issue 3414)

Ootion for less-strict html parsing. (Fixes issue 3484)
When the plugins module is more friendly to alternative packages I will repackage commons where it should be.

Change-Id: Icf4afe2ffd9280194dea70601addacbb57bacc4b
Reviewed-on: http://gerrit.dmdirc.com/436
Reviewed-by: Gregory Holmes <greboid@dmdirc.com>
Tested-by: Gregory Holmes <greboid@dmdirc.com>
tags/0.6.3
Shane Mc Cormack 14 years ago
parent
commit
e474f53285

+ 78
- 0
src/com/dmdirc/addons/freedesktop_notifications/FDNotifyCommand.java View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.freedesktop_notifications;
24
+
25
+import com.dmdirc.Server;
26
+import com.dmdirc.commandparser.CommandArguments;
27
+import com.dmdirc.commandparser.CommandManager;
28
+import com.dmdirc.commandparser.commands.GlobalCommand;
29
+import com.dmdirc.ui.interfaces.InputWindow;
30
+
31
+import java.util.List;
32
+
33
+/**
34
+ * The FDNotify Command shows a nice popup on using the FreeDesktop
35
+ * VisualNotifications.
36
+ *
37
+ * @author Shane 'Dataforce' McCormack
38
+ */
39
+public final class FDNotifyCommand extends GlobalCommand {
40
+    /** Plugin that owns this command. */
41
+    final FreeDesktopNotificationsPlugin myPlugin;
42
+    
43
+    /**
44
+     * Creates a new instance of FDNotifyCommand.
45
+     *
46
+     * @param myPlugin the plugin creating this command.
47
+     */
48
+    public FDNotifyCommand(final FreeDesktopNotificationsPlugin myPlugin) {
49
+        super();
50
+        this.myPlugin = myPlugin;
51
+        CommandManager.registerCommand(this);
52
+    }
53
+
54
+    /** {@inheritDoc} */
55
+    @Override
56
+    public void execute(final InputWindow origin, final boolean isSilent, final CommandArguments args) {
57
+        myPlugin.showNotification("", args.getArgumentsAsString());
58
+    }
59
+    
60
+    
61
+    /** {@inheritDoc} */
62
+    @Override
63
+    public String getName() {
64
+        return "fdnotify";
65
+    }
66
+    
67
+    /** {@inheritDoc} */
68
+    @Override
69
+    public boolean showInHelp() {
70
+        return true;
71
+    }
72
+    
73
+    /** {@inheritDoc} */
74
+    @Override
75
+    public String getHelp() {
76
+        return "fdnotify <message> - Show a nice popup where available";
77
+    }
78
+}

+ 223
- 0
src/com/dmdirc/addons/freedesktop_notifications/FreeDesktopNotificationsPlugin.java View File

@@ -0,0 +1,223 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.freedesktop_notifications;
24
+
25
+import com.dmdirc.plugins.Plugin;
26
+import com.dmdirc.plugins.PluginInfo;
27
+import com.dmdirc.plugins.PluginManager;
28
+import com.dmdirc.util.resourcemanager.ResourceManager;
29
+import com.dmdirc.logger.ErrorLevel;
30
+import com.dmdirc.logger.Logger;
31
+import com.dmdirc.Main;
32
+import java.io.File;
33
+import java.io.IOException;
34
+import java.util.Map;
35
+import java.util.Map.Entry;
36
+import java.util.ArrayList;
37
+import com.dmdirc.commandparser.CommandManager;
38
+import com.dmdirc.installer.StreamReader;
39
+import com.dmdirc.ui.messages.Styliser;
40
+import com.dmdirc.config.IdentityManager;
41
+import com.dmdirc.config.Identity;
42
+import com.dmdirc.config.prefs.PreferencesManager;
43
+import com.dmdirc.config.prefs.PreferencesCategory;
44
+import com.dmdirc.config.prefs.PreferencesSetting;
45
+import com.dmdirc.config.prefs.PreferencesType;
46
+import com.dmdirc.addons.freedesktop_notifications.commons.StringEscapeUtils;;
47
+
48
+/**
49
+ * This plugin adds freedesktop Style Notifications to dmdirc.
50
+ *
51
+ * @author Shane 'Dataforce' McCormack
52
+ */
53
+public final class FreeDesktopNotificationsPlugin extends Plugin {
54
+    /** The DcopCommand we created */
55
+    private FDNotifyCommand command = null;
56
+    
57
+    /** Files dir */
58
+    private static final String filesDir  = Main.getConfigDir() + "plugins/freedesktop_notifications_files/";
59
+    
60
+    /**
61
+     * Creates a new instance of the FreeDesktopNotifications Plugin.
62
+     */
63
+    public FreeDesktopNotificationsPlugin() {
64
+        super();
65
+    }
66
+
67
+    /**
68
+     * Used to show a notification using this plugin.
69
+     *
70
+     * @param title Title of dialog if applicable
71
+     * @param message Message to show
72
+     * @return True if the notification was shown.
73
+     */
74
+    public boolean showNotification(final String title, final String message) {
75
+        final int seconds = IdentityManager.getGlobalConfig().getOptionInt(getDomain(), "general.timeout");
76
+        final String icon = IdentityManager.getGlobalConfig().getOption(getDomain(), "general.icon");
77
+        final ArrayList<String> args = new ArrayList<String>();
78
+        
79
+        args.add("/usr/bin/env");
80
+        args.add("python");
81
+        args.add(filesDir+"notify.py");
82
+        args.add("-a");
83
+        args.add("DMDirc");
84
+        args.add("-i");
85
+        args.add(icon);
86
+        args.add("-t");
87
+        args.add(Integer.toString(seconds * 1000));
88
+        args.add("-s");
89
+
90
+        if (title != null && !title.isEmpty()) {
91
+            args.add(prepareString(title));
92
+        } else {
93
+            args.add("Notification from DMDirc");
94
+        }
95
+        args.add(prepareString(message));
96
+        
97
+        try {
98
+            final Process myProcess = Runtime.getRuntime().exec(args.toArray(new String[]{}));
99
+            final StringBuffer data = new StringBuffer();
100
+            new StreamReader(myProcess.getErrorStream()).start();
101
+            new StreamReader(myProcess.getInputStream(), data).start();
102
+            try { myProcess.waitFor(); } catch (InterruptedException e) { }
103
+            return true;
104
+        } catch (SecurityException e) {
105
+        } catch (IOException e) {
106
+        }
107
+        
108
+        return false;
109
+    }
110
+    
111
+    /**
112
+     * Prepare the string for sending to dbus.
113
+     *
114
+     * @param input Input string
115
+     * @return Input string after being processed according to config settings.
116
+     */
117
+    public final String prepareString(final String input) {
118
+        final boolean escapehtml = IdentityManager.getGlobalConfig().getOptionBool(getDomain(), "advanced.escapehtml");
119
+	final boolean strictescape = IdentityManager.getGlobalConfig().getOptionBool(getDomain(), "advanced.strictescape");
120
+        final boolean stripcodes = IdentityManager.getGlobalConfig().getOptionBool(getDomain(), "advanced.stripcodes");
121
+
122
+        String output = input;
123
+        if (stripcodes) { output = Styliser.stipControlCodes(output); }
124
+        if (escapehtml) {
125
+	    if (strictescape) {
126
+                output = StringEscapeUtils.escapeHtml(output);
127
+            } else {
128
+                output = output.replaceAll("&", "&amp;");
129
+                output = output.replaceAll("<", "&lt;");
130
+                output = output.replaceAll(">", "&gt;");
131
+            }
132
+        }
133
+        
134
+        return output;
135
+    }
136
+
137
+    /**
138
+     * Called when the plugin is loaded.
139
+     */
140
+    @Override
141
+    public void onLoad() {
142
+        command = new FDNotifyCommand(this);
143
+
144
+        // Extract required Files
145
+        final PluginInfo pi = PluginManager.getPluginManager().getPluginInfoByName("freedesktop_notifications");
146
+        
147
+        // This shouldn't actually happen, but check to make sure.
148
+        if (pi != null) {
149
+            // Now get the RM
150
+            try {
151
+                final ResourceManager res = pi.getResourceManager();
152
+                
153
+                // Make sure our files dir exists
154
+                final File newDir = new File(filesDir);
155
+                if (!newDir.exists()) {
156
+                    newDir.mkdirs();
157
+                }
158
+            
159
+                // Now extract the files needed
160
+                extractFiles(res, newDir, ".py");
161
+                extractFiles(res, newDir, ".png");
162
+            } catch (IOException ioe) {
163
+                Logger.userError(ErrorLevel.LOW, "Unable to open ResourceManager for freedesktop_notifications: "+ioe.getMessage(), ioe);
164
+            }
165
+        }
166
+    }
167
+    
168
+    /**
169
+     * Use the given resource manager to extract files ending with the given suffix
170
+     *
171
+     * @param res ResourceManager
172
+     * @param newDir Directory to extract to.
173
+     * @param suffix Suffix to extract
174
+     */
175
+    private static void extractFiles(final ResourceManager res, final File newDir, final String suffix) {
176
+        final Map<String, byte[]> resources = res.getResourcesEndingWithAsBytes(suffix);
177
+        for (Entry<String, byte[]> resource : resources.entrySet()) {
178
+            try {
179
+                final String key = resource.getKey();
180
+                final String resourceName = key.substring(key.lastIndexOf('/'), key.length());
181
+
182
+                final File newFile = new File(newDir, resourceName);
183
+
184
+                if (!newFile.isDirectory()) {
185
+                    if (newFile.exists()) { newFile.delete(); }
186
+                    ResourceManager.getResourceManager().resourceToFile(resource.getValue(), newFile);
187
+                }
188
+            } catch (IOException ex) {
189
+                Logger.userError(ErrorLevel.LOW, "Failed to extract "+suffix+"s for freedesktop_notifications: "+ex.getMessage(), ex);
190
+            }
191
+        }
192
+    }
193
+
194
+    /**
195
+     * Called when this plugin is Unloaded.
196
+     */
197
+    @Override
198
+    public synchronized void onUnload() {
199
+        CommandManager.unregisterCommand(command);
200
+    }
201
+    
202
+    /** {@inheritDoc} */
203
+    @Override
204
+    public void domainUpdated() {
205
+        final Identity defaults = IdentityManager.getAddonIdentity();
206
+        defaults.setOption(getDomain(), "general.icon", filesDir+"icon.png");
207
+    }
208
+    
209
+    /** {@inheritDoc} */
210
+    @Override
211
+    public void showConfig(final PreferencesManager manager) {
212
+        final PreferencesCategory general = new PreferencesCategory("FreeDesktop Notifications", "General configuration for FreeDesktop Notifications plugin.");
213
+        
214
+        general.addSetting(new PreferencesSetting(PreferencesType.INTEGER, getDomain(), "general.timeout", "Timeout", "Length of time in seconds before the notification popup closes."));
215
+        general.addSetting(new PreferencesSetting(PreferencesType.TEXT, getDomain(), "general.icon", "icon", "Path to icon to use on the notification."));
216
+        general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN, getDomain(), "advanced.escapehtml", "Escape HTML", "Some Implementations randomly parse HTML, escape it before showing?"));
217
+	general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN, getDomain(), "advanced.strictescape", "Strict Escape HTML", "Strictly escape HTML or just the basic characters? (&, < and >)"));
218
+        general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN, getDomain(), "advanced.stripcodes", "Strip Control Codes", "Strip IRC Control codes from messages?"));
219
+        
220
+        manager.getCategory("Plugins").addSubCategory(general);
221
+    }
222
+}
223
+

+ 1010
- 0
src/com/dmdirc/addons/freedesktop_notifications/commons/Entities.java
File diff suppressed because it is too large
View File


+ 364
- 0
src/com/dmdirc/addons/freedesktop_notifications/commons/IntHashMap.java View File

@@ -0,0 +1,364 @@
1
+/*
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements.  See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License.  You may obtain a copy of the License at
8
+ * 
9
+ *      http://www.apache.org/licenses/LICENSE-2.0
10
+ * 
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+/*
19
+ * Note: originally released under the GNU LGPL v2.1, 
20
+ * but rereleased by the original author under the ASF license (above).
21
+ */
22
+package com.dmdirc.addons.freedesktop_notifications.commons;
23
+
24
+/**
25
+ * <p>A hash map that uses primitive ints for the key rather than objects.</p>
26
+ *
27
+ * <p>Note that this class is for internal optimization purposes only, and may
28
+ * not be supported in future releases of Apache Commons Lang.  Utilities of
29
+ * this sort may be included in future releases of Apache Commons Collections.</p>
30
+ *
31
+ * @author Justin Couch
32
+ * @author Alex Chaffee (alex@apache.org)
33
+ * @author Stephen Colebourne
34
+ * @since 2.0
35
+ * @version $Revision$
36
+ * @see java.util.HashMap
37
+ */
38
+class IntHashMap {
39
+
40
+    /**
41
+     * The hash table data.
42
+     */
43
+    private transient Entry table[];
44
+
45
+    /**
46
+     * The total number of entries in the hash table.
47
+     */
48
+    private transient int count;
49
+
50
+    /**
51
+     * The table is rehashed when its size exceeds this threshold.  (The
52
+     * value of this field is (int)(capacity * loadFactor).)
53
+     *
54
+     * @serial
55
+     */
56
+    private int threshold;
57
+
58
+    /**
59
+     * The load factor for the hashtable.
60
+     *
61
+     * @serial
62
+     */
63
+    private float loadFactor;
64
+
65
+    /**
66
+     * <p>Innerclass that acts as a datastructure to create a new entry in the
67
+     * table.</p>
68
+     */
69
+    private static class Entry {
70
+        int hash;
71
+//        int key;    // not used currently
72
+        Object value;
73
+        Entry next;
74
+
75
+        /**
76
+         * <p>Create a new entry with the given values.</p>
77
+         *
78
+         * @param hash The code used to hash the object with
79
+         * @param key The key used to enter this in the table
80
+         * @param value The value for this key
81
+         * @param next A reference to the next entry in the table
82
+         */
83
+        protected Entry(int hash, int key, Object value, Entry next) {
84
+            this.hash = hash;
85
+//            this.key = key;
86
+            this.value = value;
87
+            this.next = next;
88
+        }
89
+    }
90
+
91
+    /**
92
+     * <p>Constructs a new, empty hashtable with a default capacity and load
93
+     * factor, which is <code>20</code> and <code>0.75</code> respectively.</p>
94
+     */
95
+    public IntHashMap() {
96
+        this(20, 0.75f);
97
+    }
98
+
99
+    /**
100
+     * <p>Constructs a new, empty hashtable with the specified initial capacity
101
+     * and default load factor, which is <code>0.75</code>.</p>
102
+     *
103
+     * @param  initialCapacity the initial capacity of the hashtable.
104
+     * @throws IllegalArgumentException if the initial capacity is less
105
+     *   than zero.
106
+     */
107
+    public IntHashMap(int initialCapacity) {
108
+        this(initialCapacity, 0.75f);
109
+    }
110
+
111
+    /**
112
+     * <p>Constructs a new, empty hashtable with the specified initial
113
+     * capacity and the specified load factor.</p>
114
+     *
115
+     * @param initialCapacity the initial capacity of the hashtable.
116
+     * @param loadFactor the load factor of the hashtable.
117
+     * @throws IllegalArgumentException  if the initial capacity is less
118
+     *             than zero, or if the load factor is nonpositive.
119
+     */
120
+    public IntHashMap(int initialCapacity, float loadFactor) {
121
+        super();
122
+        if (initialCapacity < 0) {
123
+            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
124
+        }
125
+        if (loadFactor <= 0) {
126
+            throw new IllegalArgumentException("Illegal Load: " + loadFactor);
127
+        }
128
+        if (initialCapacity == 0) {
129
+            initialCapacity = 1;
130
+        }
131
+
132
+        this.loadFactor = loadFactor;
133
+        table = new Entry[initialCapacity];
134
+        threshold = (int) (initialCapacity * loadFactor);
135
+    }
136
+
137
+    /**
138
+     * <p>Returns the number of keys in this hashtable.</p>
139
+     *
140
+     * @return  the number of keys in this hashtable.
141
+     */
142
+    public int size() {
143
+        return count;
144
+    }
145
+
146
+    /**
147
+     * <p>Tests if this hashtable maps no keys to values.</p>
148
+     *
149
+     * @return  <code>true</code> if this hashtable maps no keys to values;
150
+     *          <code>false</code> otherwise.
151
+     */
152
+    public boolean isEmpty() {
153
+        return count == 0;
154
+    }
155
+
156
+    /**
157
+     * <p>Tests if some key maps into the specified value in this hashtable.
158
+     * This operation is more expensive than the <code>containsKey</code>
159
+     * method.</p>
160
+     *
161
+     * <p>Note that this method is identical in functionality to containsValue,
162
+     * (which is part of the Map interface in the collections framework).</p>
163
+     *
164
+     * @param      value   a value to search for.
165
+     * @return     <code>true</code> if and only if some key maps to the
166
+     *             <code>value</code> argument in this hashtable as
167
+     *             determined by the <tt>equals</tt> method;
168
+     *             <code>false</code> otherwise.
169
+     * @throws  NullPointerException  if the value is <code>null</code>.
170
+     * @see        #containsKey(int)
171
+     * @see        #containsValue(Object)
172
+     * @see        java.util.Map
173
+     */
174
+    public boolean contains(Object value) {
175
+        if (value == null) {
176
+            throw new NullPointerException();
177
+        }
178
+
179
+        Entry tab[] = table;
180
+        for (int i = tab.length; i-- > 0;) {
181
+            for (Entry e = tab[i]; e != null; e = e.next) {
182
+                if (e.value.equals(value)) {
183
+                    return true;
184
+                }
185
+            }
186
+        }
187
+        return false;
188
+    }
189
+
190
+    /**
191
+     * <p>Returns <code>true</code> if this HashMap maps one or more keys
192
+     * to this value.</p>
193
+     *
194
+     * <p>Note that this method is identical in functionality to contains
195
+     * (which predates the Map interface).</p>
196
+     *
197
+     * @param value value whose presence in this HashMap is to be tested.
198
+     * @return boolean <code>true</code> if the value is contained
199
+     * @see    java.util.Map
200
+     * @since JDK1.2
201
+     */
202
+    public boolean containsValue(Object value) {
203
+        return contains(value);
204
+    }
205
+
206
+    /**
207
+     * <p>Tests if the specified object is a key in this hashtable.</p>
208
+     *
209
+     * @param  key  possible key.
210
+     * @return <code>true</code> if and only if the specified object is a
211
+     *    key in this hashtable, as determined by the <tt>equals</tt>
212
+     *    method; <code>false</code> otherwise.
213
+     * @see #contains(Object)
214
+     */
215
+    public boolean containsKey(int key) {
216
+        Entry tab[] = table;
217
+        int hash = key;
218
+        int index = (hash & 0x7FFFFFFF) % tab.length;
219
+        for (Entry e = tab[index]; e != null; e = e.next) {
220
+            if (e.hash == hash) {
221
+                return true;
222
+            }
223
+        }
224
+        return false;
225
+    }
226
+
227
+    /**
228
+     * <p>Returns the value to which the specified key is mapped in this map.</p>
229
+     *
230
+     * @param   key   a key in the hashtable.
231
+     * @return  the value to which the key is mapped in this hashtable;
232
+     *          <code>null</code> if the key is not mapped to any value in
233
+     *          this hashtable.
234
+     * @see     #put(int, Object)
235
+     */
236
+    public Object get(int key) {
237
+        Entry tab[] = table;
238
+        int hash = key;
239
+        int index = (hash & 0x7FFFFFFF) % tab.length;
240
+        for (Entry e = tab[index]; e != null; e = e.next) {
241
+            if (e.hash == hash) {
242
+                return e.value;
243
+            }
244
+        }
245
+        return null;
246
+    }
247
+
248
+    /**
249
+     * <p>Increases the capacity of and internally reorganizes this
250
+     * hashtable, in order to accommodate and access its entries more
251
+     * efficiently.</p>
252
+     *
253
+     * <p>This method is called automatically when the number of keys
254
+     * in the hashtable exceeds this hashtable's capacity and load
255
+     * factor.</p>
256
+     */
257
+    protected void rehash() {
258
+        int oldCapacity = table.length;
259
+        Entry oldMap[] = table;
260
+
261
+        int newCapacity = oldCapacity * 2 + 1;
262
+        Entry newMap[] = new Entry[newCapacity];
263
+
264
+        threshold = (int) (newCapacity * loadFactor);
265
+        table = newMap;
266
+
267
+        for (int i = oldCapacity; i-- > 0;) {
268
+            for (Entry old = oldMap[i]; old != null;) {
269
+                Entry e = old;
270
+                old = old.next;
271
+
272
+                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
273
+                e.next = newMap[index];
274
+                newMap[index] = e;
275
+            }
276
+        }
277
+    }
278
+
279
+    /**
280
+     * <p>Maps the specified <code>key</code> to the specified
281
+     * <code>value</code> in this hashtable. The key cannot be
282
+     * <code>null</code>. </p>
283
+     *
284
+     * <p>The value can be retrieved by calling the <code>get</code> method
285
+     * with a key that is equal to the original key.</p>
286
+     *
287
+     * @param key     the hashtable key.
288
+     * @param value   the value.
289
+     * @return the previous value of the specified key in this hashtable,
290
+     *         or <code>null</code> if it did not have one.
291
+     * @throws  NullPointerException  if the key is <code>null</code>.
292
+     * @see     #get(int)
293
+     */
294
+    public Object put(int key, Object value) {
295
+        // Makes sure the key is not already in the hashtable.
296
+        Entry tab[] = table;
297
+        int hash = key;
298
+        int index = (hash & 0x7FFFFFFF) % tab.length;
299
+        for (Entry e = tab[index]; e != null; e = e.next) {
300
+            if (e.hash == hash) {
301
+                Object old = e.value;
302
+                e.value = value;
303
+                return old;
304
+            }
305
+        }
306
+
307
+        if (count >= threshold) {
308
+            // Rehash the table if the threshold is exceeded
309
+            rehash();
310
+
311
+            tab = table;
312
+            index = (hash & 0x7FFFFFFF) % tab.length;
313
+        }
314
+
315
+        // Creates the new entry.
316
+        Entry e = new Entry(hash, key, value, tab[index]);
317
+        tab[index] = e;
318
+        count++;
319
+        return null;
320
+    }
321
+
322
+    /**
323
+     * <p>Removes the key (and its corresponding value) from this
324
+     * hashtable.</p>
325
+     *
326
+     * <p>This method does nothing if the key is not present in the
327
+     * hashtable.</p>
328
+     *
329
+     * @param   key   the key that needs to be removed.
330
+     * @return  the value to which the key had been mapped in this hashtable,
331
+     *          or <code>null</code> if the key did not have a mapping.
332
+     */
333
+    public Object remove(int key) {
334
+        Entry tab[] = table;
335
+        int hash = key;
336
+        int index = (hash & 0x7FFFFFFF) % tab.length;
337
+        for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next) {
338
+            if (e.hash == hash) {
339
+                if (prev != null) {
340
+                    prev.next = e.next;
341
+                } else {
342
+                    tab[index] = e.next;
343
+                }
344
+                count--;
345
+                Object oldValue = e.value;
346
+                e.value = null;
347
+                return oldValue;
348
+            }
349
+        }
350
+        return null;
351
+    }
352
+
353
+    /**
354
+     * <p>Clears this hashtable so that it contains no keys.</p>
355
+     */
356
+    public synchronized void clear() {
357
+        Entry tab[] = table;
358
+        for (int index = tab.length; --index >= 0;) {
359
+            tab[index] = null;
360
+        }
361
+        count = 0;
362
+    }
363
+    
364
+}

+ 180
- 0
src/com/dmdirc/addons/freedesktop_notifications/commons/StringEscapeUtils.java View File

@@ -0,0 +1,180 @@
1
+/*
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements.  See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License.  You may obtain a copy of the License at
8
+ * 
9
+ *      http://www.apache.org/licenses/LICENSE-2.0
10
+ * 
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+package com.dmdirc.addons.freedesktop_notifications.commons;
18
+
19
+import java.io.IOException;
20
+import java.io.StringWriter;
21
+import java.io.Writer;
22
+import java.util.Locale;
23
+
24
+/**
25
+ * <p>Escapes and unescapes <code>String</code>s for
26
+ * Java, Java Script, HTML, XML, and SQL.</p>
27
+ *
28
+ * @author Apache Jakarta Turbine
29
+ * @author Purple Technology
30
+ * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
31
+ * @author Antony Riley
32
+ * @author Helge Tesgaard
33
+ * @author <a href="sean@boohai.com">Sean Brown</a>
34
+ * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
35
+ * @author Phil Steitz
36
+ * @author Pete Gieser
37
+ * @since 2.0
38
+ * @version $Id$
39
+ */
40
+public class StringEscapeUtils {
41
+    // HTML and XML
42
+    //--------------------------------------------------------------------------
43
+    /**
44
+     * <p>Escapes the characters in a <code>String</code> using HTML entities.</p>
45
+     *
46
+     * <p>
47
+     * For example:
48
+     * </p> 
49
+     * <p><code>"bread" & "butter"</code></p>
50
+     * becomes:
51
+     * <p>
52
+     * <code>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</code>.
53
+     * </p>
54
+     *
55
+     * <p>Supports all known HTML 4.0 entities, including funky accents.
56
+     * Note that the commonly used apostrophe escape character (&amp;apos;)
57
+     * is not a legal entity and so is not supported). </p>
58
+     *
59
+     * @param str  the <code>String</code> to escape, may be null
60
+     * @return a new escaped <code>String</code>, <code>null</code> if null string input
61
+     * 
62
+     * @see #unescapeHtml(String)
63
+     * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
64
+     * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
65
+     * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
66
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
67
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
68
+     */
69
+    public static String escapeHtml(String str) {
70
+        if (str == null) {
71
+            return null;
72
+        }
73
+        try {
74
+            StringWriter writer = new StringWriter ((int)(str.length() * 1.5));
75
+            escapeHtml(writer, str);
76
+            return writer.toString();
77
+        } catch (IOException ioe) {
78
+            //should be impossible
79
+            throw new UnhandledException(ioe);
80
+        }
81
+    }
82
+
83
+    /**
84
+     * <p>Escapes the characters in a <code>String</code> using HTML entities and writes
85
+     * them to a <code>Writer</code>.</p>
86
+     *
87
+     * <p>
88
+     * For example:
89
+     * </p> 
90
+     * <code>"bread" & "butter"</code>
91
+     * <p>becomes:</p>
92
+     * <code>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</code>.
93
+     *
94
+     * <p>Supports all known HTML 4.0 entities, including funky accents.
95
+     * Note that the commonly used apostrophe escape character (&amp;apos;)
96
+     * is not a legal entity and so is not supported). </p>
97
+     *
98
+     * @param writer  the writer receiving the escaped string, not null
99
+     * @param string  the <code>String</code> to escape, may be null
100
+     * @throws IllegalArgumentException if the writer is null
101
+     * @throws IOException when <code>Writer</code> passed throws the exception from
102
+     *                                       calls to the {@link Writer#write(int)} methods.
103
+     * 
104
+     * @see #escapeHtml(String)
105
+     * @see #unescapeHtml(String)
106
+     * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
107
+     * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
108
+     * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
109
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
110
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
111
+     */
112
+    public static void escapeHtml(Writer writer, String string) throws IOException {
113
+        if (writer == null ) {
114
+            throw new IllegalArgumentException ("The Writer must not be null.");
115
+        }
116
+        if (string == null) {
117
+            return;
118
+        }
119
+        Entities.HTML40.escape(writer, string);
120
+    }
121
+
122
+    //-----------------------------------------------------------------------
123
+    /**
124
+     * <p>Unescapes a string containing entity escapes to a string
125
+     * containing the actual Unicode characters corresponding to the
126
+     * escapes. Supports HTML 4.0 entities.</p>
127
+     *
128
+     * <p>For example, the string "&amp;lt;Fran&amp;ccedil;ais&amp;gt;"
129
+     * will become "&lt;Fran&ccedil;ais&gt;"</p>
130
+     *
131
+     * <p>If an entity is unrecognized, it is left alone, and inserted
132
+     * verbatim into the result string. e.g. "&amp;gt;&amp;zzzz;x" will
133
+     * become "&gt;&amp;zzzz;x".</p>
134
+     *
135
+     * @param str  the <code>String</code> to unescape, may be null
136
+     * @return a new unescaped <code>String</code>, <code>null</code> if null string input
137
+     * @see #escapeHtml(Writer, String)
138
+     */
139
+    public static String unescapeHtml(String str) {
140
+        if (str == null) {
141
+            return null;
142
+        }
143
+        try {
144
+            StringWriter writer = new StringWriter ((int)(str.length() * 1.5));
145
+            unescapeHtml(writer, str);
146
+            return writer.toString();
147
+        } catch (IOException ioe) {
148
+            //should be impossible
149
+            throw new UnhandledException(ioe);
150
+        }
151
+    }
152
+
153
+    /**
154
+     * <p>Unescapes a string containing entity escapes to a string
155
+     * containing the actual Unicode characters corresponding to the
156
+     * escapes. Supports HTML 4.0 entities.</p>
157
+     *
158
+     * <p>For example, the string "&amp;lt;Fran&amp;ccedil;ais&amp;gt;"
159
+     * will become "&lt;Fran&ccedil;ais&gt;"</p>
160
+     *
161
+     * <p>If an entity is unrecognized, it is left alone, and inserted
162
+     * verbatim into the result string. e.g. "&amp;gt;&amp;zzzz;x" will
163
+     * become "&gt;&amp;zzzz;x".</p>
164
+     *
165
+     * @param writer  the writer receiving the unescaped string, not null
166
+     * @param string  the <code>String</code> to unescape, may be null
167
+     * @throws IllegalArgumentException if the writer is null
168
+     * @throws IOException if an IOException occurs
169
+     * @see #escapeHtml(String)
170
+     */
171
+    public static void unescapeHtml(Writer writer, String string) throws IOException {
172
+        if (writer == null ) {
173
+            throw new IllegalArgumentException ("The Writer must not be null.");
174
+        }
175
+        if (string == null) {
176
+            return;
177
+        }
178
+        Entities.HTML40.unescape(writer, string);
179
+    }
180
+}

+ 71
- 0
src/com/dmdirc/addons/freedesktop_notifications/commons/UnhandledException.java View File

@@ -0,0 +1,71 @@
1
+/*
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements.  See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License.  You may obtain a copy of the License at
8
+ * 
9
+ *      http://www.apache.org/licenses/LICENSE-2.0
10
+ * 
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+package com.dmdirc.addons.freedesktop_notifications.commons;
18
+
19
+/**
20
+ * <p>Thrown when it is impossible or undesirable to consume or throw a checked exception.</p>
21
+ * This exception supplements the standard exception classes by providing a more
22
+ * semantically rich description of the problem.</p>
23
+ * 
24
+ * <p><code>UnhandledException</code> represents the case where a method has to deal
25
+ * with a checked exception but does not wish to.
26
+ * Instead, the checked exception is rethrown in this unchecked wrapper.</p>
27
+ * 
28
+ * <pre>
29
+ * public void foo() {
30
+ *   try {
31
+ *     // do something that throws IOException
32
+ *   } catch (IOException ex) {
33
+ *     // don't want to or can't throw IOException from foo()
34
+ *     throw new UnhandledException(ex);
35
+ *   }
36
+ * }
37
+ * </pre>
38
+ *
39
+ * @author Matthew Hawthorne
40
+ * @since 2.0
41
+ * @version $Id$
42
+ */
43
+public class UnhandledException extends RuntimeException {
44
+
45
+    /**
46
+     * Required for serialization support.
47
+     * 
48
+     * @see java.io.Serializable
49
+     */
50
+    private static final long serialVersionUID = 1832101364842773720L;
51
+
52
+    /**
53
+     * Constructs the exception using a cause.
54
+     *
55
+     * @param cause  the underlying cause
56
+     */
57
+    public UnhandledException(Throwable cause) {
58
+        super(cause);
59
+    }
60
+
61
+    /**
62
+     * Constructs the exception using a message and cause.
63
+     *
64
+     * @param message  the message to use
65
+     * @param cause  the underlying cause
66
+     */
67
+    public UnhandledException(String message, Throwable cause) {
68
+        super(message, cause);
69
+    }
70
+
71
+}

BIN
src/com/dmdirc/addons/freedesktop_notifications/files/icon.png View File


+ 93
- 0
src/com/dmdirc/addons/freedesktop_notifications/files/notify.py View File

@@ -0,0 +1,93 @@
1
+#!/usr/bin/python
2
+# -*- coding: utf-8 -*-
3
+
4
+# Default Configuration (will be overridden by cmd line arguments)
5
+APPLICATION    = ''        # name of the calling application (will be shown if now summary is available)
6
+SUMMARY        = ''
7
+BODY        = ''
8
+ICON        = 'preferences-desktop-notification'
9
+TIMEOUT        = 2000        # 0 means, never hide the message; value greater than 0 is the time in ms the message is shown
10
+
11
+import sys
12
+import getopt
13
+import dbus
14
+
15
+def main():
16
+    dbus = DBus()
17
+    args = CmdLine(sys.argv[1:])
18
+    dbus.notify(app_name=args.getApplication(), app_icon=args.getIcon(), summary=args.getSummary(), body=args.getBody(), timeout=args.getTime())
19
+
20
+class CmdLine():
21
+    def __init__(self, argv):
22
+        try:
23
+            opts, args = getopt.getopt(argv, 'hs:a:i:t:', ['help', 'summary=', 'app=', 'icon=', 'time='])
24
+        except getopt.GetoptError:
25
+            usage()
26
+            sys.exit(2)
27
+
28
+        for opt, arg in opts:
29
+            if opt in ('-h', '--help'):
30
+                usage()
31
+                sys.exit()
32
+            elif opt in ('-s', '--summary'):
33
+                self.__summary = arg
34
+            elif opt in ('-a', '--app'):
35
+                self.__app = arg
36
+            elif opt in ('-i', '--icon'):
37
+                self.__icon = arg
38
+            elif opt in ('-t', '--time'):
39
+                self.__time = arg
40
+
41
+        if len(args) > 0:
42
+            self.__body = ' '.join(args)
43
+
44
+    def getApplication(self):
45
+        try:
46
+            return self.__app
47
+        except AttributeError:
48
+            return APPLICATION
49
+
50
+    def getSummary(self):
51
+        try:
52
+            return self.__summary
53
+        except AttributeError:
54
+            return SUMMARY
55
+
56
+    def getBody(self):
57
+        try:
58
+            return self.__body
59
+        except AttributeError:
60
+            return BODY
61
+
62
+    def getIcon(self):
63
+        try:
64
+            return self.__icon
65
+        except AttributeError:
66
+            return ICON
67
+
68
+    def getTime(self):
69
+        try:
70
+            return int(self.__time)
71
+        except ValueError:
72
+            return TIMEOUT
73
+        except AttributeError:
74
+            return TIMEOUT
75
+
76
+def usage():
77
+    """print usage message"""
78
+    print 'Usage: notify.py [-a|--app=<application>] [-i|--icon=<icon name or path>] [-t|--time=<time>] [-s|--summary=<summary>] [<message>]'
79
+
80
+class DBus():
81
+    """Wrapper class for notify daemon dbus interface"""
82
+
83
+    def __init__(self):
84
+        self.__notify = dbus.SessionBus().get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications')
85
+    
86
+    def notify(self, app_name='', replaces_id=dbus.UInt32(), event_id='', app_icon='', summary='', body='', actions=dbus.Array(signature='s'), hints=dbus.Dictionary(signature='sv'), timeout=0):
87
+        print self.__notify.Notify(app_name, replaces_id, app_icon, summary, body, actions, hints, timeout)
88
+
89
+    def closeNotification(self, event_id):
90
+        self.__notify.CloseNotification(event_id)
91
+
92
+if __name__ == "__main__":
93
+    main();

+ 175
- 0
src/com/dmdirc/addons/freedesktop_notifications/licences/Apache Commons - ASF 2.0 View File

@@ -0,0 +1,175 @@
1
+The Freedesktop Notifications plugin makes use of part of the Apache
2
+Commons library, which is licensed under the Apache Software Foundation
3
+License Version 2, the full text of which is included below.
4
+
5
+----------
6
+
7
+Licensed to the Apache Software Foundation (ASF) under one or more
8
+contributor license agreements.  See the NOTICE file distributed with
9
+this work for additional information regarding copyright ownership.
10
+The ASF licenses this file to You under the Apache License, Version 2.0
11
+(the "License"); you may not use this file except in compliance with
12
+the License.  You may obtain a copy of the License at
13
+
14
+     http://www.apache.org/licenses/LICENSE-2.0 (See Below)
15
+
16
+Unless required by applicable law or agreed to in writing, software
17
+distributed under the License is distributed on an "AS IS" BASIS,
18
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+See the License for the specific language governing permissions and
20
+limitations under the License.
21
+
22
+----------
23
+
24
+1. Definitions.
25
+
26
+"License" shall mean the terms and conditions for use, reproduction, and 
27
+distribution as defined by Sections 1 through 9 of this document.
28
+
29
+"Licensor" shall mean the copyright owner or entity authorized by the copyright 
30
+owner that is granting the License.
31
+
32
+"Legal Entity" shall mean the union of the acting entity and all other entities 
33
+that control, are controlled by, or are under common control with that entity. 
34
+For the purposes of this definition, "control" means (i) the power, direct or 
35
+indirect, to cause the direction or management of such entity, whether by 
36
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 
37
+outstanding shares, or (iii) beneficial ownership of such entity.
38
+
39
+"You" (or "Your") shall mean an individual or Legal Entity exercising 
40
+permissions granted by this License.
41
+
42
+"Source" form shall mean the preferred form for making modifications, including 
43
+but not limited to software source code, documentation source, and 
44
+configuration files.
45
+
46
+"Object" form shall mean any form resulting from mechanical transformation or 
47
+translation of a Source form, including but not limited to compiled object 
48
+code, generated documentation, and conversions to other media types.
49
+
50
+"Work" shall mean the work of authorship, whether in Source or Object form, 
51
+made available under the License, as indicated by a copyright notice that is 
52
+included in or attached to the work (an example is provided in the Appendix 
53
+below).
54
+
55
+"Derivative Works" shall mean any work, whether in Source or Object form, that 
56
+is based on (or derived from) the Work and for which the editorial revisions, 
57
+annotations, elaborations, or other modifications represent, as a whole, an 
58
+original work of authorship. For the purposes of this License, Derivative Works 
59
+shall not include works that remain separable from, or merely link (or bind by 
60
+name) to the interfaces of, the Work and Derivative Works thereof.
61
+
62
+"Contribution" shall mean any work of authorship, including the original 
63
+version of the Work and any modifications or additions to that Work or 
64
+Derivative Works thereof, that is intentionally submitted to Licensor for 
65
+inclusion in the Work by the copyright owner or by an individual or Legal 
66
+Entity authorized to submit on behalf of the copyright owner. For the purposes 
67
+of this definition, "submitted" means any form of electronic, verbal, or 
68
+written communication sent to the Licensor or its representatives, including 
69
+but not limited to communication on electronic mailing lists, source code 
70
+control systems, and issue tracking systems that are managed by, or on behalf 
71
+of, the Licensor for the purpose of discussing and improving the Work, but 
72
+excluding communication that is conspicuously marked or otherwise designated in 
73
+writing by the copyright owner as "Not a Contribution."
74
+
75
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf 
76
+of whom a Contribution has been received by Licensor and subsequently 
77
+incorporated within the Work.
78
+
79
+2. Grant of Copyright License. Subject to the terms and conditions of this 
80
+License, each Contributor hereby grants to You a perpetual, worldwide, 
81
+non-exclusive, no-charge, royalty-free, irrevocable copyright license to 
82
+reproduce, prepare Derivative Works of, publicly display, publicly perform, 
83
+sublicense, and distribute the Work and such Derivative Works in Source or 
84
+Object form.
85
+
86
+3. Grant of Patent License. Subject to the terms and conditions of this 
87
+License, each Contributor hereby grants to You a perpetual, worldwide, 
88
+non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this 
89
+section) patent license to make, have made, use, offer to sell, sell, import, 
90
+and otherwise transfer the Work, where such license applies only to those 
91
+patent claims licensable by such Contributor that are necessarily infringed by 
92
+their Contribution(s) alone or by combination of their Contribution(s) with the 
93
+Work to which such Contribution(s) was submitted. If You institute patent 
94
+litigation against any entity (including a cross-claim or counterclaim in a 
95
+lawsuit) alleging that the Work or a Contribution incorporated within the Work 
96
+constitutes direct or contributory patent infringement, then any patent 
97
+licenses granted to You under this License for that Work shall terminate as of 
98
+the date such litigation is filed.
99
+
100
+4. Redistribution. You may reproduce and distribute copies of the Work or 
101
+Derivative Works thereof in any medium, with or without modifications, and in 
102
+Source or Object form, provided that You meet the following conditions:
103
+
104
+   1. You must give any other recipients of the Work or Derivative Works a copy 
105
+of this License; and
106
+
107
+   2. You must cause any modified files to carry prominent notices stating that 
108
+You changed the files; and
109
+
110
+   3. You must retain, in the Source form of any Derivative Works that You 
111
+distribute, all copyright, patent, trademark, and attribution notices from the 
112
+Source form of the Work, excluding those notices that do not pertain to any 
113
+part of the Derivative Works; and
114
+
115
+   4. If the Work includes a "NOTICE" text file as part of its distribution, 
116
+then any Derivative Works that You distribute must include a readable copy of 
117
+the attribution notices contained within such NOTICE file, excluding those 
118
+notices that do not pertain to any part of the Derivative Works, in at least 
119
+one of the following places: within a NOTICE text file distributed as part of 
120
+the Derivative Works; within the Source form or documentation, if provided 
121
+along with the Derivative Works; or, within a display generated by the 
122
+Derivative Works, if and wherever such third-party notices normally appear. The 
123
+contents of the NOTICE file are for informational purposes only and do not 
124
+modify the License. You may add Your own attribution notices within Derivative 
125
+Works that You distribute, alongside or as an addendum to the NOTICE text from 
126
+the Work, provided that such additional attribution notices cannot be construed 
127
+as modifying the License.
128
+
129
+You may add Your own copyright statement to Your modifications and may provide 
130
+additional or different license terms and conditions for use, reproduction, or 
131
+distribution of Your modifications, or for any such Derivative Works as a 
132
+whole, provided Your use, reproduction, and distribution of the Work otherwise 
133
+complies with the conditions stated in this License.
134
+
135
+5. Submission of Contributions. Unless You explicitly state otherwise, any 
136
+Contribution intentionally submitted for inclusion in the Work by You to the 
137
+Licensor shall be under the terms and conditions of this License, without any 
138
+additional terms or conditions. Notwithstanding the above, nothing herein shall 
139
+supersede or modify the terms of any separate license agreement you may have 
140
+executed with Licensor regarding such Contributions.
141
+
142
+6. Trademarks. This License does not grant permission to use the trade names, 
143
+trademarks, service marks, or product names of the Licensor, except as required 
144
+for reasonable and customary use in describing the origin of the Work and 
145
+reproducing the content of the NOTICE file.
146
+
147
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in 
148
+writing, Licensor provides the Work (and each Contributor provides its 
149
+Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
150
+KIND, either express or implied, including, without limitation, any warranties 
151
+or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 
152
+PARTICULAR PURPOSE. You are solely responsible for determining the 
153
+appropriateness of using or redistributing the Work and assume any risks 
154
+associated with Your exercise of permissions under this License.
155
+
156
+8. Limitation of Liability. In no event and under no legal theory, whether in 
157
+tort (including negligence), contract, or otherwise, unless required by 
158
+applicable law (such as deliberate and grossly negligent acts) or agreed to in 
159
+writing, shall any Contributor be liable to You for damages, including any 
160
+direct, indirect, special, incidental, or consequential damages of any 
161
+character arising as a result of this License or out of the use or inability to 
162
+use the Work (including but not limited to damages for loss of goodwill, work 
163
+stoppage, computer failure or malfunction, or any and all other commercial 
164
+damages or losses), even if such Contributor has been advised of the 
165
+possibility of such damages.
166
+
167
+9. Accepting Warranty or Additional Liability. While redistributing the Work or 
168
+Derivative Works thereof, You may choose to offer, and charge a fee for, 
169
+acceptance of support, warranty, indemnity, or other liability obligations 
170
+and/or rights consistent with this License. However, in accepting such 
171
+obligations, You may act only on Your own behalf and on Your sole 
172
+responsibility, not on behalf of any other Contributor, and only if You agree 
173
+to indemnify, defend, and hold each Contributor harmless for any liability 
174
+incurred by, or claims asserted against, such Contributor by reason of your 
175
+accepting any such warranty or additional liability. 

+ 46
- 0
src/com/dmdirc/addons/freedesktop_notifications/plugin.config View File

@@ -0,0 +1,46 @@
1
+# This is a DMDirc configuration file.
2
+
3
+# This section indicates which sections below take key/value
4
+# pairs, rather than a simple list. It should be placed above
5
+# any sections that take key/values.
6
+keysections:
7
+  metadata
8
+  requires
9
+  updates
10
+  defaults
11
+  formatters
12
+  icons
13
+  version
14
+
15
+metadata:
16
+  author=Shane <shane@dmdirc.com>
17
+  mainclass=com.dmdirc.addons.freedesktop_notifications.FreeDesktopNotificationsPlugin
18
+  description=Adds FreeDesktop-Style Notifications to dmdirc
19
+  name=freedesktop_notifications
20
+  nicename=FreeDesktop Notifications Plugin
21
+
22
+updates:
23
+  id=48
24
+
25
+version:
26
+  number=8
27
+  friendly=0.8
28
+
29
+defaults:
30
+    general.hideoutput=false
31
+
32
+requires:
33
+#    linux os
34
+
35
+provides:
36
+  osd feature
37
+
38
+defaults:
39
+  general.timeout=5
40
+  general.kdialog=false
41
+  advanced.escapehtml=true
42
+  advanced.strictescape=true
43
+  advanced.stripcodes=true
44
+
45
+exports:
46
+  showNotification in com.dmdirc.addons.freedesktop_notifications.FreeDesktopNotificationsPlugin as showNotification

Loading…
Cancel
Save