Merge lp:~gabor-karsay/awn-extras/comics into lp:awn-extras

Proposed by Gabor Karsay
Status: Merged
Merged at revision: 1494
Proposed branch: lp:~gabor-karsay/awn-extras/comics
Merge into: lp:awn-extras
Diff against target: 3450 lines (+1084/-1555) (has conflicts)
43 files modified
applets/maintained/comics/Makefile.am (+3/-0)
applets/maintained/comics/comics.py (+78/-30)
applets/maintained/comics/comics_add.py (+150/-34)
applets/maintained/comics/comics_manage.py (+87/-45)
applets/maintained/comics/comics_view.py (+123/-84)
applets/maintained/comics/feed/__init__.py (+9/-8)
applets/maintained/comics/feed/basic.py (+94/-13)
applets/maintained/comics/feed/plugins/__init__.py (+18/-0)
applets/maintained/comics/feed/plugins/simple_screen_scraper.py (+112/-0)
applets/maintained/comics/feed/rss.py (+2/-2)
applets/maintained/comics/feeds/ben.feed (+7/-0)
applets/maintained/comics/feeds/buttersafe.feed (+3/-3)
applets/maintained/comics/feeds/calvinandhobbes.feed (+6/-0)
applets/maintained/comics/feeds/ferdnand.feed (+7/-0)
applets/maintained/comics/feeds/garfield.feed (+6/-0)
applets/maintained/comics/feeds/nancy.feed (+7/-0)
applets/maintained/comics/feeds/pcnp.feed (+7/-0)
applets/maintained/comics/feeds/peanuts.feed (+0/-2)
applets/maintained/comics/feeds/pearls.feed (+7/-5)
applets/maintained/comics/feeds/pickles.feed (+6/-0)
applets/maintained/comics/feeds/userfriendly.feed (+7/-0)
applets/maintained/comics/feeds/wizardofid.feed (+6/-3)
applets/maintained/comics/ui/add.ui (+281/-57)
applets/maintained/comics/ui/manage.ui (+58/-32)
applets/maintained/comics/ui/view.ui (+0/-154)
applets/unmaintained/comic/Makefile.am (+0/-24)
applets/unmaintained/comic/comic.desktop.in (+0/-11)
applets/unmaintained/comic/comic.py (+0/-226)
applets/unmaintained/comic/comicdialog.py (+0/-46)
applets/unmaintained/comic/getben.py (+0/-75)
applets/unmaintained/comic/getborn.py (+0/-75)
applets/unmaintained/comic/getdilbert.py (+0/-75)
applets/unmaintained/comic/getferdnand.py (+0/-75)
applets/unmaintained/comic/getgarfield.py (+0/-56)
applets/unmaintained/comic/getnancy.py (+0/-75)
applets/unmaintained/comic/getpcnp.py (+0/-75)
applets/unmaintained/comic/getpeanuts.py (+0/-75)
applets/unmaintained/comic/getpickles.py (+0/-75)
applets/unmaintained/comic/getwiz.py (+0/-75)
applets/unmaintained/comic/getxkcd.py (+0/-40)
debian/awn-applets-python-extras-trunk.install (+0/-3)
po/POTFILES.in (+0/-1)
po/POTFILES.skip (+0/-1)
Conflict: can't delete applets/unmaintained/comic because it is not empty.  Not deleting.
Conflict because applets/unmaintained/comic is not versioned, but has versioned children.  Versioned directory.
Contents conflict in applets/unmaintained/comic/getuf.py
To merge this branch: bzr merge lp:~gabor-karsay/awn-extras/comics
Reviewer Review Type Date Requested Status
Awn Extras Developers Pending
Review via email: mp+43374@code.launchpad.net

This proposal supersedes a proposal from 2010-10-11.

Description of the change

This brunch adds a plugin to Comics! applet, the SimpleScreenScraper. It indexes images on a web page, lets the user decide which one contains the comic and then shows this image by its index. No previous strips shown, just the one actually at display. This plugin is always used when there is no feed available.

All comics from old comic applet are included, except for "Born loser" – the URL doesn't exist anymore. The old applet is removed from source tree. Note that while the old comics can be viewed, the ones without a feed have less functionality: no going back in history; and showing a higher resolution strip isn't supported either.

The context menu changed: There is only one item "My comics" instead of the 2 items "Comics" and "Manage Comics". There are no "common" comics anymore (preinstalled comics that couldn't be removed).

Adding a comic can be done in two ways: selecting from a list of preconfigured comics or by adding an URL.

Restored the context menu for the strips (a regression at porting to 0.4)

Added an about window.

Fixes two rare crashes (admittedly I don't know the reason for one of them, bug #356334 , the crash is avoided in rev. 1432)

To post a comment you must log in.
Revision history for this message
Gabor Karsay (gabor-karsay) wrote : Posted in a previous version of this proposal

Argh, gocomics.com was o.k. last week, now they apparently changed something with the feed and it doesn't work anymore. The old feeds are not shown, new ones can't be added.

review: Needs Fixing
Revision history for this message
onox (onox) wrote : Posted in a previous version of this proposal

I'm not sure about the preinstalled comics. Best thing would be that the user could retrieve a list of comics (fetching the data from comics.com or some other website) and then choose which he/she would like to add. This way we can also avoid those "feature" requests from random users who want to see some random comic that nobody reads getting added :p

Revision history for this message
Gabor Karsay (gabor-karsay) wrote : Posted in a previous version of this proposal

Fixed the change in gocomics' feeds and a change in glade-3.

Referring to the preinstalled comics: I can't see a way to retrieve a list of comics automatically from gocomics.com (neither from comics.com, which requires registration and has very strict terms of use). So we'd probably have to create this list and maintain it ourselves - and that would be the same as preinstalling some of them (the user can still decide whether these comics are shown or not).

Actually users can add comics using the assistant. They only have to know the URL of the feed and then select the image showing the comic. It's as easy as copy & paste a backtrace to a bug report. That means: it might be way too difficult for some users ;-) That's why we have some preinstalled comics.

I agree that some of the preinstalled comics are not suited for a wide audience. I'm inclined to remove buttersafe and explosm because they are sort of weird. gocomics.com can sort its comics by popularity. I added Calvin & Hobbes because it's the most popular comic, Garfield is #3. wulffmorgenthaler was a user request, it is regularly updated and I like it (but some strips may be not suitable for children, lets say aged 12 or less).

review: Needs Resubmitting
Revision history for this message
onox (onox) wrote : Posted in a previous version of this proposal

Imho a -1 for Explosm and wulffmorgenthaler

Gabor, if you could fix lp bug #547154 in this branch, you would make moonbeam very happy :)

Revision history for this message
onox (onox) wrote : Posted in a previous version of this proposal

Oh, and +1 for removing old comic applet.

Revision history for this message
Gabor Karsay (gabor-karsay) wrote : Posted in a previous version of this proposal

I'll have a look at that bug, might take some time.

Revision history for this message
Gabor Karsay (gabor-karsay) wrote :

No comments? I'll merge this weekend then.

Revision history for this message
moonbeam (rcryderman) wrote :

Sounds good.

lp:~gabor-karsay/awn-extras/comics updated
1460. By Gabor Karsay

Update comics: Pearls before Swine new URL (old one not updated), gocomics.com changed image index

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'applets/maintained/comics/Makefile.am'
--- applets/maintained/comics/Makefile.am 2010-01-26 03:46:15 +0000
+++ applets/maintained/comics/Makefile.am 2011-01-09 09:07:16 +0000
@@ -27,6 +27,9 @@
27feedsdir = $(applet_datadir)/feeds27feedsdir = $(applet_datadir)/feeds
28dist_feeds_DATA = $(wildcard feeds/*.feed)28dist_feeds_DATA = $(wildcard feeds/*.feed)
2929
30pluginsdir = $(applet_datadir)/feed/plugins
31dist_plugins_DATA = $(wildcard feed/plugins/*.py)
32
30uidir = $(applet_datadir)/ui33uidir = $(applet_datadir)/ui
31dist_ui_DATA = \34dist_ui_DATA = \
32 $(wildcard ui/*.svg) \35 $(wildcard ui/*.svg) \
3336
=== modified file 'applets/maintained/comics/comics.py'
--- applets/maintained/comics/comics.py 2010-09-10 01:21:59 +0000
+++ applets/maintained/comics/comics.py 2011-01-09 09:07:16 +0000
@@ -27,7 +27,7 @@
27import os27import os
28import sys28import sys
29import tempfile29import tempfile
30from awn.extras import _30from awn.extras import _, awnlib
3131
32# Import Comics! modules, but check dependencies first32# Import Comics! modules, but check dependencies first
33awn.check_dependencies(globals(), 'feedparser', 'pynotify')33awn.check_dependencies(globals(), 'feedparser', 'pynotify')
@@ -35,6 +35,7 @@
3535
36import comics_manage36import comics_manage
37import comics_view37import comics_view
38from comics_add import ComicsAdder
38from feed.settings import Settings39from feed.settings import Settings
39from feed import FeedContainer40from feed import FeedContainer
40from shared import (41from shared import (
@@ -42,6 +43,8 @@
42 USER_DIR, USER_FEEDS_DIR)43 USER_DIR, USER_FEEDS_DIR)
4344
44APPLET_NAME = 'comics'45APPLET_NAME = 'comics'
46applet_display_name = _('Comics!')
47applet_icon = os.path.join(ICONS_DIR, 'comics-icon.svg')
4548
4649
47class BidirectionalIterator:50class BidirectionalIterator:
@@ -79,6 +82,38 @@
79 return self.sequence[self.index]82 return self.sequence[self.index]
8083
8184
85class about_dialog(gtk.AboutDialog):
86 def __init__(self):
87 super(about_dialog, self).__init__()
88 pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(applet_icon, 48, 48)
89 self.set_name(applet_display_name)
90 self.set_copyright('Copyright \xc2\xa9 2008 Moses Palmér')
91 self.set_authors(['Moses Palmér',
92 'Sharkbaitbobby',
93 'Mark Lee',
94 'Kyle L. Huff',
95 'Gabor Karsay'])
96 self.set_artists(['Moses Palmér'])
97 self.set_comments(_("View your favourite comics on your desktop"))
98 self.set_license("This program is free software; you can " + \
99 "redistribute it and/or modify it under the terms of the GNU " + \
100 "General Public License as published by the Free Software " + \
101 "Foundation; either version 2 of the License, or (at your " + \
102 "option) any later version.\n\n" + \
103 "This program is distributed in the hope that it will be " + \
104 "useful, but WITHOUT ANY WARRANTY; without even the implied " + \
105 "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR " + \
106 "PURPOSE. See the GNU General Public License for more " + \
107 "details.\n\nYou should have received a copy of the GNU " + \
108 "General Public License along with this program; if not, " + \
109 "write to the Free Software Foundation, Inc., 51 Franklin St, " + \
110 "Fifth Floor, Boston, MA 02110-1301, USA.")
111 self.set_wrap_license(True)
112 self.set_logo(pixbuf)
113 self.set_icon_from_file(applet_icon)
114 self.set_version(awn.extras.__version__)
115
116
82class ComicApplet(awn.AppletSimple):117class ComicApplet(awn.AppletSimple):
83 DIALOG_DURATION = 3000118 DIALOG_DURATION = 3000
84119
@@ -135,30 +170,19 @@
135 self.create_window(template=template)170 self.create_window(template=template)
136171
137 def make_menu(self):172 def make_menu(self):
138 """Generate the menu listing the comics."""173 """Generate the context menu."""
139 # Generate comics menu174 # Generate comics menu
140 menu = self.create_default_menu()175 menu = self.create_default_menu()
141 feed_menu = gtk.Menu()176 manage_item = gtk.MenuItem(_('My Comics'))
142 for feed in self.feeds.feeds:
143 label = gtk.Label()
144 label.set_markup(self.feeds.feeds[feed].name)
145 align = gtk.Alignment(xalign=0.0)
146 align.add(label)
147 menu_item = gtk.CheckMenuItem()
148 menu_item.data = feed
149 menu_item.add(align)
150 menu_item.set_active(len([w for w in self.windows
151 if w.feed_name == feed]) > 0)
152 menu_item.connect('toggled', self.on_comics_toggled)
153 feed_menu.append(menu_item)
154 feed_menu.show_all()
155 container = gtk.MenuItem(_('Comics'))
156 container.set_sensitive(len(self.feeds.feeds) > 0)
157 container.set_submenu(feed_menu)
158 menu.append(container)
159 manage_item = gtk.MenuItem(_('Manage Comics'))
160 manage_item.connect("activate", self.on_manage_comics_activated)177 manage_item.connect("activate", self.on_manage_comics_activated)
161 menu.append(manage_item)178 menu.append(manage_item)
179 about_item = gtk.ImageMenuItem(_("_About %s") % applet_display_name)
180 if awnlib.is_required_version(gtk.gtk_version, (2, 16, 0)):
181 about_item.props.always_show_image = True
182 about_item.set_image(gtk.image_new_from_stock(gtk.STOCK_ABOUT,
183 gtk.ICON_SIZE_MENU))
184 menu.append(about_item)
185 about_item.connect("activate", self.on_show_about_activated)
162 menu.show_all()186 menu.show_all()
163 return menu187 return menu
164188
@@ -176,7 +200,7 @@
176200
177 self.set_icon_name('comics-icon')201 self.set_icon_name('comics-icon')
178 # Initialise notifications202 # Initialise notifications
179 notify_init(_('Comics!'))203 notify_init(applet_display_name)
180 self.dialog = awn.Dialog(self)204 self.dialog = awn.Dialog(self)
181 self.dialog.connect('button-release-event',205 self.dialog.connect('button-release-event',
182 self.on_dialog_button_press)206 self.on_dialog_button_press)
@@ -197,6 +221,9 @@
197 self.windows = []221 self.windows = []
198 self.window_iterator = BidirectionalIterator(self.windows)222 self.window_iterator = BidirectionalIterator(self.windows)
199 self.current_window = None223 self.current_window = None
224 self.manager = None
225 self.adder = None
226 self.about = None
200227
201 try:228 try:
202 for filename in (f for f in os.listdir(STRIPS_DIR)229 for filename in (f for f in os.listdir(STRIPS_DIR)
@@ -209,24 +236,35 @@
209236
210 def on_window_updated(self, widget, title):237 def on_window_updated(self, widget, title):
211 msg = Notification(_('There is a new strip of %s!') % widget.feed_name,238 msg = Notification(_('There is a new strip of %s!') % widget.feed_name,
212 None,239 None, applet_icon)
213 os.path.join(ICONS_DIR, 'comics-icon.svg'))
214 msg.show()240 msg.show()
215241
216 def on_window_removed(self, widget):242 def on_window_removed(self, widget):
217 self.windows.remove(widget)243 self.windows.remove(widget)
244 if self.manager:
245 if self.manager.on_screen():
246 self.manager.load_feeds()
218247
219 def on_destroy(self, widget):248 def on_destroy(self, widget):
220 for window in self.windows:249 for window in self.windows:
221 window.save_settings()250 window.save_settings()
222251
223 def on_button1_pressed(self, event):252 def on_button1_pressed(self, event):
224 self.set_visibility(not self.visible)253 if len(self.feeds.feeds) == 0:
254 if self.adder and self.adder.on_screen():
255 self.adder.present()
256 else:
257 self.adder = []
258 self.adder = ComicsAdder(self)
259 elif not self.windows:
260 self.on_manage_comics_activated(None)
261 else:
262 self.set_visibility(not self.visible)
225263
226 def on_button3_pressed(self, event):264 def on_button3_pressed(self, event):
227 menu = self.make_menu()265 menu = self.make_menu()
228 if menu:266 if menu:
229 self.popup_gtk_menu (menu, event.button, event.time)267 self.popup_gtk_menu(menu, event.button, event.time)
230268
231 def on_button_press(self, widget, event):269 def on_button_press(self, widget, event):
232 if event.button == 1:270 if event.button == 1:
@@ -255,9 +293,21 @@
255 self.toggle_feed(widget.data, widget.get_active())293 self.toggle_feed(widget.data, widget.get_active())
256294
257 def on_manage_comics_activated(self, widget):295 def on_manage_comics_activated(self, widget):
258 manager = comics_manage.ComicsManager(self.feeds)296 if self.manager and self.manager.on_screen():
259 manager.show()297 self.manager.present()
298 else:
299 self.manager = []
300 self.manager = comics_manage.ComicsManager(self)
301 self.manager.show()
260302
303 def on_show_about_activated(self, widget):
304 if self.about and len(self.about) != 0:
305 self.about.present()
306 else:
307 self.about = []
308 self.about = about_dialog()
309 self.about.run()
310 self.about.destroy()
261311
262if __name__ == '__main__':312if __name__ == '__main__':
263 # Initialise threading313 # Initialise threading
@@ -274,14 +324,12 @@
274324
275 # Load the feeds325 # Load the feeds
276 feeds = FeedContainer()326 feeds = FeedContainer()
277 feeds.load_directory(SYS_FEEDS_DIR)
278 feeds.load_directory(USER_FEEDS_DIR)327 feeds.load_directory(USER_FEEDS_DIR)
279328
280 #Initialise AWN and create the applet329 #Initialise AWN and create the applet
281 awn.init(sys.argv[1:])330 awn.init(sys.argv[1:])
282 applet = ComicApplet(awn.uid, awn.panel_id, feeds)331 applet = ComicApplet(awn.uid, awn.panel_id, feeds)
283332
284
285 # Initialize user agent string333 # Initialize user agent string
286 import urllib334 import urllib
287335
288336
=== modified file 'applets/maintained/comics/comics_add.py'
--- applets/maintained/comics/comics_add.py 2010-03-01 06:50:28 +0000
+++ applets/maintained/comics/comics_add.py 2011-01-09 09:07:16 +0000
@@ -17,6 +17,7 @@
17# Free Software Foundation, Inc., 59 Temple Place - Suite 330,17# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18# Boston, MA 02111-1307, USA.18# Boston, MA 02111-1307, USA.
1919
20from __future__ import with_statement
2021
21# Libraries used22# Libraries used
22import gobject23import gobject
@@ -30,10 +31,11 @@
3031
31# Local32# Local
32from downloader import Downloader33from downloader import Downloader
33from feed.basic import Feed, NAME, URL34from feed import FeedContainer
35from feed.basic import Feed, NAME, URL, PLUGIN
34from feed.settings import Settings36from feed.settings import Settings
35from feed.rss import IMG_INDEX37from feed.rss import IMG_INDEX
36from shared import (UI_DIR, USER_FEEDS_DIR)38from shared import (UI_DIR, USER_FEEDS_DIR, SYS_FEEDS_DIR)
3739
38UI_FILE = os.path.join(UI_DIR, 'add.ui')40UI_FILE = os.path.join(UI_DIR, 'add.ui')
3941
@@ -67,13 +69,30 @@
6769
68 return True70 return True
6971
72 def load_sys_list(self):
73 if not self.sys:
74 self.sys = FeedContainer()
75 self.sys.load_directory(SYS_FEEDS_DIR)
76 self.sys_model.clear()
77 names = self.sys.feeds.keys()
78 names.sort(key=str.lower)
79 for feed in names:
80 self.sys_model.append((feed, self.sys.feeds[feed].filename))
81
82 def on_screen(self):
83 return len(self.assistant) != 0
84
85 def present(self):
86 self.assistant.present()
87
70 ########################################################################88 ########################################################################
71 # Standard python methods #89 # Standard python methods #
72 ########################################################################90 ########################################################################
7391
74 def __init__(self, feeds):92 def __init__(self, parent):
75 """Create a new ComicsAdder instance."""93 """Create a new ComicsAdder instance."""
76 self.feeds = feeds94 self.__parent = parent
95 self.feeds = parent.feeds
77 self.name = ''96 self.name = ''
78 self.url = ''97 self.url = ''
79 self.feed = None98 self.feed = None
@@ -86,9 +105,24 @@
86 self.assistant = self.ui.get_object('add_assistant')105 self.assistant = self.ui.get_object('add_assistant')
87 self.image_list = self.ui.get_object('image_list')106 self.image_list = self.ui.get_object('image_list')
88107
108 self.sys = None
109 self.sys_list = self.ui.get_object('pre_list')
110 self.sys_model = gtk.ListStore(gobject.TYPE_STRING,
111 gobject.TYPE_STRING)
112 self.sys_col = self.ui.get_object('pre_col')
113 self.load_sys_list()
114 self.sys_list.set_model(self.sys_model)
115
116 self.from_list = True
117 self.radio_button = self.ui.get_object('list_radio')
118 self.radio_button.set_active(self.from_list)
119
89 self.model = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf)120 self.model = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf)
90 self.image_list.set_model(self.model)121 self.image_list.set_model(self.model)
91122
123 selection = self.sys_list.get_selection()
124 selection.connect('changed', self.on_list_selection_changed)
125 selection.set_mode(gtk.SELECTION_MULTIPLE)
92 # Show window126 # Show window
93 self.assistant.set_page_complete(self.ui.get_object('intro_page'),127 self.assistant.set_page_complete(self.ui.get_object('intro_page'),
94 True)128 True)
@@ -115,39 +149,113 @@
115 os.mkdir(USER_FEEDS_DIR)149 os.mkdir(USER_FEEDS_DIR)
116 except Exception:150 except Exception:
117 pass151 pass
118 f, filename = tempfile.mkstemp('.feed', '', USER_FEEDS_DIR, True)
119 os.close(f)
120 settings = Settings(filename)
121 settings.description = 'Automatically generated by comics'
122 settings[NAME] = self.name
123 settings[URL] = self.url
124 settings[IMG_INDEX] = self.image[0] + 1
125 settings.comments[IMG_INDEX] = \
126 'The index of the image in the HTML-code'
127152
128 settings.save()153 if self.from_list:
129 self.feeds.add_feed(filename)154 model, paths = self.sys_list.get_selection().get_selected_rows()
155 for path in paths:
156 self.name = model.get_value(model.get_iter(path), 0)
157 src = model.get_value(model.get_iter(path), 1)
158 filename = USER_FEEDS_DIR + src[len(SYS_FEEDS_DIR):]
159 with open(src, 'r') as fp:
160 src_content = fp.read()
161 try:
162 with open(filename, 'r') as fp:
163 f = fp.read()
164 except IOError:
165 f = None
166 if f:
167 if cmp(src_content, f) == 0:
168 continue
169 msg = _("Overwrite comic \"%s\"?") % self.name
170 sec = _(
171 "This comic is already installed with different settings.")
172 dialog = gtk.MessageDialog(parent=self.assistant,
173 flags=gtk.DIALOG_DESTROY_WITH_PARENT,
174 type=gtk.MESSAGE_WARNING,
175 message_format=msg)
176 dialog.format_secondary_markup(sec)
177 if path != paths[-1]:
178 dialog.add_buttons(
179 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
180 dialog.add_buttons(gtk.STOCK_NO, gtk.RESPONSE_NO,
181 gtk.STOCK_YES, gtk.RESPONSE_YES)
182 response = dialog.run()
183 dialog.destroy()
184 if response == gtk.RESPONSE_NO:
185 continue
186 if response != gtk.RESPONSE_YES:
187 return
188 with open(filename, 'w') as fp:
189 fp.write(src_content)
190 self.feeds.add_feed(filename)
191 self.feeds.update()
192 self.__parent.toggle_feed(self.name, True)
193 else:
194 self.name = self.ui.get_object('name_entry').get_text()
195 f, filename = tempfile.mkstemp('.feed', '', USER_FEEDS_DIR, True)
196 os.close(f)
197 settings = Settings(filename)
198 settings.description = 'Automatically generated by comics'
199 settings[NAME] = self.name
200 settings[URL] = self.url
201 settings[IMG_INDEX] = self.image[0] + 1
202 settings.comments[IMG_INDEX] = \
203 'The index of the image in the HTML-code'
204 if self.feed.__module__.startswith('feed.plugins.'):
205 settings[PLUGIN] = self.feed.__module__[13:]
206 settings.save()
207 self.feeds.add_feed(filename)
208 self.feeds.update()
209 self.__parent.toggle_feed(self.name, True)
130210
131 def on_add_assistant_prepare(self, widget, page):211 def on_add_assistant_prepare(self, widget, page):
132 if page is self.ui.get_object('url_page'):212 if page is self.ui.get_object('url_page'):
133 self.ui.get_object('wait_page').show()213 if self.from_list:
214 self.ui.get_object('list_box').show()
215 self.ui.get_object('url_box').hide()
216 else:
217 self.ui.get_object('list_box').hide()
218 self.ui.get_object('url_box').show()
134219
135 elif page is self.ui.get_object('wait_page'):220 elif page is self.ui.get_object('wait_page'):
136 self.assistant.set_page_complete(page, False)221 if self.from_list:
137 self.url = self.ui.get_object('url_entry').get_text()222 self.ui.get_object('name_box').hide()
138223 last_label = self.ui.get_object('last_label')
139 self.ui.get_object('wait_label').set_markup(224 last_label.set_markup(_('''\
140 _('Connecting to <i>%s</i>...') % self.url)225This guide has finished.\n\
141226Press "apply" to add the comic.'''))
142 # Download feed227 self.assistant.set_current_page(4)
143 self.feed = self.feeds.get_feed_for_url(self.url)228 else:
144 self.__update = self.feed.connect('updated', self.on_feed_updated)229 self.assistant.set_page_complete(page, False)
145 self.feed.update()230 self.url = self.ui.get_object('url_entry').get_text()
231
232 self.ui.get_object('wait_label').set_markup(
233 _('Connecting to <i>%s</i>...') % self.url)
234
235 # Download feed
236 self.feed = self.feeds.get_feed_for_url(self.url)
237 self.__update = self.feed.connect('updated',
238 self.on_feed_updated)
239 self.feed.update()
240
241 def on_radio_button_toggled(self, widget):
242 self.from_list = self.radio_button.get_active()
146243
147 def on_url_entry_changed(self, widget):244 def on_url_entry_changed(self, widget):
148 text = widget.get_text()245 text = widget.get_text()
149 self.assistant.set_page_complete(self.ui.get_object('url_page'),246 if not self.from_list:
150 not URL_RE.match(text) is None)247 self.assistant.set_page_complete(self.ui.get_object('url_page'),
248 not URL_RE.match(text) is None)
249
250 def on_list_selection_changed(self, widget):
251 if self.from_list:
252 self.assistant.set_page_complete(self.ui.get_object('url_page'),
253 self.sys_list.get_selection().count_selected_rows() > 0)
254
255 def on_name_entry_changed(self, widget):
256 text = widget.get_text()
257 self.assistant.set_page_complete(self.ui.get_object('last_page'),
258 not text == '')
151259
152 def on_image_list_unselect_all(self, widget):260 def on_image_list_unselect_all(self, widget):
153 self.assistant.set_page_complete(self.ui.get_object('image_page'),261 self.assistant.set_page_complete(self.ui.get_object('image_page'),
@@ -172,8 +280,10 @@
172280
173 last_label = self.ui.get_object('last_label')281 last_label = self.ui.get_object('last_label')
174 last_label.set_markup(_('''\282 last_label.set_markup(_('''\
175This guide has finished.\n\nPress "apply" to add <i>%s</i>.''') \283This guide has finished.\n\
176 % self.name)284You can change the name of this comic. Press "apply" to add it.'''))
285 name_entry = self.ui.get_object('name_entry')
286 name_entry.set_text(self.name)
177287
178 # Can we skip the image page?288 # Can we skip the image page?
179 images = feed.get_unique_images()289 images = feed.get_unique_images()
@@ -189,7 +299,11 @@
189 self.ui.get_object('image_page').show()299 self.ui.get_object('image_page').show()
190 else:300 else:
191 self.ui.get_object('image_page').hide()301 self.ui.get_object('image_page').hide()
192 self.image = images[0]302 try:
303 self.image = images[0]
304 except IndexError:
305 self.process_error(Feed.DOWNLOAD_NOT_FEED)
306 return
193307
194 # Complete page308 # Complete page
195 self.assistant.set_page_complete(self.ui.get_object('wait_page'),309 self.assistant.set_page_complete(self.ui.get_object('wait_page'),
@@ -204,7 +318,9 @@
204 if code != Downloader.OK:318 if code != Downloader.OK:
205 self.model.remove(iterator)319 self.model.remove(iterator)
206 else:320 else:
207 pixbuf = gtk.gdk.pixbuf_new_from_file(o.filename)321 try:
322 pixbuf = gtk.gdk.pixbuf_new_from_file(o.filename)
323 self.model.set_value(iterator, 1, pixbuf)
324 except Exception:
325 self.model.remove(iterator)
208 os.remove(o.filename)326 os.remove(o.filename)
209
210 self.model.set_value(iterator, 1, pixbuf)
211327
=== modified file 'applets/maintained/comics/comics_manage.py'
--- applets/maintained/comics/comics_manage.py 2010-03-01 06:50:28 +0000
+++ applets/maintained/comics/comics_manage.py 2011-01-09 09:07:16 +0000
@@ -24,6 +24,7 @@
24import os24import os
2525
26# Symbols used26# Symbols used
27from gettext import ngettext
27from awn.extras import _28from awn.extras import _
2829
29# Local30# Local
@@ -47,86 +48,127 @@
47 def load_feeds(self):48 def load_feeds(self):
48 """Load the descriptions of all installed feeds."""49 """Load the descriptions of all installed feeds."""
49 self.model.clear()50 self.model.clear()
5051 names = self.feeds.feeds.keys()
51 shared_iterator = self.model.append(None, (_('Shared comics'), ''))52 names.sort(key=str.lower)
52 user_iterator = self.model.append(None, (_('Your comics'), ''))53 for feed in names:
53 for feed_name, feed in self.feeds.feeds.items():54 self.model.append(
54 if os.access(os.path.dirname(feed.filename), os.W_OK):55 (len([w for w in self.__parent.windows
55 self.model.append(user_iterator, (feed_name, feed.filename))56 if w.feed_name == feed]) > 0,
56 else:57 feed, self.feeds.feeds[feed].filename))
57 self.model.append(shared_iterator, (feed_name, feed.filename))
58
59 self.comics_list.expand_all()
6058
61 def show(self):59 def show(self):
62 self.manage_window.show()60 self.manage_window.show()
6361
62 def present(self):
63 self.manage_window.present()
64
65 def on_screen(self):
66 return len(self.manage_window) != 0
67
64 ########################################################################68 ########################################################################
65 # Standard python methods #69 # Standard python methods #
66 ########################################################################70 ########################################################################
6771
68 def __init__(self, feeds):72 def __init__(self, parent):
69 """Create a new ComicsManage instance."""73 """Create a new ComicsManage instance."""
70 # Connect dialogue events74 # Connect dialogue events
71 self.ui = gtk.Builder()75 self.ui = gtk.Builder()
72 self.ui.add_from_file(UI_FILE)76 self.ui.add_from_file(UI_FILE)
73 self.ui.connect_signals(self)77 self.ui.connect_signals(self)
7478
75 self.feeds = feeds79 self.__parent = parent
80 self.feeds = parent.feeds
7681
77 self.manage_window = self.ui.get_object('manage_window')82 self.manage_window = self.ui.get_object('manage_window')
7883
79 self.model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)84 self.model = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING,
85 gobject.TYPE_STRING)
8086
81 self.comics_list = self.ui.get_object('comics_list')87 self.comics_list = self.ui.get_object('comics_list')
82 selection = self.comics_list.get_selection()88 selection = self.comics_list.get_selection()
83 selection.connect('changed', self.on_comics_list_selection_changed)89 selection.connect('changed', self.on_comics_list_selection_changed)
84 cr = gtk.CellRendererText()90 selection.set_mode(gtk.SELECTION_MULTIPLE)
85 column = gtk.TreeViewColumn()
86 column.pack_start(cr)
87 column.set_attributes(cr, text=0)
88 self.comics_list.append_column(column)
89 self.comics_list.set_model(self.model)91 self.comics_list.set_model(self.model)
92 # Translators: checkbox to show comic
93 self.ui.get_object('toggle_col').set_title(_('Show'))
94 self.ui.get_object('name_col').set_title(_('Comic'))
9095
91 self.load_feeds()96 self.load_feeds()
97 x, y = self.comics_list.size_request()
98 if x > 475:
99 x = 475
100 if y > 400:
101 y = 400
102 self.manage_window.set_default_size(x + 25, y + 100)
92103
93 ########################################################################104 ########################################################################
94 # Event hooks #105 # Event hooks #
95 ########################################################################106 ########################################################################
96107
97 def on_comics_list_selection_changed(self, widget):108 def on_comics_list_selection_changed(self, widget):
98 model, iterator = self.comics_list.get_selection().get_selected()109 rows = self.comics_list.get_selection().count_selected_rows()
99 button = self.ui.get_object('remove_button')110 button = self.ui.get_object('remove_button')
100 if iterator:111 button.set_sensitive(rows > 0)
101 directory = os.path.dirname(self.model.get_value(iterator, 1))112
102 button.set_sensitive(os.access(directory, os.W_OK))113 def on_feed_toggled(self, widget, path):
114 self.model[path][0] = not self.model[path][0]
115 self.__parent.toggle_feed(self.model[path][1], self.model[path][0])
116
117 def on_add_button_clicked(self, widget):
118 if self.__parent.adder and self.__parent.adder.on_screen():
119 self.__parent.adder.present()
103 else:120 else:
104 button.set_sensitive(False)121 self.__parent.adder = []
105122 self.__parent.adder = ComicsAdder(self.__parent)
106 def on_add_button_clicked(self, widget):123 self.__parent.adder.assistant.set_transient_for(self.manage_window)
107 adder = ComicsAdder(self.feeds)124 self.__parent.adder.assistant.connect('destroy',
108 adder.assistant.set_transient_for(self.manage_window)125 self.on_adder_destroy)
109 adder.assistant.connect('destroy', self.on_adder_destroy)
110126
111 def on_remove_button_clicked(self, widget):127 def on_remove_button_clicked(self, widget):
112 model, iterator = self.comics_list.get_selection().get_selected()128 model, path = self.comics_list.get_selection().get_selected_rows()
113 feed_name = self.model.get_value(iterator, 0)129 msg = ngettext(
114 filename = self.model.get_value(iterator, 1)130 "Are you sure you want to remove the comic \"%(name)s\"?",
115 try:131 "Are you sure you want to remove the %(number)d selected comics?",
116 self.feeds.remove_feed(feed_name)132 len(path)) % {'number': len(path),
117 os.remove(filename)133 'name': self.model.get_value(self.model.get_iter(path[0]), 1)}
118 except Exception:134 sec = ngettext(
119 msg = _('Failed to remove <i>%s</i>.') % filename135 "This will remove the comic from your personal comics list.",
120 dialog = gtk.MessageDialog(parent=self.manage_window,136 "This will remove these comics from your personal comics list.",
121 flags=gtk.DIALOG_DESTROY_WITH_PARENT,137 len(path))
122 type=gtk.MESSAGE_INFO,138
123 buttons=gtk.BUTTONS_CLOSE,139 dialog = gtk.MessageDialog(parent=self.manage_window,
124 message_format=msg)140 flags=gtk.DIALOG_DESTROY_WITH_PARENT,
125 dialog.set_title(_('Error'))141 type=gtk.MESSAGE_WARNING,
126 dialog.run()142 message_format=msg)
127 dialog.hide()143 dialog.format_secondary_markup(sec)
128 del dialog144 dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
145 gtk.STOCK_REMOVE, gtk.RESPONSE_OK)
146 response = dialog.run()
147 dialog.destroy()
148
149 if response != gtk.RESPONSE_OK:
129 return150 return
151
152 def remove(model, path, iterator):
153 feed_name = model.get_value(iterator, 1)
154 filename = model.get_value(iterator, 2)
155 self.__parent.toggle_feed(feed_name, False)
156 try:
157 self.feeds.remove_feed(feed_name)
158 os.remove(filename)
159 except Exception:
160 msg = _("Failed to remove '%s'.") % filename
161 dialog = gtk.MessageDialog(parent=self.manage_window,
162 flags=gtk.DIALOG_DESTROY_WITH_PARENT,
163 type=gtk.MESSAGE_INFO,
164 buttons=gtk.BUTTONS_CLOSE,
165 message_format=msg)
166 dialog.set_title(_('Error'))
167 dialog.run()
168 dialog.destroy()
169 return
170
171 self.comics_list.get_selection().selected_foreach(remove)
130 self.load_feeds()172 self.load_feeds()
131173
132 def on_close_button_clicked(self, widget):174 def on_close_button_clicked(self, widget):
133175
=== modified file 'applets/maintained/comics/comics_view.py'
--- applets/maintained/comics/comics_view.py 2010-03-01 06:50:28 +0000
+++ applets/maintained/comics/comics_view.py 2011-01-09 09:07:16 +0000
@@ -42,7 +42,6 @@
4242
43STRIPS_DIR = USER_DIR43STRIPS_DIR = USER_DIR
44CACHE_FILE = os.path.join(USER_DIR, '%s.cache')44CACHE_FILE = os.path.join(USER_DIR, '%s.cache')
45UI_FILE = os.path.join(UI_DIR, 'view.ui')
4645
47BROWSER_COMMAND = 'xdg-open'46BROWSER_COMMAND = 'xdg-open'
4847
@@ -123,11 +122,13 @@
123 screen = self.get_screen()122 screen = self.get_screen()
124 screen_width, screen_height = (screen.get_width(),123 screen_width, screen_height = (screen.get_width(),
125 screen.get_height())124 screen.get_height())
125 w, h = self.get_size()
126 x = self.__settings.get_int('x', (screen_width - w) / 2)
127 y = self.__settings.get_int('y', (screen_height - h) / 2)
126128
127 # Show the window first...129 # Show the window first...
128 self.show()130 self.show()
129131
130 x, y = self.get_position()
131 x %= screen_width132 x %= screen_width
132 if x < 0:133 if x < 0:
133 x += screen_width134 x += screen_width
@@ -135,32 +136,34 @@
135 if y < 0:136 if y < 0:
136 y += screen_height137 y += screen_height
137138
139 # this must be between self.show() and self.move()
140 # it calls self.get_position(), without it the comic
141 # will not be painted the very first time
142 self.save_settings()
143
138 # ...and then move it144 # ...and then move it
139 self.move(x, y)145 self.move(x, y)
140146
141 self.__settings['x'] = x
142 self.__settings['y'] = y
143
144 if has_widget_layer():147 if has_widget_layer():
145 compiz_widget_set(self, False)148 compiz_widget_set(self, False)
146 else:149 else:
150 if self.get_window():
151 self.save_settings()
147 if has_widget_layer():152 if has_widget_layer():
148 self.show()153 self.show()
149 compiz_widget_set(self, True)154 compiz_widget_set(self, True)
150 else:155 else:
151 self.hide()156 self.hide()
152157
153 self.__settings.save()
154
155 def close(self):158 def close(self):
156 self.emit('removed')
157 self.__settings.delete()
158 self.destroy()159 self.destroy()
159160
160 def get_menu_item_name(self, item):161 def get_menu_item_name(self, item):
161 """Return the menu item name of item."""162 """Return the menu item name of item."""
162 if item[DATE] > 0:163 if item[DATE] > 0:
163 tt = time.localtime(item[DATE])164 tt = time.localtime(item[DATE])
165 # Translators: This is a date/time format string. You can check the
166 # output in terminal with 'date +"%%A %d %B"'.
164 return time.strftime(_('%A %d %B'), tt)167 return time.strftime(_('%A %d %B'), tt)
165 else:168 else:
166 return item[TITLE]169 return item[TITLE]
@@ -335,49 +338,64 @@
335338
336 ctx.restore()339 ctx.restore()
337340
338 def make_file_type_chooser(self):
339 """Add the possible image types to the file chooser dialog."""
340 combo = self.__ui.get_object('file_format_combo')
341 model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
342 gobject.TYPE_STRING)
343 for format in gdk.pixbuf_get_formats():
344 if format['is_writable']:
345 text = '%s (*.%s)' % (format['description'],
346 format['extensions'][0])
347 model.append((format['description'], format['name'],
348 format['extensions'][0]))
349 combo.set_model(model)
350 combo.set_active(0)
351
352 def make_menu(self):341 def make_menu(self):
353 """Create the context menu."""342 """Create the context menu."""
343 menu = gtk.Menu()
344
354 # Generate history menu345 # Generate history menu
355 history_menu = self.__ui.get_object('history_menu')346 if len(self.feeds.feeds[self.feed_name].items) > 1:
356 history_menu.foreach(lambda child: history_menu.remove(child))347 history_container = gtk.ImageMenuItem(gtk.STOCK_JUMP_TO)
357 items = self.feeds.feeds[self.feed_name].items.items()348 history_menu = gtk.Menu()
358 items.sort(reverse=True)349 history_menu.foreach(lambda child: history_menu.remove(child))
359 for date, item in items:350 items = self.feeds.feeds[self.feed_name].items.items()
360 label = gtk.Label()351 items.sort(reverse=True)
361 text = self.get_menu_item_name(item)352 for date, item in items:
362 if self.__current_timestamp == date:353 label = gtk.Label()
363 label.set_markup('<b>' + text + '</b>')354 text = self.get_menu_item_name(item)
364 else:355 if self.__current_timestamp == date:
365 label.set_markup(text)356 label.set_markup('<b>' + text + '</b>')
366 align = gtk.Alignment(xalign=0.0)357 else:
367 align.add(label)358 label.set_markup(text)
368 menu_item = gtk.MenuItem()359 align = gtk.Alignment(xalign=0.0)
369 menu_item.data = item360 align.add(label)
370 menu_item.connect('activate', self.on_history_activated)361 menu_item = gtk.MenuItem()
371 menu_item.add(align)362 menu_item.data = item
372 history_menu.append(menu_item)363 menu_item.connect('activate', self.on_history_activated)
373 history_menu.show_all()364 menu_item.add(align)
374 self.__ui.get_object('show_link_item').set_active(self.show_link)365 history_menu.append(menu_item)
375 self.__ui.get_object('history_container').set_sensitive(366 history_container.set_submenu(history_menu)
376 len(self.feeds.feeds[self.feed_name].items) > 0)367 menu.append(history_container)
377 self.__ui.get_object('save_as_item').set_sensitive(not self.__pixbuf \368
378 is None)369 size_container = gtk.MenuItem(_("Size"))
379370 size_menu = gtk.Menu()
380 return self.__ui.get_object('menu')371 zoom_normal_item = gtk.ImageMenuItem(gtk.STOCK_ZOOM_100)
372 zoom_normal_item.connect('activate', self.on_normal_activated)
373 zoom_in_item = gtk.ImageMenuItem(gtk.STOCK_ZOOM_IN)
374 zoom_in_item.connect('activate', self.on_larger_activated)
375 zoom_out_item = gtk.ImageMenuItem(gtk.STOCK_ZOOM_OUT)
376 zoom_out_item.connect('activate', self.on_smaller_activated)
377 size_menu.append(zoom_normal_item)
378 size_menu.append(zoom_in_item)
379 size_menu.append(zoom_out_item)
380 size_container.set_submenu(size_menu)
381 menu.append(size_container)
382
383 show_link_item = gtk.CheckMenuItem(_("Show link"))
384 show_link_item.set_active(self.show_link)
385 show_link_item.connect('toggled', self.on_show_link_toggled)
386 menu.append(show_link_item)
387
388 save_as_item = gtk.ImageMenuItem(stock_id='gtk-save-as')
389 save_as_item.set_sensitive(not self.__pixbuf is None)
390 save_as_item.connect('activate', self.on_save_as_activated)
391 menu.append(save_as_item)
392
393 close_item = gtk.ImageMenuItem(stock_id='gtk-close')
394 close_item.connect('activate', self.on_close_activated)
395 menu.append(close_item)
396
397 menu.show_all()
398 return menu
381399
382 ########################################################################400 ########################################################################
383 # Standard python methods #401 # Standard python methods #
@@ -399,9 +417,6 @@
399 except Exception:417 except Exception:
400 self.__pixbuf = None418 self.__pixbuf = None
401 self.__is_error = False419 self.__is_error = False
402 self.__ui = gtk.Builder()
403 self.__ui.add_from_file(UI_FILE)
404 self.make_file_type_chooser()
405 self.__link = WWWLink('', '', LINK_FONTSIZE)420 self.__link = WWWLink('', '', LINK_FONTSIZE)
406 self.__link.connect('size-allocate', self.on_link_size_allocate)421 self.__link.connect('size-allocate', self.on_link_size_allocate)
407 self.__ticker = Ticker((20.0, 20.0))422 self.__ticker = Ticker((20.0, 20.0))
@@ -412,7 +427,6 @@
412 # Connect events427 # Connect events
413 self.connect('destroy', self.on_destroy)428 self.connect('destroy', self.on_destroy)
414 self.feeds.connect('feed-changed', self.on_feed_changed)429 self.feeds.connect('feed-changed', self.on_feed_changed)
415 self.__ui.connect_signals(self)
416430
417 # Build UI431 # Build UI
418 self.__link.connect('button-press-event', self.on_link_clicked)432 self.__link.connect('button-press-event', self.on_link_clicked)
@@ -422,9 +436,10 @@
422436
423 self.set_skip_taskbar_hint(True)437 self.set_skip_taskbar_hint(True)
424 self.set_skip_pager_hint(True)438 self.set_skip_pager_hint(True)
425 self.set_visibility(visible)
426439
427 self.load_settings()440 self.load_settings()
441 if visible:
442 self.set_visibility(visible)
428443
429 ########################################################################444 ########################################################################
430 # Property updating methods #445 # Property updating methods #
@@ -432,14 +447,9 @@
432447
433 def load_settings(self):448 def load_settings(self):
434 """Load the settings."""449 """Load the settings."""
435 screen = self.get_screen()
436 w, h = self.get_size()
437
438 self.set_show_link(self.__settings.get_bool('show_link',450 self.set_show_link(self.__settings.get_bool('show_link',
439 False))451 False))
440 self.set_feed_name(self.__settings.get_string('feed_name', ''))452 self.set_feed_name(self.__settings.get_string('feed_name', ''))
441 self.move(self.__settings.get_int('x', (screen.get_width() - w) / 2),
442 self.__settings.get_int('y', (screen.get_height() - h) / 2))
443453
444 def save_settings(self):454 def save_settings(self):
445 """Save the settings."""455 """Save the settings."""
@@ -484,6 +494,8 @@
484 ########################################################################494 ########################################################################
485495
486 def on_destroy(self, widget):496 def on_destroy(self, widget):
497 self.emit('removed')
498 self.__settings.delete()
487 if self.__update_id:499 if self.__update_id:
488 self.feeds.feeds[self.feed_name].disconnect(self.__update_id)500 self.feeds.feeds[self.feed_name].disconnect(self.__update_id)
489 self.__update_id = None501 self.__update_id = None
@@ -516,33 +528,55 @@
516 self.close()528 self.close()
517529
518 def on_save_as_activated(self, widget):530 def on_save_as_activated(self, widget):
519 dialog = self.__ui.get_object('save_as_dialog')531 """Run FileChooserDialog and save file."""
520 dialog.set_title(self.feed_name)532 self.dialog = gtk.FileChooserDialog(_("Save comic as…"), \
521 combo = self.__ui.get_object('file_format_combo')533 buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, \
522 model, iterator = combo.get_model(), combo.get_active_iter()534 gtk.STOCK_SAVE, gtk.RESPONSE_OK), \
523 format = model.get_value(iterator, 1)535 action=gtk.FILE_CHOOSER_ACTION_SAVE)
524 ext = model.get_value(iterator, 2)536 self.dialog.set_icon_from_file(os.path.join(UI_DIR, 'comics.svg'))
525 dialog.set_current_name('%s.%s' % (self.__link.text, ext))537 self.dialog.set_do_overwrite_confirmation(True)
526 if dialog.run():538 self.dialog.set_current_name(self.__link.text + '.jpg')
527 model, iterator = combo.get_model(), combo.get_active_iter()539
528 format = model.get_value(iterator, 1)540 # Set filters, default jpg, without ico
541 for format in gdk.pixbuf_get_formats():
542 if format['is_writable'] and format['name'] != 'ico':
543 ff = gtk.FileFilter()
544 ff.set_name(format['description'])
545 for i in format['mime_types']:
546 ff.add_mime_type(i)
547 self.dialog.add_filter(ff)
548 if format['name'] == 'jpeg':
549 self.dialog.set_filter(ff)
550 self.dialog.connect('notify::filter', self.on_filter_changed)
551
552 if self.dialog.run() == gtk.RESPONSE_OK:
553 ff = gtk.FileFilter()
554 ff = self.dialog.get_filter()
555 name = ff.get_name()
556 for format in gdk.pixbuf_get_formats():
557 if format['description'] == name:
558 name = format['name']
559 break
529 try:560 try:
530 self.__pixbuf.save(dialog.get_filename(), format)561 self.__pixbuf.save(self.dialog.get_filename(), name)
531 except Exception:562 except Exception:
532 self.applet.show_message(_('Failed to save <i>%s</i>.') %563 self.applet.show_message(_('Failed to save <i>%s</i>.') %
533 dialog.get_filename(), gtk.STOCK_DIALOG_ERROR)564 self.dialog.get_filename(), gtk.STOCK_DIALOG_ERROR)
534565 self.dialog.destroy()
535 dialog.hide()566
536567 def on_filter_changed(self, pspec, data):
537 def on_file_format_combo_changed(self, widget):568 """Change filename extension."""
538 dialog = self.__ui.get_object('save_as_dialog')569 current_name = self.dialog.get_filename().rsplit('.', 1)
539 current_name = dialog.get_filename().rsplit('.', 1)
540 if len(current_name) == 2:570 if len(current_name) == 2:
541 combo = widget571 ff = gtk.FileFilter()
542 model, iterator = combo.get_model(), combo.get_active_iter()572 ff = self.dialog.get_filter()
543 ext = model.get_value(iterator, 2)573 for i in gdk.pixbuf_get_formats():
544 dialog.set_current_name('%s.%s' % (574 if i['description'] == ff.get_name():
545 os.path.basename(current_name[0]), ext))575 for ext in i['extensions']:
576 if current_name[1] == ext:
577 return
578 self.dialog.set_current_name('%s.%s' % (
579 os.path.basename(current_name[0]), i['extensions'][0]))
546580
547 def on_link_size_allocate(self, widget, e):581 def on_link_size_allocate(self, widget, e):
548 i_dim = self.get_image_dimensions()582 i_dim = self.get_image_dimensions()
@@ -578,7 +612,8 @@
578 # Only emit the updated signal when there actually is an update612 # Only emit the updated signal when there actually is an update
579 if self.__current_timestamp != 0.0:613 if self.__current_timestamp != 0.0:
580 self.emit('updated', feed.items[feed.newest][TITLE])614 self.emit('updated', feed.items[feed.newest][TITLE])
581 self.select_item(feed.items[feed.newest])615 if feed.newest in feed.items:
616 self.select_item(feed.items[feed.newest])
582617
583 def on_download_completed(self, o, code, item):618 def on_download_completed(self, o, code, item):
584 """A new image has been downloaded."""619 """A new image has been downloaded."""
@@ -593,7 +628,11 @@
593 self.__download_id = None628 self.__download_id = None
594629
595 if not self.__is_error:630 if not self.__is_error:
596 del self.__pixbuf631 try:
632 del self.__pixbuf
633 except AttributeError:
634 # Received destroy signal after download was initiated
635 return
597 try:636 try:
598 self.__pixbuf = gdk.pixbuf_new_from_file(o.filename)637 self.__pixbuf = gdk.pixbuf_new_from_file(o.filename)
599 except gobject.GError:638 except gobject.GError:
600639
=== modified file 'applets/maintained/comics/feed/__init__.py'
--- applets/maintained/comics/feed/__init__.py 2010-01-04 07:37:45 +0000
+++ applets/maintained/comics/feed/__init__.py 2011-01-09 09:07:16 +0000
@@ -40,14 +40,14 @@
40 of factories. If filename does not contain a feed factory, it is not40 of factories. If filename does not contain a feed factory, it is not
41 added."""41 added."""
42 try:42 try:
43 module = __import__('plugins.%s' % name, fromlist=[name])43 module = __import__('plugins.%s' % name, globals(), locals(), [name], -1)
44 if hasattr(module, 'matches_url') and hasattr(module, 'get_class'):44 if hasattr(module, 'matches_url') and hasattr(module, 'get_class'):
45 self.feed_factories.append(module)45 self.feed_factories[name] = module
46 return True46 return True
47 else:47 else:
48 del module48 del module
49 except Exception:49 except Exception, err:
50 pass50 print "Comics!: Error loading plugin: %s" % err
5151
52 return False52 return False
5353
@@ -75,14 +75,15 @@
75 if plugin in self.feed_factories:75 if plugin in self.feed_factories:
76 factory = self.feed_factories[plugin].get_class()76 factory = self.feed_factories[plugin].get_class()
77 else:77 else:
78 print "Comics!: Plugin '%s' not found" % plugin
78 return False79 return False
79 else:80 else:
80 factory = RSSFeed81 factory = RSSFeed
81 feed = factory(settings)82 feed = factory(settings)
82 self.feeds[settings[NAME]] = feed83 self.feeds[settings[NAME]] = feed
83 self.emit('feed-changed', feed, FeedContainer.FEED_ADDED)84 self.emit('feed-changed', feed, FeedContainer.FEED_ADDED)
84 except Exception:85 except Exception, err:
85 pass86 print "Comics!: Error loading feed: %s" % err
8687
87 return False88 return False
8889
@@ -90,8 +91,8 @@
90 """Creates a feed suitable for a given URL. If no plugin matches the91 """Creates a feed suitable for a given URL. If no plugin matches the
91 URL, an RSSFeed is returned."""92 URL, an RSSFeed is returned."""
92 for factory in self.feed_factories:93 for factory in self.feed_factories:
93 if factory.matches_url(url):94 if self.feed_factories[factory].matches_url(url):
94 return factory.get_class()(url=url)95 return self.feed_factories[factory].get_class()(url=url)
95 return RSSFeed(url=url)96 return RSSFeed(url=url)
9697
97 def remove_feed(self, feed_name):98 def remove_feed(self, feed_name):
9899
=== modified file 'applets/maintained/comics/feed/basic.py'
--- applets/maintained/comics/feed/basic.py 2010-01-04 07:36:10 +0000
+++ applets/maintained/comics/feed/basic.py 2011-01-09 09:07:16 +0000
@@ -23,15 +23,23 @@
23import urllib23import urllib
24import urlparse24import urlparse
25import threading25import threading
26import htmlentitydefs
27import httplib
28import time
2629
27from settings import Settings30from settings import Settings
2831
29NAME = 'name'32NAME = 'name'
30URL = 'url'33URL = 'url'
34PLUGIN = 'plugin'
31TITLE = 'title'35TITLE = 'title'
32LINK = 'link'36LINK = 'link'
33DATE = 'date'37DATE = 'date'
3438
39month = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04',
40 'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08',
41 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'}
42
3543
36class Feed(gobject.GObject):44class Feed(gobject.GObject):
37 """A feed class."""45 """A feed class."""
@@ -58,8 +66,83 @@
58 elif parsed[0][2][0] == '/':66 elif parsed[0][2][0] == '/':
59 return parsed[1][0] + '://' + parsed[1][1] + parsed[0][2]67 return parsed[1][0] + '://' + parsed[1][1] + parsed[0][2]
60 else:68 else:
69 # TODO this didn't work for some (or all?) urls,
70 # like http://www.gwscomic.com - test more thoroughly whether
71 # there should be an elif for that
72 #return parsed[1][0] + '://' + parsed[1][1] \
73 # + parsed[1][2].rsplit('/', 1)[0] + parsed[0][2]
61 return parsed[1][0] + '://' + parsed[1][1] \74 return parsed[1][0] + '://' + parsed[1][1] \
62 + parsed[1][2].rsplit('/', 1)[0] + parsed[0][2]75 + '/' + parsed[0][2]
76
77 def get_timestamp_for_url(self, url):
78 """Request the "Last-Modified" header from url without downloading
79 any data and return a timestamp or None"""
80 if url is None or len(url) == 0:
81 return None
82 p = urlparse.urlparse(url)
83 try:
84 if p.scheme == 'http':
85 conn = httplib.HTTPConnection(p.netloc)
86 elif p.scheme == 'https':
87 conn = httplib.HTTPSConnection(p.netloc)
88 else:
89 raise Exception
90 conn.request("HEAD", p.path)
91 res = conn.getresponse()
92 htime = res.getheader("Last-Modified")
93 except Exception:
94 return None
95
96 # Based on a posting by Philip Semanchuk, Nov 2009 on
97 # http://mail.python.org/mailman/listinfo/python-list
98
99 try:
100 if not htime.endswith("GMT"):
101 # ASCTIME format
102 # Work around locale problems: remove weedays,
103 # convert month names to decimals
104 htime = htime[4:]
105 htime = month[htime[0:3]] + htime[3:]
106 timestamp = time.strptime(htime, "%m %d %H:%M:%S %Y")
107 else:
108 # RFC 850 Format
109 if "-" in htime:
110 htime = htime.split(" ", 1)[1]
111 htime = htime[:3] + month[htime[3:6]] + htime[6:]
112 timestamp = time.strptime(htime, "%d-%m-%y %H:%M:%S GMT")
113 else:
114 # RFC 1123 Format
115 htime = htime[5:]
116 htime = htime[:3] + month[htime[3:6]] + htime[6:]
117 timestamp = time.strptime(htime, "%d %m %Y %H:%M:%S GMT")
118 timestamp = time.mktime(timestamp)
119 except Exception, err:
120 print "Comics!: %s" % err
121 return None
122 return timestamp
123
124 def unescape_html(self, text):
125 """Taken from Fredrik Lundh -
126 http://effbot.org/zone/re-sub.htm#unescape-html"""
127 def fixup(m):
128 text = m.group(0)
129 if text[:2] == "&#":
130 # character reference
131 try:
132 if text[:3] == "&#x":
133 return unichr(int(text[3:-1], 16))
134 else:
135 return unichr(int(text[2:-1]))
136 except ValueError:
137 pass
138 else:
139 # named entity
140 try:
141 text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
142 except KeyError:
143 pass
144 return text # leave as is
145 return re.sub("&#?\w+;", fixup, text)
63146
64 def __init__(self, settings=None, url=None):147 def __init__(self, settings=None, url=None):
65 """Initialize a feed."""148 """Initialize a feed."""
@@ -88,23 +171,21 @@
88 """The thread body."""171 """The thread body."""
89 if not self.__lock.acquire(False):172 if not self.__lock.acquire(False):
90 return173 return
174 old_status = self.status
175 self.updated = False
91 try:176 try:
92 old_status = self.status177 filename, headers = urllib.urlretrieve(self.url)
93 try:178 self.status = self.parse_file(filename)
94 self.updated = False
95 filename, headers = urllib.urlretrieve(self.url)
96 self.status = self.parse_file(filename)
97 finally:
98 pass
99 #except Exception:
100 # self.status = Feed.DOWNLOAD_FAILED
101
102 # If the status has changed, the feed is considered updated179 # If the status has changed, the feed is considered updated
103 if self.updated or old_status != self.status:180 if self.updated or old_status != self.status:
104 gobject.idle_add(gobject.GObject.emit, self, 'updated',181 gobject.idle_add(gobject.GObject.emit, self, 'updated',
105 self.status)182 self.status)
106 finally:183 except IOError: # Network is down
107 self.__lock.release()184 self.status = Feed.DOWNLOAD_FAILED
185 except Exception, err:
186 self.status = Feed.DOWNLOAD_FAILED
187 print "Comics!: Parsing error: %s" % err
188 self.__lock.release()
108189
109 def update(self):190 def update(self):
110 """Reload the feed."""191 """Reload the feed."""
111192
=== added file 'applets/maintained/comics/feed/plugins/__init__.py'
--- applets/maintained/comics/feed/plugins/__init__.py 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feed/plugins/__init__.py 2011-01-09 09:07:16 +0000
@@ -0,0 +1,18 @@
1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2010 Gabor Karsay
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2 of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the
17# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18# Boston, MA 02111-1307, USA.
019
=== added file 'applets/maintained/comics/feed/plugins/simple_screen_scraper.py'
--- applets/maintained/comics/feed/plugins/simple_screen_scraper.py 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feed/plugins/simple_screen_scraper.py 2011-01-09 09:07:16 +0000
@@ -0,0 +1,112 @@
1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2010 Gabor Karsay
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2 of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the
17# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18# Boston, MA 02111-1307, USA.
19
20from __future__ import with_statement
21
22import feedparser
23import re
24
25from ..basic import URL, TITLE, LINK, DATE, Feed
26from ..rss import IMAGES
27
28
29def get_class():
30 '''Mandatory for plugins.'''
31 return SimpleScreenScraper
32
33
34def matches_url(url):
35 '''Mandatory for plugins.
36 Return True if we want to read a comic from this url, else return False.
37 SimpleScreenScraper accepts all urls that are not feeds.'''
38 try:
39 feed = feedparser.parse(url)
40 if feed.version == '':
41 return True
42 except Exception:
43 return True
44 return False
45
46
47class SimpleScreenScraper(Feed):
48 """A SimpleScreenScraper class."""
49
50 def __init__(self, settings=None, url=None):
51 super(SimpleScreenScraper, self).__init__(settings, url)
52 if settings:
53 self.img_index = settings.get_int('img_index', 1) - 1
54 else:
55 self.img_index = 0
56
57 def parse_file(self, filename):
58 '''Mandatory for plugins.
59 Parses given file (a downloaded feed) and puts each found item
60 into a dict with the keys URL (path to the image), LINK to the
61 page, TITLE for that link, DATE (a timestamp) and IMAGES (list of
62 images, only needed for new comics).
63 Each of this dicts has to be put into self.items with DATE as key.'''
64 try:
65 with open(filename, 'r') as f:
66 data = f.read()
67 except IOError:
68 return Feed.DOWNLOAD_FAILED
69
70 # Update properties
71 if self.name is None:
72 title_re = re.compile("<title>(.*?)<\/title>", re.DOTALL |
73 re.M |
74 re.IGNORECASE)
75 try:
76 self.name = self.unescape_html(title_re.findall(data)[0])
77 except IndexError:
78 self.name = "Comic"
79
80
81 images = []
82 images += [self.make_absolute_url(u, self.url)
83 for u in Feed.IMG_SRC_RE.findall(data)]
84
85 item = {}
86 try:
87 item[URL] = images[self.img_index]
88 except IndexError:
89 print "Comics!: img_index out of range in '%s'." % self.name
90 return Feed.DOWNLOAD_NOT_FEED
91 item[LINK] = self.url
92 item[TITLE] = self.name
93 item[DATE] = self.get_timestamp_for_url(item[URL])
94 if item[DATE] == None:
95 item[DATE] = 1.0
96 item[IMAGES] = images
97
98 self.items[item[DATE]] = item
99
100 if self.newest != item[DATE]:
101 self.newest = item[DATE]
102 self.updated = True
103 return Feed.DOWNLOAD_OK
104
105 def get_unique_images(self):
106 """Mandatory for plugins.
107 Returns a list of (index, url) tuples for the images."""
108 if len(self.items) == 0:
109 return None
110 items = self.items.itervalues()
111 item = items.next()
112 return list(enumerate(item[IMAGES]))
0113
=== modified file 'applets/maintained/comics/feed/rss.py'
--- applets/maintained/comics/feed/rss.py 2010-01-04 07:40:00 +0000
+++ applets/maintained/comics/feed/rss.py 2011-01-09 09:07:16 +0000
@@ -89,9 +89,9 @@
8989
90 # Update properties90 # Update properties
91 if 'description' in feed:91 if 'description' in feed:
92 self.description = feed.description92 self.description = self.unescape_html(feed.description)
93 if 'title' in feed.feed:93 if 'title' in feed.feed:
94 self.name = feed.feed.title94 self.name = self.unescape_html(feed.feed.title)
9595
96 # Create an item-thread tuple for every entry96 # Create an item-thread tuple for every entry
97 threads = []97 threads = []
9898
=== added file 'applets/maintained/comics/feeds/ben.feed'
--- applets/maintained/comics/feeds/ben.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/ben.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://comics.com/ben/
4plugin=simple_screen_scraper
5name=Ben
6# The index of the image in the HTML-code
7img_index=4
08
=== modified file 'applets/maintained/comics/feeds/buttersafe.feed'
--- applets/maintained/comics/feeds/buttersafe.feed 2009-01-29 04:55:04 +0000
+++ applets/maintained/comics/feeds/buttersafe.feed 2011-01-09 09:07:16 +0000
@@ -1,6 +1,6 @@
1# Automatically generated by comics1# Automatically generated by comics
22
3url=http://feeds.feedburner.com/Buttersafe3url=http://feeds.feedburner.com/buttersafe
4name=Buttersafe4name=Buttersafe - Updated Tuesdays and Thursdays
5# The index of the image in the HTML-code5# The index of the image in the HTML-code
6img_index=46img_index=5
77
=== added file 'applets/maintained/comics/feeds/calvinandhobbes.feed'
--- applets/maintained/comics/feeds/calvinandhobbes.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/calvinandhobbes.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,6 @@
1# Automatically generated by comics
2
3url=http://feeds.feedburner.com/uclick/calvinandhobbes
4name=Calvin and Hobbes
5# The index of the image in the HTML-code
6img_index=27
07
=== added file 'applets/maintained/comics/feeds/ferdnand.feed'
--- applets/maintained/comics/feeds/ferdnand.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/ferdnand.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://comics.com/ferdnand/
4plugin=simple_screen_scraper
5name=Ferd'nand
6# The index of the image in the HTML-code
7img_index=4
08
=== added file 'applets/maintained/comics/feeds/garfield.feed'
--- applets/maintained/comics/feeds/garfield.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/garfield.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,6 @@
1# Automatically generated by comics
2
3url=http://feeds.feedburner.com/uclick/garfield
4name=Garfield
5# The index of the image in the HTML-code
6img_index=27
07
=== added file 'applets/maintained/comics/feeds/nancy.feed'
--- applets/maintained/comics/feeds/nancy.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/nancy.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://comics.com/nancy/
4plugin=simple_screen_scraper
5name=Nancy
6# The index of the image in the HTML-code
7img_index=4
08
=== added file 'applets/maintained/comics/feeds/pcnp.feed'
--- applets/maintained/comics/feeds/pcnp.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/pcnp.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://comics.com/pc_and_pixel/
4plugin=simple_screen_scraper
5name=PC and Pixel
6# The index of the image in the HTML-code
7img_index=4
08
=== added file 'applets/maintained/comics/feeds/peanuts.feed'
--- applets/maintained/comics/feeds/peanuts.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/peanuts.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://comics.com/peanuts
4plugin=simple_screen_scraper
5name=Peanuts
6# The index of the image in the HTML-code
7img_index=6
08
=== removed file 'applets/maintained/comics/feeds/peanuts.feed'
--- applets/maintained/comics/feeds/peanuts.feed 2008-12-11 22:58:58 +0000
+++ applets/maintained/comics/feeds/peanuts.feed 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
1name=Peanuts
2url=http://feeds.feedburner.com/tapestrypeanuts
30
=== modified file 'applets/maintained/comics/feeds/pearls.feed'
--- applets/maintained/comics/feeds/pearls.feed 2008-02-23 15:38:06 +0000
+++ applets/maintained/comics/feeds/pearls.feed 2011-01-09 09:07:16 +0000
@@ -1,5 +1,7 @@
1# Feed description1# Automatically generated by comics
22
3name=Pearls before Swine3url=http://comics.com/pearls_before_swine/
4url=http://feeds.feedburner.com/tapestrypearls4plugin=simple_screen_scraper
55name=Pearls Before Swine
6# The index of the image in the HTML-code
7img_index=4
68
=== added file 'applets/maintained/comics/feeds/pickles.feed'
--- applets/maintained/comics/feeds/pickles.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/pickles.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,6 @@
1# Automatically generated by comics
2
3url=http://feeds.feedburner.com/uclick/pickles
4name=Pickles
5# The index of the image in the HTML-code
6img_index=26
07
=== added file 'applets/maintained/comics/feeds/userfriendly.feed'
--- applets/maintained/comics/feeds/userfriendly.feed 1970-01-01 00:00:00 +0000
+++ applets/maintained/comics/feeds/userfriendly.feed 2011-01-09 09:07:16 +0000
@@ -0,0 +1,7 @@
1# Automatically generated by comics
2
3url=http://www.userfriendly.org/static/
4plugin=simple_screen_scraper
5name=UserFriendly.Org
6# The index of the image in the HTML-code
7img_index=4
08
=== modified file 'applets/maintained/comics/feeds/wizardofid.feed'
--- applets/maintained/comics/feeds/wizardofid.feed 2009-01-19 18:50:48 +0000
+++ applets/maintained/comics/feeds/wizardofid.feed 2011-01-09 09:07:16 +0000
@@ -1,3 +1,6 @@
1name=Wizard of ID1# Automatically generated by comics
2url=http://feeds.gocomics.com/uclick/wizardofid2
3img_index=173url=http://feeds.feedburner.com/uclick/wizardofid
4name=Wizard of Id
5# The index of the image in the HTML-code
6img_index=26
47
=== modified file 'applets/maintained/comics/ui/add.ui'
--- applets/maintained/comics/ui/add.ui 2010-01-26 03:46:15 +0000
+++ applets/maintained/comics/ui/add.ui 2011-01-09 09:07:16 +0000
@@ -1,77 +1,249 @@
1<?xml version="1.0"?>1<?xml version="1.0"?>
2<!--Generated with glade3 3.4.0 on Thu Feb 21 11:37:45 2008 -->
3<interface>2<interface>
3 <!-- interface-requires gtk+ 2.12 -->
4 <!-- interface-naming-policy toplevel-contextual -->
4 <object class="GtkAssistant" id="add_assistant">5 <object class="GtkAssistant" id="add_assistant">
5 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>6 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
6 <property name="border_width">4</property>7 <property name="border_width">12</property>
7 <property name="title" translatable="yes">Add Comic</property>8 <property name="title" translatable="yes">Add Comic</property>
8 <property name="window_position">GTK_WIN_POS_CENTER</property>9 <property name="window_position">center</property>
9 <property name="icon">comics.svg</property>10 <property name="icon">comics.svg</property>
10 <signal handler="on_add_assistant_close" name="close"/>11 <signal name="apply" handler="on_add_assistant_apply"/>
11 <signal handler="on_add_assistant_cancel" name="cancel"/>12 <signal name="prepare" handler="on_add_assistant_prepare"/>
12 <signal handler="on_add_assistant_apply" name="apply"/>13 <signal name="cancel" handler="on_add_assistant_cancel"/>
13 <signal handler="on_add_assistant_prepare" name="prepare"/>14 <signal name="close" handler="on_add_assistant_close"/>
15 <child>
16 <placeholder/>
17 </child>
18 <child>
19 <placeholder/>
20 </child>
14 <child>21 <child>
15 <object class="GtkVBox" id="intro_page">22 <object class="GtkVBox" id="intro_page">
16 <property name="visible">True</property>23 <property name="visible">True</property>
17 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>24 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
18 <property name="spacing">10</property>25 <property name="border_width">12</property>
19 <child>26 <property name="spacing">12</property>
20 <object class="GtkLabel" id="intro_label">27 <child>
28 <placeholder/>
29 </child>
30 <child>
31 <object class="GtkVBox" id="vbox2">
21 <property name="visible">True</property>32 <property name="visible">True</property>
22 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>33 <property name="spacing">12</property>
23 <property name="xalign">0</property>34 <child>
24 <property name="yalign">0</property>35 <object class="GtkLabel" id="intro_label">
25 <property name="label" translatable="yes">This guide will help you to add a new comic.36 <property name="visible">True</property>
2637 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
27To find comics suitable for adding, you may search the Internet for "comics rss".38 <property name="xalign">0</property>
2839 <property name="yalign">0</property>
29Press "next" to proceed.</property>40 <property name="label" translatable="yes">This guide will help you to add a new comic.</property>
30 <property name="wrap">True</property>41 <property name="use_markup">True</property>
42 <property name="wrap">True</property>
43 </object>
44 <packing>
45 <property name="position">0</property>
46 </packing>
47 </child>
48 <child>
49 <object class="GtkLabel" id="intro_label2">
50 <property name="visible">True</property>
51 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
52 <property name="xalign">0</property>
53 <property name="yalign">0</property>
54 <property name="label" translatable="yes">Please select how you want to add a comic:</property>
55 <property name="use_markup">True</property>
56 <property name="wrap">True</property>
57 </object>
58 <packing>
59 <property name="position">1</property>
60 </packing>
61 </child>
62 <child>
63 <placeholder/>
64 </child>
65 <child>
66 <placeholder/>
67 </child>
68 <child>
69 <object class="GtkAlignment" id="alignment1">
70 <property name="visible">True</property>
71 <property name="left_padding">12</property>
72 <child>
73 <object class="GtkVBox" id="vbox1">
74 <property name="visible">True</property>
75 <property name="spacing">6</property>
76 <child>
77 <object class="GtkRadioButton" id="list_radio">
78 <property name="label" translatable="yes">Select a comic from a list</property>
79 <property name="visible">True</property>
80 <property name="can_focus">True</property>
81 <property name="receives_default">False</property>
82 <property name="active">True</property>
83 <property name="draw_indicator">True</property>
84 <signal name="toggled" handler="on_radio_button_toggled"/>
85 </object>
86 <packing>
87 <property name="position">0</property>
88 </packing>
89 </child>
90 <child>
91 <object class="GtkRadioButton" id="url_radio">
92 <property name="label" translatable="yes">Add a comic by URL</property>
93 <property name="visible">True</property>
94 <property name="can_focus">True</property>
95 <property name="receives_default">False</property>
96 <property name="active">True</property>
97 <property name="draw_indicator">True</property>
98 <property name="group">list_radio</property>
99 </object>
100 <packing>
101 <property name="position">1</property>
102 </packing>
103 </child>
104 </object>
105 </child>
106 </object>
107 <packing>
108 <property name="position">4</property>
109 </packing>
110 </child>
31 </object>111 </object>
112 <packing>
113 <property name="expand">False</property>
114 <property name="fill">False</property>
115 <property name="position">1</property>
116 </packing>
32 </child>117 </child>
33 </object>118 </object>
34 <packing>119 <packing>
35 <property name="page_type">GTK_ASSISTANT_PAGE_INTRO</property>120 <property name="page_type">intro</property>
36 <property name="title" translatable="yes">Add Comic</property>121 <property name="title" translatable="yes">Add Comic</property>
37 <property name="sidebar_image">logo.svg</property>122 <property name="sidebar_image">logo.svg</property>
38 </packing>123 </packing>
39 </child>124 </child>
40 <child>125 <child>
126 <placeholder/>
127 </child>
128 <child>
41 <object class="GtkVBox" id="url_page">129 <object class="GtkVBox" id="url_page">
42 <property name="visible">True</property>130 <property name="visible">True</property>
43 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>131 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
44 <property name="spacing">10</property>132 <property name="border_width">12</property>
45 <child>133 <property name="spacing">12</property>
46 <object class="GtkHBox" id="url_page_hbox">134 <child>
47 <property name="visible">True</property>135 <object class="GtkVBox" id="url_box">
48 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>136 <property name="visible">True</property>
49 <property name="spacing">10</property>137 <child>
50 <child>138 <object class="GtkLabel" id="intro_label1">
51 <object class="GtkLabel" id="url_page_label">139 <property name="visible">True</property>
52 <property name="visible">True</property>140 <property name="can_focus">True</property>
53 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>141 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
54 <property name="xalign">1</property>142 <property name="xalign">0</property>
55 <property name="label" translatable="yes">Enter the URL of the RSS feed:</property>143 <property name="yalign">0</property>
56 </object>144 <property name="label" translatable="yes">Comics! needs either an RSS feed or a web page with a comic.
57 <packing>145
58 <property name="expand">False</property>146Comics from feeds contain several strips. You may find suitable feeds on dedicated comics websites like &lt;a href="http://www.gocomics.com/features/rsspage"&gt;gocomics.com&lt;/a&gt;.
59 <property name="fill">False</property>147
60 </packing>148Using a web page only the current comic is shown. You'll find suitable web pages e.g. at &lt;a href="http://www.comics.com/"&gt;comics.com&lt;/a&gt; or searching the web for "comics" or "webcomics".</property>
61 </child>149 <property name="use_markup">True</property>
62 <child>150 <property name="wrap">True</property>
63 <object class="GtkEntry" id="url_entry">151 </object>
64 <property name="visible">True</property>152 <packing>
65 <property name="can_focus">True</property>153 <property name="expand">False</property>
66 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>154 <property name="fill">False</property>
67 <property name="text">http://</property>155 <property name="position">0</property>
68 <signal handler="on_url_entry_changed" name="changed"/>156 </packing>
69 </object>157 </child>
70 <packing>158 <child>
71 <property name="position">1</property>159 <object class="GtkHBox" id="url_page_hbox">
72 </packing>160 <property name="visible">True</property>
73 </child>161 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
74 </object>162 <property name="spacing">10</property>
163 <child>
164 <object class="GtkLabel" id="url_page_label">
165 <property name="visible">True</property>
166 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
167 <property name="xalign">1</property>
168 <property name="label" translatable="yes">URL of the RSS feed or web page:</property>
169 </object>
170 <packing>
171 <property name="expand">False</property>
172 <property name="fill">False</property>
173 <property name="position">0</property>
174 </packing>
175 </child>
176 <child>
177 <object class="GtkEntry" id="url_entry">
178 <property name="visible">True</property>
179 <property name="can_focus">True</property>
180 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
181 <property name="invisible_char">&#x25CF;</property>
182 <property name="activates_default">True</property>
183 <property name="text">http://</property>
184 <signal name="changed" handler="on_url_entry_changed"/>
185 </object>
186 <packing>
187 <property name="position">1</property>
188 </packing>
189 </child>
190 </object>
191 <packing>
192 <property name="expand">False</property>
193 <property name="fill">False</property>
194 <property name="position">1</property>
195 </packing>
196 </child>
197 </object>
198 <packing>
199 <property name="expand">False</property>
200 <property name="fill">False</property>
201 <property name="position">0</property>
202 </packing>
203 </child>
204 <child>
205 <placeholder/>
206 </child>
207 <child>
208 <object class="GtkVBox" id="list_box">
209 <property name="visible">True</property>
210 <child>
211 <placeholder/>
212 </child>
213 <child>
214 <object class="GtkScrolledWindow" id="scrolledwindow1">
215 <property name="visible">True</property>
216 <property name="can_focus">True</property>
217 <property name="hscrollbar_policy">automatic</property>
218 <property name="vscrollbar_policy">automatic</property>
219 <child>
220 <object class="GtkTreeView" id="pre_list">
221 <property name="visible">True</property>
222 <property name="can_focus">True</property>
223 <property name="headers_visible">False</property>
224 <property name="rules_hint">True</property>
225 <child>
226 <object class="GtkTreeViewColumn" id="pre_col">
227 <property name="title">column</property>
228 <child>
229 <object class="GtkCellRendererText" id="cellrenderertext2"/>
230 <attributes>
231 <attribute name="text">0</attribute>
232 </attributes>
233 </child>
234 </object>
235 </child>
236 </object>
237 </child>
238 </object>
239 <packing>
240 <property name="position">1</property>
241 </packing>
242 </child>
243 </object>
244 <packing>
245 <property name="position">2</property>
246 </packing>
75 </child>247 </child>
76 </object>248 </object>
77 <packing>249 <packing>
@@ -79,9 +251,13 @@
79 </packing>251 </packing>
80 </child>252 </child>
81 <child>253 <child>
254 <placeholder/>
255 </child>
256 <child>
82 <object class="GtkVBox" id="wait_page">257 <object class="GtkVBox" id="wait_page">
83 <property name="visible">True</property>258 <property name="visible">True</property>
84 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>259 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
260 <property name="border_width">12</property>
85 <property name="spacing">10</property>261 <property name="spacing">10</property>
86 <child>262 <child>
87 <object class="GtkLabel" id="wait_label">263 <object class="GtkLabel" id="wait_label">
@@ -91,10 +267,13 @@
91 <property name="yalign">0</property>267 <property name="yalign">0</property>
92 <property name="wrap">True</property>268 <property name="wrap">True</property>
93 </object>269 </object>
270 <packing>
271 <property name="position">0</property>
272 </packing>
94 </child>273 </child>
95 </object>274 </object>
96 <packing>275 <packing>
97 <property name="page_type">GTK_ASSISTANT_PAGE_PROGRESS</property>276 <property name="page_type">progress</property>
98 <property name="title" translatable="yes">Downloading Comic</property>277 <property name="title" translatable="yes">Downloading Comic</property>
99 </packing>278 </packing>
100 </child>279 </child>
@@ -102,6 +281,7 @@
102 <object class="GtkVBox" id="image_page">281 <object class="GtkVBox" id="image_page">
103 <property name="visible">True</property>282 <property name="visible">True</property>
104 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>283 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
284 <property name="border_width">12</property>
105 <property name="spacing">10</property>285 <property name="spacing">10</property>
106 <child>286 <child>
107 <object class="GtkLabel" id="label_image_page">287 <object class="GtkLabel" id="label_image_page">
@@ -115,6 +295,7 @@
115 <packing>295 <packing>
116 <property name="expand">False</property>296 <property name="expand">False</property>
117 <property name="fill">False</property>297 <property name="fill">False</property>
298 <property name="position">0</property>
118 </packing>299 </packing>
119 </child>300 </child>
120 <child>301 <child>
@@ -122,16 +303,21 @@
122 <property name="visible">True</property>303 <property name="visible">True</property>
123 <property name="can_focus">True</property>304 <property name="can_focus">True</property>
124 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>305 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
125 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>306 <property name="hscrollbar_policy">automatic</property>
126 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>307 <property name="vscrollbar_policy">automatic</property>
127 <child>308 <child>
128 <object class="GtkIconView" id="image_list">309 <object class="GtkIconView" id="image_list">
129 <property name="visible">True</property>310 <property name="visible">True</property>
130 <property name="can_focus">True</property>311 <property name="can_focus">True</property>
131 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>312 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
132 <property name="pixbuf_column">1</property>
133 <property name="item_width">100</property>313 <property name="item_width">100</property>
134 <signal handler="on_image_list_selection_changed" name="selection_changed"/>314 <signal name="selection_changed" handler="on_image_list_selection_changed"/>
315 <child>
316 <object class="GtkCellRendererPixbuf" id="cellrenderertext"/>
317 <attributes>
318 <attribute name="pixbuf">1</attribute>
319 </attributes>
320 </child>
135 </object>321 </object>
136 </child>322 </child>
137 </object>323 </object>
@@ -148,6 +334,7 @@
148 <object class="GtkVBox" id="last_page">334 <object class="GtkVBox" id="last_page">
149 <property name="visible">True</property>335 <property name="visible">True</property>
150 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>336 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
337 <property name="border_width">12</property>
151 <property name="spacing">10</property>338 <property name="spacing">10</property>
152 <child>339 <child>
153 <object class="GtkLabel" id="last_label">340 <object class="GtkLabel" id="last_label">
@@ -159,12 +346,49 @@
159 <property name="wrap">True</property>346 <property name="wrap">True</property>
160 </object>347 </object>
161 <packing>348 <packing>
349 <property name="expand">False</property>
350 <property name="fill">False</property>
351 <property name="position">0</property>
352 </packing>
353 </child>
354 <child>
355 <object class="GtkHBox" id="name_box">
356 <property name="visible">True</property>
357 <property name="spacing">12</property>
358 <child>
359 <object class="GtkLabel" id="label1">
360 <property name="visible">True</property>
361 <property name="xalign">0</property>
362 <property name="label" translatable="yes">Name of the comic:</property>
363 </object>
364 <packing>
365 <property name="expand">False</property>
366 <property name="fill">False</property>
367 <property name="position">0</property>
368 </packing>
369 </child>
370 <child>
371 <object class="GtkEntry" id="name_entry">
372 <property name="visible">True</property>
373 <property name="can_focus">True</property>
374 <property name="invisible_char">&#x25CF;</property>
375 <property name="activates_default">True</property>
376 <signal name="changed" handler="on_name_entry_changed"/>
377 </object>
378 <packing>
379 <property name="position">1</property>
380 </packing>
381 </child>
382 </object>
383 <packing>
384 <property name="expand">False</property>
385 <property name="fill">False</property>
162 <property name="position">1</property>386 <property name="position">1</property>
163 </packing>387 </packing>
164 </child>388 </child>
165 </object>389 </object>
166 <packing>390 <packing>
167 <property name="page_type">GTK_ASSISTANT_PAGE_CONFIRM</property>391 <property name="page_type">confirm</property>
168 <property name="title" translatable="yes">Ready to add comic!</property>392 <property name="title" translatable="yes">Ready to add comic!</property>
169 </packing>393 </packing>
170 </child>394 </child>
171395
=== modified file 'applets/maintained/comics/ui/manage.ui'
--- applets/maintained/comics/ui/manage.ui 2010-01-26 03:46:15 +0000
+++ applets/maintained/comics/ui/manage.ui 2011-01-09 09:07:16 +0000
@@ -1,45 +1,60 @@
1<?xml version="1.0"?>1<?xml version="1.0"?>
2<!--Generated with glade3 3.4.0 on Thu Feb 21 11:35:04 2008 -->
3<interface>2<interface>
3 <!-- interface-requires gtk+ 2.12 -->
4 <!-- interface-naming-policy toplevel-contextual -->
4 <object class="GtkWindow" id="manage_window">5 <object class="GtkWindow" id="manage_window">
5 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>6 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
7 <property name="border_width">6</property>
6 <property name="title" translatable="yes">Manage comics</property>8 <property name="title" translatable="yes">Manage comics</property>
7 <property name="window_position">GTK_WIN_POS_CENTER</property>9 <property name="window_position">center</property>
8 <property name="default_width">300</property>
9 <property name="default_height">400</property>
10 <property name="icon">manage.svg</property>10 <property name="icon">manage.svg</property>
11 <child>11 <child>
12 <object class="GtkVBox" id="manage_window_vbox">12 <object class="GtkVBox" id="manage_window_vbox">
13 <property name="visible">True</property>13 <property name="visible">True</property>
14 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>14 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
15 <property name="border_width">2</property>15 <property name="border_width">2</property>
16 <property name="spacing">5</property>16 <property name="spacing">6</property>
17 <child>17 <child>
18 <object class="GtkLabel" id="manage_window_label">18 <placeholder/>
19 <property name="visible">True</property>
20 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
21 <property name="xalign">0</property>
22 <property name="yalign">0</property>
23 <property name="label" translatable="yes">The following comics are installed:</property>
24 </object>
25 <packing>
26 <property name="expand">False</property>
27 <property name="fill">False</property>
28 </packing>
29 </child>19 </child>
30 <child>20 <child>
31 <object class="GtkScrolledWindow" id="manage_window_scrolledwindow">21 <object class="GtkScrolledWindow" id="manage_window_scrolledwindow">
32 <property name="visible">True</property>22 <property name="visible">True</property>
33 <property name="can_focus">True</property>23 <property name="can_focus">True</property>
34 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>24 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
35 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>25 <property name="hscrollbar_policy">automatic</property>
36 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>26 <property name="vscrollbar_policy">automatic</property>
37 <child>27 <child>
38 <object class="GtkTreeView" id="comics_list">28 <object class="GtkTreeView" id="comics_list">
39 <property name="visible">True</property>29 <property name="visible">True</property>
40 <property name="can_focus">True</property>30 <property name="can_focus">True</property>
41 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>31 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
42 <property name="headers_visible">False</property>32 <property name="headers_clickable">False</property>
33 <property name="rules_hint">True</property>
34 <child>
35 <object class="GtkTreeViewColumn" id="toggle_col">
36 <property name="title">column</property>
37 <child>
38 <object class="GtkCellRendererToggle" id="cellrenderertoggle1">
39 <signal name="toggled" handler="on_feed_toggled"/>
40 </object>
41 <attributes>
42 <attribute name="active">0</attribute>
43 </attributes>
44 </child>
45 </object>
46 </child>
47 <child>
48 <object class="GtkTreeViewColumn" id="name_col">
49 <property name="title">column</property>
50 <child>
51 <object class="GtkCellRendererText" id="cellrenderertext1"/>
52 <attributes>
53 <attribute name="text">1</attribute>
54 </attributes>
55 </child>
56 </object>
57 </child>
43 </object>58 </object>
44 </child>59 </child>
45 </object>60 </object>
@@ -51,44 +66,55 @@
51 <object class="GtkHButtonBox" id="manage_window_hbuttonbox">66 <object class="GtkHButtonBox" id="manage_window_hbuttonbox">
52 <property name="visible">True</property>67 <property name="visible">True</property>
53 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>68 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
54 <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>69 <property name="border_width">6</property>
70 <property name="spacing">6</property>
71 <property name="layout_style">spread</property>
55 <child>72 <child>
56 <object class="GtkButton" id="add_button">73 <object class="GtkButton" id="add_button">
57 <property name="visible">True</property>
58 <property name="can_focus">True</property>
59 <property name="receives_default">True</property>
60 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
61 <property name="label">gtk-add</property>74 <property name="label">gtk-add</property>
75 <property name="visible">True</property>
76 <property name="can_focus">True</property>
77 <property name="receives_default">True</property>
78 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
62 <property name="use_stock">True</property>79 <property name="use_stock">True</property>
63 <signal handler="on_add_button_clicked" name="clicked"/>80 <signal name="clicked" handler="on_add_button_clicked"/>
64 </object>81 </object>
82 <packing>
83 <property name="expand">False</property>
84 <property name="fill">False</property>
85 <property name="position">0</property>
86 </packing>
65 </child>87 </child>
66 <child>88 <child>
67 <object class="GtkButton" id="remove_button">89 <object class="GtkButton" id="remove_button">
90 <property name="label">gtk-remove</property>
68 <property name="visible">True</property>91 <property name="visible">True</property>
69 <property name="sensitive">False</property>92 <property name="sensitive">False</property>
70 <property name="can_focus">True</property>93 <property name="can_focus">True</property>
71 <property name="receives_default">True</property>94 <property name="receives_default">True</property>
72 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>95 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
73 <property name="label">gtk-remove</property>
74 <property name="use_stock">True</property>96 <property name="use_stock">True</property>
75 <signal handler="on_remove_button_clicked" name="clicked"/>97 <signal name="clicked" handler="on_remove_button_clicked"/>
76 </object>98 </object>
77 <packing>99 <packing>
100 <property name="expand">False</property>
101 <property name="fill">False</property>
78 <property name="position">1</property>102 <property name="position">1</property>
79 </packing>103 </packing>
80 </child>104 </child>
81 <child>105 <child>
82 <object class="GtkButton" id="close_button">106 <object class="GtkButton" id="close_button">
83 <property name="visible">True</property>
84 <property name="can_focus">True</property>
85 <property name="receives_default">True</property>
86 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
87 <property name="label">gtk-close</property>107 <property name="label">gtk-close</property>
108 <property name="visible">True</property>
109 <property name="can_focus">True</property>
110 <property name="receives_default">True</property>
111 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
88 <property name="use_stock">True</property>112 <property name="use_stock">True</property>
89 <signal handler="on_close_button_clicked" name="clicked"/>113 <signal name="clicked" handler="on_close_button_clicked"/>
90 </object>114 </object>
91 <packing>115 <packing>
116 <property name="expand">False</property>
117 <property name="fill">False</property>
92 <property name="position">2</property>118 <property name="position">2</property>
93 </packing>119 </packing>
94 </child>120 </child>
95121
=== removed file 'applets/maintained/comics/ui/view.ui'
--- applets/maintained/comics/ui/view.ui 2010-03-25 12:38:35 +0000
+++ applets/maintained/comics/ui/view.ui 1970-01-01 00:00:00 +0000
@@ -1,154 +0,0 @@
1<?xml version="1.0"?>
2<interface>
3 <!-- interface-requires gtk+ 2.12 -->
4 <!-- interface-naming-policy toplevel-contextual -->
5 <object class="GtkUIManager" id="uimanager1">
6 <child>
7 <object class="GtkActionGroup" id="actiongroup1">
8 <child>
9 <object class="GtkAction" id="history_container">
10 <property name="stock_id">gtk-jump-to</property>
11 <property name="name">history_container</property>
12 </object>
13 </child>
14 <child>
15 <object class="GtkAction" id="size_container">
16 <property name="name">size_container</property>
17 <property name="label" translatable="yes">Size</property>
18 </object>
19 </child>
20 <child>
21 <object class="GtkAction" id="zoom_normal_item">
22 <property name="stock_id">gtk-zoom-100</property>
23 <property name="name">zoom_normal_item</property>
24 <signal handler="on_normal_activated" name="activate"/>
25 </object>
26 </child>
27 <child>
28 <object class="GtkAction" id="zoom_in_item">
29 <property name="stock_id">gtk-zoom-in</property>
30 <property name="name">zoom_in_item</property>
31 <signal handler="on_larger_activated" name="activate"/>
32 </object>
33 </child>
34 <child>
35 <object class="GtkAction" id="zoom_out_item">
36 <property name="stock_id">gtk-zoom-out</property>
37 <property name="name">zoom_out_item</property>
38 <signal handler="on_smaller_activated" name="activate"/>
39 </object>
40 </child>
41 <child>
42 <object class="GtkToggleAction" id="show_link_item">
43 <property name="name">show_link_item</property>
44 <property name="label" translatable="yes">Show link</property>
45 <signal handler="on_show_link_toggled" name="toggled"/>
46 </object>
47 </child>
48 <child>
49 <object class="GtkAction" id="save_as_item">
50 <property name="stock_id">gtk-save-as</property>
51 <property name="name">save_as_item</property>
52 <signal handler="on_save_as_activated" name="activate"/>
53 </object>
54 </child>
55 <child>
56 <object class="GtkAction" id="close_item">
57 <property name="stock_id">gtk-close</property>
58 <property name="name">close_item</property>
59 <signal handler="on_close_activated" name="activate"/>
60 </object>
61 </child>
62 </object>
63 </child>
64 <ui>
65 <popup name="history_menu">
66 <menu action="history_container"/>
67 <menu action="size_container">
68 <menuitem action="zoom_normal_item"/>
69 <menuitem action="zoom_in_item"/>
70 <menuitem action="zoom_out_item"/>
71 </menu>
72 <menuitem action="show_link_item"/>
73 <menuitem action="save_as_item"/>
74 <menuitem action="close_item"/>
75 </popup>
76 </ui>
77 </object>
78 <object class="GtkMenu" constructor="uimanager1" id="history_menu">
79 <property name="visible">True</property>
80 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
81 <signal handler="on_widget_show" name="show"/>
82 </object>
83 <object class="GtkFileChooserDialog" id="save_as_dialog">
84 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
85 <property name="border_width">5</property>
86 <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
87 <property name="icon">comics.svg</property>
88 <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
89 <property name="has_separator">False</property>
90 <property name="use_preview_label">False</property>
91 <property name="action">GTK_FILE_CHOOSER_ACTION_SAVE</property>
92 <property name="do_overwrite_confirmation">True</property>
93 <property name="preview_widget_active">False</property>
94 <child internal-child="vbox">
95 <object class="GtkVBox" id="save_as_dialog_vbox">
96 <property name="visible">True</property>
97 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
98 <property name="orientation">vertical</property>
99 <property name="spacing">2</property>
100 <child>
101 <object class="GtkComboBox" id="file_format_combo">
102 <property name="visible">True</property>
103 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
104 <signal handler="on_file_format_combo_changed" name="changed"/>
105 </object>
106 <packing>
107 <property name="expand">False</property>
108 <property name="fill">False</property>
109 <property name="position">2</property>
110 </packing>
111 </child>
112 <child internal-child="action_area">
113 <object class="GtkHButtonBox" id="action_area_hbuttonbox">
114 <property name="visible">True</property>
115 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
116 <property name="layout_style">end</property>
117 <child>
118 <object class="GtkButton" id="action_area_cancel">
119 <property name="visible">True</property>
120 <property name="can_focus">True</property>
121 <property name="receives_default">True</property>
122 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
123 <property name="label">gtk-cancel</property>
124 <property name="use_stock">True</property>
125 </object>
126 </child>
127 <child>
128 <object class="GtkButton" id="action_area_save">
129 <property name="visible">True</property>
130 <property name="can_focus">True</property>
131 <property name="receives_default">True</property>
132 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
133 <property name="label">gtk-save</property>
134 <property name="use_stock">True</property>
135 </object>
136 <packing>
137 <property name="position">1</property>
138 </packing>
139 </child>
140 </object>
141 <packing>
142 <property name="expand">False</property>
143 <property name="pack_type">end</property>
144 <property name="position">0</property>
145 </packing>
146 </child>
147 </object>
148 </child>
149 <action-widgets>
150 <action-widget response="0">action_area_cancel</action-widget>
151 <action-widget response="1">action_area_save</action-widget>
152 </action-widgets>
153 </object>
154</interface>
1550
=== removed file 'applets/unmaintained/comic/Makefile.am'
--- applets/unmaintained/comic/Makefile.am 2009-02-01 00:13:07 +0000
+++ applets/unmaintained/comic/Makefile.am 1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
1APPLET_NAME = comic
2APPLET_MAIN_FILE = comic.py
3include $(top_srcdir)/Makefile.python-applet
4
5dist_applet_DATA = \
6 comicdialog.py \
7 getben.py \
8 getborn.py \
9 getdilbert.py \
10 getferdnand.py \
11 getgarfield.py \
12 getnancy.py \
13 getpcnp.py \
14 getpeanuts.py \
15 getpickles.py \
16 getuf.py \
17 getxkcd.py \
18 getwiz.py \
19 $(NULL)
20
21comic_iconsdir = $(applet_datadir)/icons
22dist_comic_icons_DATA = \
23 icons/comic-applet.png \
24 $(NULL)
250
=== removed file 'applets/unmaintained/comic/comic.desktop.in'
--- applets/unmaintained/comic/comic.desktop.in 2009-10-06 19:42:48 +0000
+++ applets/unmaintained/comic/comic.desktop.in 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1[Desktop Entry]
2Version=1.0
3_Name=Dilbert Applet
4Type=Application
5X-AWN-Type=Applet
6X-AWN-AppletType=Python
7_Comment=Read Dilbert and other comics
8Exec=awn-applet -p %k
9X-AWN-AppletExec=comic/comic.py
10Icon=comic/icons/comic-applet.png
11X-AWN-AppletCategory=Network,News,Amusement
120
=== removed file 'applets/unmaintained/comic/comic.py'
--- applets/unmaintained/comic/comic.py 2009-08-14 13:00:22 +0000
+++ applets/unmaintained/comic/comic.py 1970-01-01 00:00:00 +0000
@@ -1,226 +0,0 @@
1#!/usr/bin/python
2# -*- coding: iso-8859-15 -*-
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16#
17# Name: comic.py
18# Version: .5.
19# Date: 10-15-07
20# Description: A python Applet for the avant-windows-navigator to display comic strips.
21#
22# Authors: cj13
23# pavpanchekha
24
25import sys, os
26import gobject
27import gtk
28import awn
29import comicdialog
30#default comic
31GETWHAT = 'getdilbert.py'
32showhover = False
33
34class App (awn.AppletSimple):
35 titleText = "Daily Comic"
36 visible = False
37
38 def __init__ (self, uid, orient, height):
39 awn.AppletSimple.__init__ (self, uid, orient, height)
40 self.set_awn_icon('comic', 'comic-applet')
41
42 self.title = awn.awn_title_get_default ()
43 self.dialog = awn.AppletDialog (self)
44 self.connect ("button-press-event", self.button_press)
45 self.connect ("enter-notify-event", self.enter_notify)
46 self.connect ("leave-notify-event", self.leave_notify)
47 self.dialog.connect ("focus-out-event", self.dialog_focus_out)
48
49 # Setup popup menu
50 self.popup_menu = self.create_default_menu()
51 dil_item = gtk.MenuItem("Dilbert")
52 pnut_item = gtk.MenuItem("Peanuts")
53 born_item = gtk.MenuItem("The Born Loser")
54 ben_item = gtk.MenuItem("Ben")
55 ferdnand_item = gtk.MenuItem("Ferdnand")
56 nancy_item = gtk.MenuItem("Nancy")
57 pickles_item = gtk.MenuItem("Pickles")
58 garfield_item = gtk.MenuItem("Garfield")
59 uf_item = gtk.MenuItem("User Friendly")
60 wiz_item = gtk.MenuItem("Wizard of ID")
61 xkcd_item = gtk.MenuItem("xkcd")
62 showho_item = gtk.CheckMenuItem("Hide Strip on Hover")
63 self.popup_menu.append(dil_item)
64 self.popup_menu.append(pnut_item)
65 self.popup_menu.append(born_item)
66 self.popup_menu.append(ben_item)
67 self.popup_menu.append(ferdnand_item)
68 self.popup_menu.append(nancy_item)
69 self.popup_menu.append(pickles_item)
70 self.popup_menu.append(garfield_item)
71 self.popup_menu.append(uf_item)
72 self.popup_menu.append(wiz_item)
73 self.popup_menu.append(xkcd_item)
74 self.popup_menu.append(showho_item)
75 dil_item.connect_object("activate",self.dil_callback,self)
76 pnut_item.connect_object("activate",self.pnut_callback,self)
77 born_item.connect_object("activate",self.born_callback,self)
78 ben_item.connect_object("activate",self.ben_callback,self)
79 ferdnand_item.connect_object("activate",self.ferdnand_callback,self)
80 nancy_item.connect_object("activate",self.nancy_callback,self)
81 pickles_item.connect_object("activate",self.pickles_callback,self)
82 garfield_item.connect_object("activate",self.garfield_callback,self)
83 uf_item.connect_object("activate",self.uf_callback,self)
84 wiz_item.connect_object("activate",self.wiz_callback,self)
85 xkcd_item.connect_object("activate",self.xkcd_callback,self)
86 showho_item.connect_object("activate",self.showho_callback,self)
87 dil_item.show()
88 pnut_item.show()
89 born_item.show()
90 ben_item.show()
91 ferdnand_item.show()
92 nancy_item.show()
93 pickles_item.show()
94 garfield_item.show()
95 uf_item.show()
96 wiz_item.show()
97 xkcd_item.show()
98 showho_item.show()
99
100 self.build_dialog()
101
102
103 def build_dialog(self):
104 #print "Getting Comic"
105
106 getit = 'python ' + os.path.dirname (__file__) + '/' + GETWHAT
107 os.system(getit)
108
109 self.dialog = awn.AppletDialog (self)
110 self.dialog.set_title("Comic")
111
112 box = gtk.VBox()
113 comic = comicdialog.ComicDialog()
114 box.pack_start(comic,False,False,0)
115 box.show_all()
116 self.dialog.add(box)
117
118 self.timer = gobject.timeout_add (3600000, self.build_dialog)
119
120
121 def button_press (self, widget, event):
122 if event.button == 3:
123 # right click
124 self.title.hide(self)
125 self.visible = False
126 self.dialog.hide()
127 self.popup_menu.popup(None, None, None, event.button, event.time)
128 elif event.button == 1:
129 if self.visible:
130 self.dialog.hide()
131 self.title.hide(self)
132 else:
133 self.title.hide(self)
134 self.dialog.show_all()
135 self.visible = not self.visible
136
137
138 def dil_callback(self, widget):
139 global GETWHAT
140 GETWHAT = 'getdilbert.py'
141 self.build_dialog()
142
143
144 def pnut_callback(self, widget):
145 global GETWHAT
146 GETWHAT = 'getpeanuts.py'
147 self.build_dialog()
148
149 def born_callback(self, widget):
150 global GETWHAT
151 GETWHAT = 'getborn.py'
152 self.build_dialog()
153
154 def ben_callback(self, widget):
155 global GETWHAT
156 GETWHAT = 'getben.py'
157 self.build_dialog()
158
159 def ferdnand_callback(self, widget):
160 global GETWHAT
161 GETWHAT = 'getferdnand.py'
162 self.build_dialog()
163
164 def nancy_callback(self, widget):
165 global GETWHAT
166 GETWHAT = 'getnancy.py'
167 self.build_dialog()
168
169 def pickles_callback(self, widget):
170 global GETWHAT
171 GETWHAT = 'getpickles.py'
172 self.build_dialog()
173
174 def garfield_callback(self, widget):
175 global GETWHAT
176 GETWHAT = 'getgarfield.py'
177 self.build_dialog()
178
179 def uf_callback(self, widget):
180 global GETWHAT
181 GETWHAT = 'getuf.py'
182 self.build_dialog()
183
184 def wiz_callback(self, widget):
185 global GETWHAT
186 GETWHAT = 'getwiz.py'
187 self.build_dialog()
188
189 def xkcd_callback(self, widget):
190 global GETWHAT
191 GETWHAT = 'getxkcd.py'
192 self.build_dialog()
193
194 def showho_callback(self, widget):
195 global showhover
196 showhover = not showhover
197
198
199 def dialog_focus_out (self, widget, event):
200 self.visible = False
201 self.dialog.hide()
202
203
204 def enter_notify (self, widget, event):
205 global showhover
206 self.title.show (self, self.titleText)
207 if showhover:
208 self.title.hide(self)
209 self.dialog.show_all()
210 self.visible = False
211
212 def leave_notify (self, widget, event):
213 global showhover
214 self.title.hide(self)
215 if showhover:
216 self.dialog.hide()
217 self.visible = False
218
219
220if __name__ == "__main__":
221 awn.init (sys.argv[1:])
222 #print "main %s %d %d" % (awn.uid, awn.orient, awn.height)
223 applet = App(awn.uid, awn.orient, awn.height)
224 awn.embed_applet(applet)
225 applet.show_all()
226 gtk.main()
2270
=== removed file 'applets/unmaintained/comic/comicdialog.py'
--- applets/unmaintained/comic/comicdialog.py 2008-08-23 00:52:27 +0000
+++ applets/unmaintained/comic/comicdialog.py 1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
1#!/usr/bin/python
2# -*- coding: iso-8859-15 -*-
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16#
17# Name: comic.py
18# Version: .5.
19# Date: 10-15-07
20# Description: A python Applet for the avant-windows-navigator to display comic strips.
21#
22# Authors: cj13
23#
24import gtk
25from gtk import gdk
26import cairo
27
28class ComicDialog(gtk.DrawingArea):
29 def __init__(self):
30 gtk.DrawingArea.__init__(self)
31 self.connect("expose_event", self.expose)
32
33 def expose(self,widget,event):
34 icon_name = '/tmp/dilbert.gif'
35 icon = gdk.pixbuf_new_from_file(icon_name)
36 dim = [icon.get_width(),icon.get_height()]
37 self.set_size_request(dim[0], dim[1])
38
39 context = widget.window.cairo_create()
40 context.set_source_rgb(0,0,0)
41
42 context.set_source_pixbuf(icon,1,1)
43 context.fill()
44 context.paint()
45 return False
46
470
=== removed file 'applets/unmaintained/comic/getben.py'
--- applets/unmaintained/comic/getben.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getben.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_bornloser_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://www.comics.com/ben/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y-%m-%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getborn.py'
--- applets/unmaintained/comic/getborn.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getborn.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_bornloser_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://comics.com/the_born_loser/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getdilbert.py'
--- applets/unmaintained/comic/getdilbert.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getdilbert.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_dilbert_strips.py -- fetch dilbert strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.strip\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.strip\\.sunday\\.gif')
41temp1 = 'http://dilbert.com/%s/'
42temp2 = 'http://dilbert.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y-%m-%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getferdnand.py'
--- applets/unmaintained/comic/getferdnand.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getferdnand.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_bornloser_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://comics.com/ferdnand/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getgarfield.py'
--- applets/unmaintained/comic/getgarfield.py 2009-01-16 17:07:28 +0000
+++ applets/unmaintained/comic/getgarfield.py 1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# getgarfield.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39temp = 'http://picayune.uclick.com/comics/ga/%s/ga%s.%s'
40
41date = datetime.today()
42one_day = timedelta(1)
43
44for i in range(number_of_days):
45
46 giforjpg = 'gif'
47
48 url = temp % (date.strftime('%Y'),date.strftime('%y%m%d'),giforjpg)
49 print '+ %s' % (url)
50 fil = urllib.urlopen(url)
51 diskfile = file(path_prefix + 'dilbert.gif', 'w')
52 diskfile.write(fil.read())
53 fil.close()
54 diskfile.close()
55
56 date = date - one_day
570
=== removed file 'applets/unmaintained/comic/getnancy.py'
--- applets/unmaintained/comic/getnancy.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getnancy.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_bornloser_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://www.comics.com/nancy/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getpcnp.py'
--- applets/unmaintained/comic/getpcnp.py 2008-08-23 00:52:27 +0000
+++ applets/unmaintained/comic/getpcnp.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_pcnpixel_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('pcnpixel\\d+\\.gif')
40pattern2 = re.compile('pcnpixel\\d+\\.jpg')
41temp1 = 'http://www.snoopy.com/wash/pcnpixel%s.html'
42temp2 = 'http://www.snoopy.com/wash/pcnpixel/archive/images/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getpeanuts.py'
--- applets/unmaintained/comic/getpeanuts.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getpeanuts.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_peanuts_strips.py -- fetch peanuts strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://comics.com/peanuts/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getpickles.py'
--- applets/unmaintained/comic/getpickles.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getpickles.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_bornloser_strips.py -- fetch strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://www.comics.com/pickles/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y-%m-%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== renamed file 'applets/unmaintained/comic/getuf.py' => 'applets/unmaintained/comic/getuf.py.THIS'
=== removed file 'applets/unmaintained/comic/getwiz.py'
--- applets/unmaintained/comic/getwiz.py 2008-11-21 20:19:36 +0000
+++ applets/unmaintained/comic/getwiz.py 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# get_wizofid_strips.py -- fetch wizofids strips of last N days
18
19################################################################
20# BEGIN configuration
21
22number_of_days = 1
23
24path_prefix = '/tmp/' # where do you want to save the files?
25
26# --END configuration
27################################################################
28
29import sys
30import urllib
31import re
32
33from string import join
34from datetime import datetime, timedelta
35
36if len(sys.argv) > 1:
37 number_of_days = int(sys.argv[1])
38
39pattern = re.compile('str_strip[0-9/]+\\.full\\.gif')
40pattern2 = re.compile('str_strip[0-9/]+\\.full\\.jpg')
41temp1 = 'http://comics.com/wizard_of_id/%s/'
42temp2 = 'http://assets.comics.com/dyn/%s'
43
44date = datetime.today()
45one_day = timedelta(1)
46
47filename = None
48
49for i in range(number_of_days):
50 url = temp1 % (date.strftime('%Y%m%d'))
51 #print '? %s' % (url)
52 fil = urllib.urlopen(url)
53 for line in fil:
54 match = pattern.search(line)
55 if match != None:
56 filename = match.group()
57 break
58 else:
59 match2 = pattern2.search(line)
60 if match2 != None:
61 filename = match2.group()
62 break
63 fil.close()
64
65 if filename != None:
66 url = temp2 % (filename)
67 #print '+ %s' % (url)
68 fil = urllib.urlopen(url)
69 diskfile = file(path_prefix + 'dilbert.gif', 'w')
70 diskfile.write(fil.read())
71 fil.close()
72 diskfile.close()
73
74 date = date - one_day
75 filename = None
760
=== removed file 'applets/unmaintained/comic/getxkcd.py'
--- applets/unmaintained/comic/getxkcd.py 2008-08-23 00:52:27 +0000
+++ applets/unmaintained/comic/getxkcd.py 1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
1#!/usr/bin/python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License version 2 as
5# published by the Free Software Foundation
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16################################################################
17# getxkcd.py -- fetch last (current) xkcd strip
18
19################################################################
20# BEGIN configuration
21
22
23path_prefix = '/tmp/' # where do you want to save the files?
24
25# --END configuration
26################################################################
27
28import urllib
29import re
30
31
32comic = urllib.urlopen("http://www.xkcd.com/")
33link = re.compile("http://imgs.xkcd.com/comics/.*png").search(comic.read(),1)
34fil = urllib.urlopen(link.group())
35
36diskfile = file(path_prefix + 'dilbert.gif', 'w')
37diskfile.write(fil.read())
38fil.close()
39diskfile.close()
40
410
=== removed directory 'applets/unmaintained/comic/icons'
=== removed file 'applets/unmaintained/comic/icons/comic-applet.png'
42Binary files applets/unmaintained/comic/icons/comic-applet.png 2008-07-18 02:16:24 +0000 and applets/unmaintained/comic/icons/comic-applet.png 1970-01-01 00:00:00 +0000 differ1Binary files applets/unmaintained/comic/icons/comic-applet.png 2008-07-18 02:16:24 +0000 and applets/unmaintained/comic/icons/comic-applet.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'debian/awn-applets-python-extras-trunk.install'
--- debian/awn-applets-python-extras-trunk.install 2010-09-30 16:12:44 +0000
+++ debian/awn-applets-python-extras-trunk.install 2011-01-09 09:07:16 +0000
@@ -49,9 +49,6 @@
49# Disabled applets #49# Disabled applets #
50####################50####################
51#51#
52#usr/share/avant-window-navigator/applets/comic/
53#usr/share/avant-window-navigator/applets/comic.desktop
54#
55# Rtm52# Rtm
56#53#
57#usr/share/avant-window-navigator/applets/rtm/54#usr/share/avant-window-navigator/applets/rtm/
5855
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2010-10-22 17:00:33 +0000
+++ po/POTFILES.in 2011-01-09 09:07:16 +0000
@@ -43,7 +43,6 @@
43applets/maintained/comics/feed/__init__.py43applets/maintained/comics/feed/__init__.py
44[type: gettext/glade]applets/maintained/comics/ui/add.ui44[type: gettext/glade]applets/maintained/comics/ui/add.ui
45[type: gettext/glade]applets/maintained/comics/ui/manage.ui45[type: gettext/glade]applets/maintained/comics/ui/manage.ui
46[type: gettext/glade]applets/maintained/comics/ui/view.ui
47applets/maintained/comics/main.py46applets/maintained/comics/main.py
48applets/maintained/common-folder/common-folder.desktop.in47applets/maintained/common-folder/common-folder.desktop.in
49applets/maintained/common-folder/common-folder.py48applets/maintained/common-folder/common-folder.py
5049
=== modified file 'po/POTFILES.skip'
--- po/POTFILES.skip 2010-10-15 18:18:48 +0000
+++ po/POTFILES.skip 2011-01-09 09:07:16 +0000
@@ -26,7 +26,6 @@
26# Disabled applets26# Disabled applets
27#27#
28applets/maintained/rtm/rtm.desktop.in28applets/maintained/rtm/rtm.desktop.in
29applets/unmaintained/comic/comic.desktop.in
30applets/unmaintained/dropper/awn-applet-dropper.schema-ini.in29applets/unmaintained/dropper/awn-applet-dropper.schema-ini.in
31applets/unmaintained/dropper/dropper.desktop.in30applets/unmaintained/dropper/dropper.desktop.in
32applets/unmaintained/dropper/dropper-prefs.ui31applets/unmaintained/dropper/dropper-prefs.ui

Subscribers

People subscribed via source and target branches