Merge lp:~frederik-elwert/lens-cooking/chefkoch-scope into lp:lens-cooking
- chefkoch-scope
- Merge into lens-cooking
Proposed by
Frederik Elwert
Status: | Merged |
---|---|
Approved by: | Eduard Gotwig |
Approved revision: | 44 |
Merge reported by: | Eduard Gotwig |
Merged at revision: | not available |
Proposed branch: | lp:~frederik-elwert/lens-cooking/chefkoch-scope |
Merge into: | lp:lens-cooking |
Diff against target: |
331 lines (+233/-13) 8 files modified
chefkoch.scope (+3/-0) chefkoch.svg (+71/-0) debian/unity-lens-cooking.install (+7/-4) setup.py (+9/-2) unity-lens-cooking (+7/-5) unity-scope-chefkoch (+131/-0) unity-scope-chefkoch.service (+3/-0) unity-scope-gourmet (+2/-2) |
To merge this branch: | bzr merge lp:~frederik-elwert/lens-cooking/chefkoch-scope |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eduard Gotwig | Approve | ||
Review via email: mp+106897@code.launchpad.net |
Commit message
Description of the change
Added scope for chefkoch.de and added this as a new category to the lens.
To post a comment you must log in.
Revision history for this message
Eduard Gotwig (gotwig) wrote : | # |
I am going to merge this in 5 hours.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'chefkoch.scope' |
2 | --- chefkoch.scope 1970-01-01 00:00:00 +0000 |
3 | +++ chefkoch.scope 2012-05-22 20:35:21 +0000 |
4 | @@ -0,0 +1,3 @@ |
5 | +[Scope] |
6 | +DBusName=net.launchpad.scope.cooking.chefkoch |
7 | +DBusPath=/net/launchpad/scope/cooking/chefkoch |
8 | |
9 | === added file 'chefkoch.svg' |
10 | --- chefkoch.svg 1970-01-01 00:00:00 +0000 |
11 | +++ chefkoch.svg 2012-05-22 20:35:21 +0000 |
12 | @@ -0,0 +1,71 @@ |
13 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
14 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
15 | + |
16 | +<svg |
17 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
18 | + xmlns:cc="http://creativecommons.org/ns#" |
19 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
20 | + xmlns:svg="http://www.w3.org/2000/svg" |
21 | + xmlns="http://www.w3.org/2000/svg" |
22 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
23 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
24 | + width="32.625004" |
25 | + height="28.500004" |
26 | + id="svg3018" |
27 | + version="1.1" |
28 | + inkscape:version="0.48.3.1 r9886" |
29 | + sodipodi:docname="chefkoch.svg"> |
30 | + <defs |
31 | + id="defs3020" /> |
32 | + <sodipodi:namedview |
33 | + id="base" |
34 | + pagecolor="#ffffff" |
35 | + bordercolor="#666666" |
36 | + borderopacity="1.0" |
37 | + inkscape:pageopacity="0.0" |
38 | + inkscape:pageshadow="2" |
39 | + inkscape:zoom="2.8" |
40 | + inkscape:cx="0.096507634" |
41 | + inkscape:cy="4.5050419" |
42 | + inkscape:document-units="px" |
43 | + inkscape:current-layer="layer1" |
44 | + showgrid="false" |
45 | + fit-margin-top="0" |
46 | + fit-margin-left="0" |
47 | + fit-margin-right="0" |
48 | + fit-margin-bottom="0" |
49 | + inkscape:window-width="1301" |
50 | + inkscape:window-height="744" |
51 | + inkscape:window-x="65" |
52 | + inkscape:window-y="24" |
53 | + inkscape:window-maximized="1" /> |
54 | + <metadata |
55 | + id="metadata3023"> |
56 | + <rdf:RDF> |
57 | + <cc:Work |
58 | + rdf:about=""> |
59 | + <dc:format>image/svg+xml</dc:format> |
60 | + <dc:type |
61 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
62 | + <dc:title></dc:title> |
63 | + </cc:Work> |
64 | + </rdf:RDF> |
65 | + </metadata> |
66 | + <g |
67 | + inkscape:label="Ebene 1" |
68 | + inkscape:groupmode="layer" |
69 | + id="layer1" |
70 | + transform="translate(-335.3125,-518.46875)"> |
71 | + <path |
72 | + inkscape:connector-curvature="0" |
73 | + id="path3219" |
74 | + d="m 342.15481,519.26909 c -3.31663,-0.003 -6.00944,2.58203 -6.01217,5.77118 -0.002,2.7707 2.02629,5.09149 4.7339,5.65418 l -0.0132,15.43625 21.50651,0.0183 0.0132,-15.43622 c 2.70857,-0.55807 4.74117,-2.8754 4.74353,-5.64609 0.003,-3.18916 -2.68563,-5.77862 -6.00229,-5.78146 -1.9333,-0.002 -3.65477,0.87481 -4.75521,2.23917 -1.09836,-1.36232 -2.80673,-2.24563 -4.73683,-2.24728 -1.92681,-0.002 -3.63969,0.86865 -4.74061,2.22516 -1.09859,-1.35838 -2.80999,-2.23161 -4.73683,-2.23325 z" |
75 | + style="fill:#eef4f3;fill-opacity:1;fill-rule:evenodd;stroke:#4c6f0f;stroke-width:1.62983214999999992;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" /> |
76 | + <path |
77 | + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#4c6f0f;stroke-width:1.62999999999999967;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" |
78 | + d="m 340.73707,540.8274 21.38024,0.0183" |
79 | + id="path4436" |
80 | + inkscape:connector-curvature="0" |
81 | + sodipodi:nodetypes="cc" /> |
82 | + </g> |
83 | +</svg> |
84 | |
85 | === modified file 'debian/unity-lens-cooking.install' |
86 | --- debian/unity-lens-cooking.install 2012-04-06 14:37:30 +0000 |
87 | +++ debian/unity-lens-cooking.install 2012-05-22 20:35:21 +0000 |
88 | @@ -1,15 +1,18 @@ |
89 | build/share/unity/lenses/cooking/cooking.lens /usr/share/unity/lenses/cooking |
90 | cooking.svg /usr/share/unity/lenses/cooking |
91 | recipefy.png /usr/share/unity/lenses/cooking/icons |
92 | +chefkoch.svg /usr/share/unity/lenses/cooking/icons |
93 | gourmet.png /usr/share/unity/lenses/cooking/icons |
94 | cuisine.png /usr/share/unity/lenses/cooking/icons |
95 | +unity-lens-cooking /usr/share/unity/lenses/cooking |
96 | +unity-lens-cooking.service /usr/share/dbus-1/services |
97 | recipefy.scope /usr/share/unity/lenses/cooking |
98 | -unity-lens-cooking /usr/share/unity/lenses/cooking |
99 | unity-scope-recipefy /usr/share/unity/lenses/cooking |
100 | -unity-lens-cooking.service /usr/share/dbus-1/services |
101 | unity-scope-recipefy.service /usr/share/dbus-1/services |
102 | +chefkoch.scope /usr/share/unity/lenses/cooking |
103 | +unity-scope-chefkoch /usr/share/unity/lenses/cooking |
104 | +unity-scope-chefkoch.service /usr/share/dbus-1/services |
105 | +gourmet.scope /usr/share/unity/lenses/cooking |
106 | unity-scope-gourmet /usr/share/unity/lenses/cooking |
107 | unity-scope-gourmet.service /usr/share/dbus-1/services |
108 | -gourmet.scope /usr/share/unity/lenses/cooking |
109 | build/mo/* /usr/share/locale |
110 | - |
111 | |
112 | === modified file 'setup.py' |
113 | --- setup.py 2012-04-04 20:42:32 +0000 |
114 | +++ setup.py 2012-05-22 20:35:21 +0000 |
115 | @@ -14,10 +14,17 @@ |
116 | ['unity-lens-cooking', |
117 | 'unity-scope-gourmet', |
118 | 'unity-scope-recipefy', |
119 | - 'cooking.svg',]), |
120 | + 'unity-scope-chefkoch', |
121 | + 'chefkoch.svg', |
122 | + 'cooking.svg', |
123 | + 'cuisine.png', |
124 | + 'gourmet.png', |
125 | + ]), |
126 | ('share/dbus-1/services', |
127 | ['unity-lens-cooking.service', |
128 | 'unity-scope-gourmet.service', |
129 | - 'unity-scope-recipefy.service',]), |
130 | + 'unity-scope-recipefy.service', |
131 | + 'unity-scope-chefkoch.service', |
132 | + ]), |
133 | ], cmdclass={"build": build_extra.build_extra, |
134 | "build_i18n": build_i18n.build_i18n,}) |
135 | |
136 | === modified file 'unity-lens-cooking' |
137 | --- unity-lens-cooking 2012-04-05 14:39:09 +0000 |
138 | +++ unity-lens-cooking 2012-05-22 20:35:21 +0000 |
139 | @@ -1,6 +1,6 @@ |
140 | #! /usr/bin/python |
141 | # -*- coding: utf-8 -*- |
142 | -# Copyright 2012 Eduard Gotwig |
143 | +# Copyright 2012 Eduard Gotwig, Frederik Elwert <frederik.elwert@web.de> |
144 | # License: GPLv3 |
145 | |
146 | from gi.repository import GLib, GObject, Gio |
147 | @@ -23,8 +23,9 @@ |
148 | # Translatable strings |
149 | |
150 | |
151 | -ONLINE = _("Recipefy Recipes") |
152 | -LOCAL = _("Gourmet Recipes") |
153 | +RECIPEFY = _("Recipefy Recipes") |
154 | +CHEFKOCH = _("Chefkoch Recipes") |
155 | +GOURMET = _("Gourmet Recipes") |
156 | |
157 | LIKES = _("Likes") |
158 | TIME = _("Time") |
159 | @@ -60,8 +61,9 @@ |
160 | ### Then, we populate the categories |
161 | cats = [] |
162 | # A category is a display name, an icon and a renderer |
163 | - cats.append (Unity.Category.new (ONLINE,Gio.ThemedIcon.new("/usr/share/unity/lenses/cooking/icons/recipefy.png"),Unity.CategoryRenderer.HORIZONTAL_TILE)) |
164 | - cats.append (Unity.Category.new (LOCAL,Gio.ThemedIcon.new("/usr/share/unity/lenses/cooking/icons/gourmet.png"),Unity.CategoryRenderer.HORIZONTAL_TILE)) |
165 | + cats.append (Unity.Category.new (RECIPEFY,Gio.ThemedIcon.new("/usr/share/unity/lenses/cooking/icons/recipefy.png"),Unity.CategoryRenderer.HORIZONTAL_TILE)) |
166 | + cats.append (Unity.Category.new (CHEFKOCH,Gio.ThemedIcon.new("/usr/share/unity/lenses/cooking/icons/chefkoch.svg"),Unity.CategoryRenderer.HORIZONTAL_TILE)) |
167 | + cats.append (Unity.Category.new (GOURMET,Gio.ThemedIcon.new("/usr/share/unity/lenses/cooking/icons/gourmet.png"),Unity.CategoryRenderer.HORIZONTAL_TILE)) |
168 | self._lens.props.categories = cats |
169 | ### Populate filters NOT IN USE FOR NOW |
170 | """filters = [] |
171 | |
172 | === added file 'unity-scope-chefkoch' |
173 | --- unity-scope-chefkoch 1970-01-01 00:00:00 +0000 |
174 | +++ unity-scope-chefkoch 2012-05-22 20:35:21 +0000 |
175 | @@ -0,0 +1,131 @@ |
176 | +#! /usr/bin/python |
177 | +# -*- coding: utf-8 -*- |
178 | +# Copyright 2012 Eduard Gotwig, Frederik Elwert <frederik.elwert@web.de> |
179 | +# License: GPLv3 |
180 | + |
181 | +from gi.repository import GLib, GObject, Gio |
182 | +from gi.repository import Dee |
183 | +from gi.repository import Unity |
184 | +import lxml.html |
185 | +import os |
186 | +import re |
187 | +import gettext |
188 | +import locale |
189 | +import sys |
190 | + |
191 | +APP_NAME="unity-lens-cooking" |
192 | +LOCAL_PATH="/usr/share/locale" |
193 | + |
194 | +gettext.bindtextdomain(APP_NAME, LOCAL_PATH) |
195 | +gettext.textdomain(APP_NAME) |
196 | +_ = gettext.gettext |
197 | + |
198 | +RUNNING = _("Failed to own name %s. Bailing out. An other instance is already running!") |
199 | + |
200 | +FULLSTAR_RE = re.compile(r'suche-scrore-(\d).gif') |
201 | +HALFSTAR_RE = re.compile(r'suche-scrore-(\d)_(\d).gif') |
202 | + |
203 | +# The scope dbus id |
204 | +BUS_NAME = "net.launchpad.scope.cooking.chefkoch" |
205 | + |
206 | +class Daemon: |
207 | + def __init__ (self): |
208 | + # Create the scope (this matches the path defined in the .scope file) |
209 | + self.scope = Unity.Scope.new ("/net/launchpad/scope/cooking/chefkoch") |
210 | + # Is the scope searchable from the home dash? |
211 | + self.scope.search_in_global = False |
212 | + # Connect to the search changed signal (it is fired when the lens is opened for the first time, then for each search change) |
213 | + self.scope.connect ("search-changed", self.on_search_changed) |
214 | + # Listen to the lens filters |
215 | + self.scope.connect ("filters-changed", lambda scope : scope.queue_search_changed(Unity.SearchType.DEFAULT)) |
216 | + # The scope is ready |
217 | + self.scope.export() |
218 | + # On each search change, this method is called |
219 | + def on_search_changed (self, scope, search, search_type, cancellable): |
220 | + # Get the search string |
221 | + search_string = search.props.search_string.strip() |
222 | + print "Search changed to \"%s\"" % search_string |
223 | + # Get the Dee model (the database used by the lens to store and display search results) |
224 | + model = search.props.results_model |
225 | + # Empty the model |
226 | + model.clear() |
227 | + # Update the model |
228 | + self.update_results_model (search_string, model) |
229 | + # Signal to the lens that the search is finished (the spinning search icon stops) |
230 | + search.finished() |
231 | + |
232 | + # Update the model |
233 | + def update_results_model(self, search, model): |
234 | + self.chefkoch(search, model) |
235 | + |
236 | + # This method sends the search string to chefkoch and brings back results |
237 | + def chefkoch_search(self,search): |
238 | + # Search for recipes over GET |
239 | + url = ("http://www.chefkoch.de/rs/s0/%s/Rezepte.html" % (search)) |
240 | + print "Searching for Recipes at %s" % url |
241 | + tree = lxml.html.parse(url) |
242 | + tree.getroot().make_links_absolute() |
243 | + items = tree.xpath("//table[@class='result']//tr[@bgcolor]") |
244 | + print 'Got %d results' % len(items) |
245 | + return items |
246 | + # This method parses the results and adds them to the model |
247 | + def chefkoch(self, search, model): |
248 | + # Skip empty search |
249 | + if not search: |
250 | + print 'Empty search, skipping.' |
251 | + return |
252 | + # We iterate through each of the returned results |
253 | + for i, item in enumerate(self.chefkoch_search(search)): |
254 | + title = item.xpath("string(td[2]/a)") |
255 | + icon = item.xpath("td[1]/img/@src")[0] |
256 | + if icon == 'http://cdn.chefkoch.de/img/no-image-rsmain.gif': |
257 | + icon = '/usr/share/unity/lenses/cooking/icons/cuisine.png' |
258 | + uri = item.xpath("td[2]/a/@href")[0] |
259 | + stars = {0: '☆☆☆☆☆', 1: '✮☆☆☆☆', 2: '★☆☆☆☆', 3: '★✮☆☆☆', 4: '★★☆☆☆', 5: '★★✮☆☆', 6: '★★★☆☆', 7: '★★★✮☆', 8: '★★★★☆', 9: '★★★★✮', 10: '★★★★★'} |
260 | + likes = 0 |
261 | + stars_img = item.xpath("td[3]/img/@src")[0] |
262 | + result = FULLSTAR_RE.search(stars_img) |
263 | + if result: |
264 | + likes = int(result.group(1)) * 2 |
265 | + else: |
266 | + result = HALFSTAR_RE.search(stars_img) |
267 | + if result: |
268 | + likes = int(result.group(1)) * 2 + 1 |
269 | + time = item[3].text |
270 | + difficulty = item[3].find('br').tail |
271 | + comments = [stars[likes], time + ' ⌚ ', difficulty] |
272 | + comment = ' | '.join(comments) |
273 | + |
274 | + # If the uri seems valid, we add the results to the Dee model |
275 | + if (uri.startswith("http://")): |
276 | + # uri, icon, category (matching the order of the categories in the lens), mimetype, title, comment, drag and drop uri |
277 | + model.append(uri, icon, 1, "text/html", title, comment, uri) |
278 | + # We can append the same result to multiple models, just by changing the category |
279 | + |
280 | +if __name__ == "__main__": |
281 | + # Check if we are running in a German locale. Otherwise, the results are |
282 | + # rather useless, so don't create the daemon. |
283 | + lang = locale.getdefaultlocale()[0] |
284 | + if '_' in lang: |
285 | + lang = lang.split('_', 1)[0] |
286 | + if not lang == 'de': |
287 | + raise SystemExit('No German locale, exiting chefkoch scope') |
288 | + # The following lines take care of the Bus connexion. |
289 | + session_bus_connection = Gio.bus_get_sync (Gio.BusType.SESSION, None) |
290 | + session_bus = Gio.DBusProxy.new_sync (session_bus_connection, 0, None, |
291 | + 'org.freedesktop.DBus', |
292 | + '/org/freedesktop/DBus', |
293 | + 'org.freedesktop.DBus', None) |
294 | + result = session_bus.call_sync('RequestName', |
295 | + GLib.Variant ("(su)", (BUS_NAME, 0x4)), |
296 | + 0, -1, None) |
297 | + |
298 | + # Unpack variant response with signature "(u)". 1 means we got it. |
299 | + result = result.unpack()[0] |
300 | + |
301 | + if result != 1 : |
302 | + print >> sys.stderr, RUNNING % BUS_NAME |
303 | + raise SystemExit (1) |
304 | + |
305 | + daemon = Daemon() |
306 | + GObject.MainLoop().run() |
307 | |
308 | === added file 'unity-scope-chefkoch.service' |
309 | --- unity-scope-chefkoch.service 1970-01-01 00:00:00 +0000 |
310 | +++ unity-scope-chefkoch.service 2012-05-22 20:35:21 +0000 |
311 | @@ -0,0 +1,3 @@ |
312 | +[D-BUS Service] |
313 | +Name=net.launchpad.scope.cooking.chefkoch |
314 | +Exec=/usr/share/unity/lenses/cooking/unity-scope-chefkoch |
315 | |
316 | === modified file 'unity-scope-gourmet' |
317 | --- unity-scope-gourmet 2012-04-07 23:41:13 +0000 |
318 | +++ unity-scope-gourmet 2012-05-22 20:35:21 +0000 |
319 | @@ -128,10 +128,10 @@ |
320 | # uri, icon, category (matching the order of the categories in the lens), mimetype, title, comment, drag and drop uri |
321 | if row[14]: |
322 | open('/tmp/unity-scope-gourmet/icon' + str(i), 'wb').write(row[14]) |
323 | - model.append(uri, '/tmp/unity-scope-gourmet/icon' + str(i), 1, "text/html", title, comment, uri) |
324 | + model.append(uri, '/tmp/unity-scope-gourmet/icon' + str(i), 2, "text/html", title, comment, uri) |
325 | else: |
326 | if os.path.exists('/tmp/unity-scope-gourmet/icon' + str(i)): os.remove('/tmp/unity-scope-gourmet/icon' + str(i)) |
327 | - model.append(uri, '/usr/share/unity/lenses/cooking/icons/cuisine.png', 1, "text/html", title, comment, uri) |
328 | + model.append(uri, '/usr/share/unity/lenses/cooking/icons/cuisine.png', 2, "text/html", title, comment, uri) |
329 | # We can append the same result to multiple models, just by changing the category |
330 | |
331 | # The following lines take care of the Bus connexion. |
Approved, thank you for your big help :-)!