~davidc3/onehundredscopes/minecraft-quantal

« back to all changes in this revision

Viewing changes to src/unity-lens-minecraft

  • Committer: David Callé
  • Date: 2012-11-07 10:14:09 UTC
  • Revision ID: davidc@framli.eu-20121107101409-svul5xsu3u8i40jl
pep8 fixes. Handle template changes in interesting pages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#! /usr/bin/python
2
2
 
3
 
#    Copyright (c) 2012 David Calle <davidc@framli.eu>
 
3
#    Copyright(c) 2012 David Calle <davidc@framli.eu>
4
4
 
5
5
#    This program is free software: you can redistribute it and/or modify
6
6
#    it under the terms of the GNU General Public License as published by
7
7
#    the Free Software Foundation, either version 3 of the License, or
8
 
#    (at your option) any later version.
 
8
#   (at your option) any later version.
9
9
 
10
10
#    This program is distributed in the hope that it will be useful,
11
11
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
26
26
BUS_NAME = "net.launchpad.lens.minecraft"
27
27
CACHE = "%s/unity-lens-minecraft/" % GLib.get_user_cache_dir()
28
28
 
 
29
 
29
30
class Daemon:
30
31
 
31
 
    def __init__ (self):
32
 
        self._lens = Unity.Lens.new ("/net/launchpad/lens/minecraft", "minecraft")
33
 
        self._scope = Unity.Scope.new ("/net/launchpad/lens/minecraft/main")
 
32
    def __init__(self):
 
33
        self._lens = Unity.Lens.new("/net/launchpad/lens/minecraft",
 
34
                                     "minecraft")
 
35
        self._scope = Unity.Scope.new("/net/launchpad/lens/minecraft/main")
34
36
        self._lens.props.search_hint = "Search Minecraft recipes"
35
 
        self._lens.props.visible = True;
 
37
        self._lens.props.visible = True
36
38
 
37
 
        self._lens.add_local_scope (self._scope);
 
39
        self._lens.add_local_scope(self._scope)
38
40
        self._scope.connect("search-changed", self.on_search_changed)
39
41
        self._scope.connect('preview-uri', self.on_preview_uri)
40
42
        svg_dir = "/usr/share/icons/unity-icon-theme/places/svg/"
41
43
        cats = []
42
 
        cats.append (Unity.Category.new ("Recipes",
43
 
                                         Gio.ThemedIcon.new(svg_dir+"group-installed.svg"),
44
 
                                         Unity.CategoryRenderer.VERTICAL_TILE))
 
44
        cats.append(Unity.Category.new("Recipes",
 
45
                                       Gio.ThemedIcon.new(svg_dir+"group-installed.svg"),
 
46
                                       Unity.CategoryRenderer.VERTICAL_TILE))
45
47
        self._lens.props.categories = cats
46
48
        self.wiki = ["http://minecraftwiki.net"]
47
 
        self.title_fixes = {"Torches":"Torch","Boots":"Leather Boots","Helmet":"Leather Cap","Leggings":"Leather Pants","Chestplate":"Leather Tunic", "Gold Ingot":"Gold (Ingot)", "Iron Ingot":"Iron (Ingot)", "Sword":"Wooden Sword","Doors":"Wooden Door", "Axe":"Wooden Axe", "Shovel":"Wooden Shovel", "Pickaxe":"Wooden Pickaxe", "Hoe":"Wooden Hoe","Wool":"White Wool","Redstone Torch":"Redstone (Torch)","Minecart with Furnace":"Powered Minecart","Minecart with Chest":"Storage Minecart","Jack 'o' Lantern":"Jack-O-Lantern", "Ore":"Gold (Ore)", "Button":"Stone Button","Rail":"Rails", "Map (item)":"Empty Map","Slabs":"Stone Slab", "Stairs":"Cobblestone Stairs","Pressure Plates":"Wooden Pressure Plate", "Wooden Planks":"Wooden Plank", "Bow#Arrows":"Arrow", "Snow Block":"Snow", "Bricks":"Brick (Block)","Glowstone Block":"Glowstone (Block)"}
48
 
        self.recipes = self.parseDB ()
 
49
        self.title_fixes = {"Torches": "Torch", "Boots": "Leather Boots", "Helmet": "Leather Cap", "Leggings": "Leather Pants", "Chestplate": "Leather Tunic", "Gold Ingot": "Gold(Ingot)", "Iron Ingot": "Iron(Ingot)", "Sword": "Wooden Sword", "Doors": "Wooden Door", "Axe": "Wooden Axe", "Shovel": "Wooden Shovel", "Pickaxe": "Wooden Pickaxe", "Hoe": "Wooden Hoe", "Wool": "White Wool", "Redstone Torch": "Redstone(Torch)", "Minecart with Furnace": "Powered Minecart", "Minecart with Chest": "Storage Minecart", "Jack 'o' Lantern": "Jack-O-Lantern", "Ore": "Gold(Ore)", "Button": "Stone Button", "Rail": "Rails", "Map(item)": "Empty Map", "Slabs": "Stone Slab", "Stairs": "Cobblestone Stairs", "Pressure Plates": "Wooden Pressure Plate", "Wooden Planks": "Wooden Plank", "Bow#Arrows": "Arrow", "Snow Block": "Snow", "Bricks": "Brick(Block)", "Glowstone Block": "Glowstone(Block)"}
 
50
        self.recipes = self.parseDB()
49
51
        self.icons_retrieved = []
50
52
        self.icon_runs = {}
51
53
        
52
54
        
53
55
        self.preferences = Unity.PreferencesManager.get_default()
54
56
        self.preferences.connect("notify::remote-content-search", self._on_preference_changed)
55
 
        self._lens.export ();
56
 
        self._scope.export ();
 
57
        self._lens.export();
 
58
        self._scope.export();
57
59
 
58
 
    def _on_preference_changed (self, *_):
 
60
    def _on_preference_changed(self, *_):
59
61
        self._scope.queue_search_changed(Unity.SearchType.DEFAULT)
60
62
 
61
 
    def on_search_changed (self, scope, search, search_type, *_):
 
63
    def on_search_changed(self, scope, search, search_type, *_):
62
64
        model = search.props.results_model
63
 
        model.clear ()
 
65
        model.clear()
64
66
 
65
67
        # only perform the request if the user has not disabled
66
68
        # online/commercial suggestions. That will hide the category as well.
69
71
            return
70
72
 
71
73
        if search_type is Unity.SearchType.DEFAULT:
72
 
            search_string = search.props.search_string.strip ()
 
74
            search_string = search.props.search_string.strip()
73
75
            print "Search changed to \"%s\"" % search_string
74
76
            self.update_results_model(model, search_string)
75
 
            search.set_reply_hint ("no-results-hint", GLib.Variant.new_string("Sorry, there are no articles that match your search."))
76
 
        search.finished ()
 
77
            search.set_reply_hint("no-results-hint", GLib.Variant.new_string("Sorry, there are no articles that match your search."))
 
78
        search.finished()
77
79
 
78
 
    def getRecipeData (self):
 
80
    def getRecipeData(self):
79
81
        try:
80
 
            url = ("http://www.minecraftwiki.net/api.php?action=query&format=json&titles=Crafting/Blocks|Crafting/Items|Template:Wool_Crafting|Template:Tool_Crafting|Template:Armor_Crafting|Template:Weapon_Crafting|Glowstone_Block&prop=revisions&rvprop=content")
 
82
            url =("http://www.minecraftwiki.net/api.php?action=query&format=json&titles=Crafting/Blocks|Crafting/Items|Template:Wool_Crafting|Template:Tool_Crafting|Template:Armor_Crafting|Template:Weapon_Crafting|Glowstone_Block&prop=revisions&rvprop=content")
81
83
            results = simplejson.load(urllib2.urlopen(url))
 
84
            print url
82
85
        except:
83
86
            results = None
84
87
        return results
85
88
 
86
 
    def getIcon (self, title):
 
89
    def getIcon(self, title):
87
90
        icon_list = []
88
91
        title_list = []
89
92
        if not title:
96
99
            tc += 1
97
100
        titles = 'File:Grid_'+'.png|File:Grid_'.join(title)+'.png'
98
101
 
99
 
        url = ("http://www.minecraftwiki.net/api.php?action=query&format=json&prop=imageinfo&iiprop=url&limit=50&titles=%s" % (titles.replace(' ','_')))
 
102
        url =("http://www.minecraftwiki.net/api.php?action=query&format=json&prop=imageinfo&iiprop=url&limit=50&titles=%s" %(titles.replace(' ','_')))
100
103
#        print url
101
104
        results = simplejson.load(urllib2.urlopen(url))
102
105
        if results:
108
111
                    self.icon_runs[content['title']] = 1
109
112
                if 'imageinfo' in content:
110
113
                    for c in content['imageinfo']:
111
 
                        icon_list.append (c['url'])
 
114
                        icon_list.append(c['url'])
112
115
                else:
113
116
#                    print "no icon found"
114
 
                    icon_list.append ('')
 
117
                    icon_list.append('')
115
118
 
116
 
                title_list.append (content['title'].replace("File:Grid ", "").replace('.png', ''))
 
119
                title_list.append(content['title'].replace("File:Grid ", "").replace('.png', ''))
117
120
#        print "ICONS " + str(icon_list)
118
121
#        print "TITLES " + str(title_list)
119
122
        return icon_list, title_list
127
130
            if file_type is Gio.FileType.REGULAR:
128
131
                return True
129
132
 
130
 
    def update_results_model (self, model, search):
 
133
    def update_results_model(self, model, search):
131
134
        results = []
132
135
        icon_request = []
133
 
        dset = set ()
 
136
        dset = set()
134
137
        
135
138
        random.shuffle(self.recipes)
136
139
        for item in self.recipes:
139
142
                if i and i != item[2]:
140
143
                    i_items = i.split(' ')
141
144
                    for i_i in i_items:
142
 
                        if i_i.lower ().startswith(search.lower ()):
 
145
                        if i_i.lower().startswith(search.lower()):
143
146
                            match = True
144
147
                    if len(search) < 2:
145
148
                        match = True
148
151
                        if e:
149
152
                            e_items = e.split(' ')
150
153
                            for e_i in e_items:
151
 
                                if e_i.lower ().startswith(search.lower ()):
 
154
                                if e_i.lower().startswith(search.lower()):
152
155
                                    match = True
153
156
                if match:
154
157
                    if item[0] not in results and len(results) < 50:
156
159
                        dset.add(item[0])
157
160
                        b = len(dset)
158
161
                        if b > a:
159
 
                            results.append (item)
 
162
                            results.append(item)
160
163
        if not len(search) < 1:
161
 
            results.sort ()
 
164
            results.sort()
162
165
        for r in results:
163
166
            r[0] = r[0].replace('[','').replace(']','')
164
167
            icon_request.append(r[0])
165
168
        if len(results) > 0:
166
 
            icons, titles = self.getIcon (icon_request)
 
169
            icons, titles = self.getIcon(icon_request)
167
170
            i = 0
168
171
            for r in results:
169
172
                try:
184
187
                else:
185
188
                    cat = 0
186
189
                if icon != '':
187
 
                    model.append (str(r[0]),icon,cat, "text/html", r[0].replace('|',' or '), '', '')
 
190
                    model.append(str(r[0]),icon,cat, "text/html", r[0].replace('|',' or '), '', '')
188
191
                i += 1
189
192
 
190
193
 
191
 
    def parseDB (self):
 
194
    def parseDB(self):
192
195
        item_list = []
193
196
        recipes_list = []
194
197
        cat_list = []
195
 
        recipes = self.getRecipeData ()
 
198
        recipes = self.getRecipeData()
196
199
        for r in recipes['query']['pages']:
 
200
            if not 'revisions' in recipes['query']['pages'][r]:
 
201
                continue
197
202
            content = recipes['query']['pages'][r]['revisions']
198
203
            cat = recipes['query']['pages'][r]['title']
199
204
            for c in content:
211
216
                        title = re.search("\[\[(.*)\]\]", title.group(1))
212
217
                        if title:
213
218
                            title2 = re.search("(.*)\|", title.group(1))
214
 
                            
215
219
                            if title2:
216
220
                                if title2.group(1) in self.title_fixes:
217
221
                                    item.append(self.title_fixes[title2.group(1)])
227
231
                            item.append('')
228
232
                    else:
229
233
                        item.append('')
230
 
                    
231
 
                    content = re.search("\n.*center.*\| (.*)\n", a)
 
234
                    content = re.search("\n.*center.*\|(.*)\n", a)
232
235
                    if content:
233
236
                        item.append(content.group(1))
234
237
                    else:
239
242
                                  None, None, None]
240
243
                    A1 = re.search("\|A1=(.*)\|.*B1", a,flags=re.MULTILINE | re.S)
241
244
                    if A1:
242
 
                        recipe_map[0] = str(A1.group(1).strip ())
 
245
                        recipe_map[0] = str(A1.group(1).strip())
243
246
                    B1 = re.search("\|B1=(.*)\|.*C1", a,re.MULTILINE | re.S)
244
247
                    if B1:
245
 
                        recipe_map[1] = str(B1.group(1).strip ())
 
248
                        recipe_map[1] = str(B1.group(1).strip())
246
249
                    C1 = re.search("\|C1=(.*)\|.*A2", a,re.MULTILINE | re.S)
247
250
                    if C1:
248
 
                        recipe_map[2] = str(C1.group(1).strip ())
 
251
                        recipe_map[2] = str(C1.group(1).strip())
249
252
                    A2 = re.search("\|A2=(.*)\|.*B2", a,re.MULTILINE | re.S)
250
253
                    if A2:
251
 
                        recipe_map[3] = str(A2.group(1).strip ())
 
254
                        recipe_map[3] = str(A2.group(1).strip())
252
255
                    B2 = re.search("\|B2=(.*)\|.*C2", a,re.MULTILINE | re.S)
253
256
                    if B2:
254
 
                        recipe_map[4] = str(B2.group(1).strip ())
 
257
                        recipe_map[4] = str(B2.group(1).strip())
255
258
                    C2 = re.search("\|C2=(.*)\|.*A3", a,re.MULTILINE | re.S)
256
259
                    if C2:
257
 
                        recipe_map[5] = str(C2.group(1).strip ())
 
260
                        recipe_map[5] = str(C2.group(1).strip())
258
261
                    A3 = re.search("\|A3=(.*)\|.*B3", a,re.MULTILINE | re.S)
259
262
                    if A3:
260
 
                        recipe_map[6] = str(A3.group(1).strip ())
 
263
                        recipe_map[6] = str(A3.group(1).strip())
261
264
                    B3 = re.search("\|B3=(.*)\|.*C3", a,re.MULTILINE | re.S)
262
265
                    if B3:
263
 
                        recipe_map[7] = str(B3.group(1).strip ())
 
266
                        recipe_map[7] = str(B3.group(1).strip())
264
267
                    C3 = re.search("\|C3=(.*)\n?\|.*Output", a,re.MULTILINE | re.S)
265
268
                    if C3:
266
 
                        recipe_map[8] = str(C3.group(1).strip ())
 
269
                        recipe_map[8] = str(C3.group(1).strip())
267
270
                    rmap = []
268
271
                    for m in recipe_map:
269
272
                        if m:
276
279
                        elif m and "Planks" in m:
277
280
                            rmap.append("Wooden Plank")
278
281
                        elif m and "Diamond" in m:
279
 
                            rmap.append("Diamond (Gem)")
 
282
                            rmap.append("Diamond(Gem)")
280
283
                        elif m and "Milk" in m:
281
284
                            rmap.append("Milk Bucket")
282
285
                        elif m and "Egg" in m:
283
286
                            rmap.append("Egg")
284
287
                        elif m and "Dust" in m:
285
 
                            m = m.replace("Dust","(Dust)")
 
288
                            m = m.replace("Dust", "(Dust)")
286
289
                            rmap.append(m)
287
290
                        elif m and "Ingot" in m:
288
 
                            m = m.replace("Ingot","(Ingot)")
 
291
                            m = m.replace("Ingot", "(Ingot)")
289
292
                            rmap.append(m)
290
293
                        elif m and "Coal" in m:
291
 
                            rmap.append("Coal (Item)")
 
294
                            rmap.append("Coal(Item)")
292
295
                        elif m and "Redstone Torch" in m:
293
 
                            rmap.append("Redstone (Torch)")
 
296
                            rmap.append("Redstone(Torch)")
294
297
                        elif m and "Melon Slice" in m:
295
 
                            rmap.append("Melon (Slice)")
 
298
                            rmap.append("Melon(Slice)")
296
299
                        elif m and "Output" in m:
297
300
                            rmap.append("")
298
301
                        elif m and "Block of Gold" in m:
299
 
                            rmap.append("Gold (Block)")
 
302
                            rmap.append("Gold(Block)")
300
303
                        elif m and "Oak Wood" in m:
301
304
                            rmap.append("Wood")
302
305
                        elif m and "Clay Balls" in m:
303
 
                            rmap.append("Clay (Item)")
304
 
                        elif m and "Brick (Item)" in m:
305
 
                            rmap.append("Clay (Brick)")
306
 
 
307
 
 
 
306
                            rmap.append("Clay(Item)")
 
307
                        elif m and "Brick(Item)" in m:
 
308
                            rmap.append("Clay(Brick)")
308
309
                        else:
309
310
                            rmap.append(m)
310
 
#                    print rmap
311
311
                    item.append(rmap)
312
 
                    
313
 
                    output = re.search("Output= (.*)\n", a)
 
312
                    output = re.search("Output=(.*)\n", a)
314
313
                    if output:
315
314
                        if item[0] == '':
316
 
                            if output.group(1).strip () in self.title_fixes:
317
 
                                item[0] = (self.title_fixes[output.group(1).strip ()])
 
315
                            if output.group(1).strip() in self.title_fixes:
 
316
                                item[0] =(self.title_fixes[output.group(1).strip()])
318
317
                            else:
319
 
                                item[0] = output.group(1).strip ()
320
 
                        item.append(output.group(1).strip ())
 
318
                                item[0] = output.group(1).strip()
 
319
                        item.append(output.group(1).strip())
321
320
                    else:
322
321
                        item.append('')
323
322
                    description = re.search("Output=.*\n.*\n\|\s(.*)", a, re.MULTILINE)
324
323
                    if description:
325
 
                        description = description.group(1).strip ()
326
 
                        description = re.sub("\[\[.*\|","", description)
327
 
                        description = re.sub("\]\]","", description)
328
 
                        description = re.sub("\[\[","", description)
 
324
                        description = description.group(1).strip()
 
325
                        description = re.sub("\[\[.*\|", "", description)
 
326
                        description = re.sub("\]\]", "", description)
 
327
                        description = re.sub("\[\[", "", description)
329
328
                        description = re.sub(r"\{\{hungerbar\|(\d+)\}\}",r"\1 hunger points", description)
330
329
                        item.append(description)
331
330
                    else:
352
351
                        if ',' in r[3]:
353
352
                            amount = r[3].split(',')[-1]
354
353
                        description = r[4]
355
 
                
356
 
                image = self.createRecipeImage (title)
 
354
 
 
355
                image = self.createRecipeImage(title)
357
356
                
358
357
                gicon_icon = Gio.FileIcon.new(Gio.file_new_for_uri(model.get_value(iter, 1)))
359
 
                if self.is_file (CACHE+image):
 
358
                if self.is_file(CACHE+image):
360
359
                    gicon_recipe = Gio.FileIcon.new(Gio.file_new_for_path(CACHE+image))
361
360
                else:
362
361
                    gicon_recipe = ''
363
 
                preview = Unity.ApplicationPreview.new(title.strip (),'' ,description,gicon_icon, gicon_recipe)
 
362
                preview = Unity.ApplicationPreview.new(title.strip(),'' ,description,gicon_icon, gicon_recipe)
364
363
                if amount != '':
365
364
                    preview.add_info(Unity.InfoHint.new("Production", "Production", None, amount))
366
365
#                gfile_icon = Gio.file_new_for_path("/usr/share/icons/unity-icon-theme/places/svg/service-picasa.svg")
367
 
#                gicon = Gio.FileIcon.new (gfile_icon)
 
366
#                gicon = Gio.FileIcon.new(gfile_icon)
368
367
#                view_action = Unity.PreviewAction.new("view", _("View"), gicon)
369
368
#                view_action.connect('activated', self.view_action)
370
369
#                preview.add_action(view_action)
371
370
                break
372
371
            iter = model.next(iter)
373
372
        if preview == None:
374
 
            print ("Couldn't find model row for requested preview uri: '%s'", uri)
 
373
            print("Couldn't find model row for requested preview uri: '%s'", uri)
375
374
        return preview
376
375
 
377
 
    def createRecipeImage (self, title):
 
376
    def createRecipeImage(self, title):
378
377
        final_image = 'recipe_'+title+'.png'
379
 
        if self.is_file (CACHE+final_image):
 
378
        if self.is_file(CACHE+final_image):
380
379
            return final_image
381
380
        recipe = []
382
381
        for r in self.recipes:
383
382
            if title == r[0]:
384
383
                recipe = r[2]
385
 
        icons, titles = self.getIcon (recipe)
 
384
        icons, titles = self.getIcon(recipe)
386
385
        ordered_icons = []
387
386
        for item in recipe:
388
387
            if item == '':
389
 
                ordered_icons.append ('')
 
388
                ordered_icons.append('')
390
389
            else:
391
390
                position = titles.index(item)
392
391
                ordered_icons.append(icons[position])
404
403
            if i != '' and ordered_icons[recipe.index(i)] != '':
405
404
                im = Image.open(CACHE+i)
406
405
                im = im.convert('RGBA')
407
 
                im = im.resize ((100,100))
 
406
                im = im.resize((100,100))
408
407
 
409
 
                blank_image.paste(im, (x+10,y+10))
 
408
                blank_image.paste(im,(x+10,y+10))
410
409
            x += 120
411
410
            if x > 350:
412
411
                x = 10
416
415
        return final_image
417
416
 
418
417
 
419
 
    def view_action (self, scope, uri):
 
418
    def view_action(self, scope, uri):
420
419
        """On item clicked, close the Dash and display the photo"""
421
420
        return
422
421
 
423
422
 
424
423
if __name__ == "__main__":
425
 
    session_bus_connection = Gio.bus_get_sync (Gio.BusType.SESSION, None)
426
 
    session_bus = Gio.DBusProxy.new_sync (session_bus_connection, 0, None,
 
424
    session_bus_connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
 
425
    session_bus = Gio.DBusProxy.new_sync(session_bus_connection, 0, None,
427
426
                                          'org.freedesktop.DBus',
428
427
                                          '/org/freedesktop/DBus',
429
428
                                          'org.freedesktop.DBus', None)
430
429
    result = session_bus.call_sync('RequestName',
431
 
                                   GLib.Variant ("(su)", (BUS_NAME, 0x4)),
 
430
                                   GLib.Variant("(su)",(BUS_NAME, 0x4)),
432
431
                                   0, -1, None)
433
432
                                   
434
433
    result = result.unpack()[0]
435
 
    
436
 
    if result != 1 :
 
434
 
 
435
    if result != 1:
437
436
        print >> sys.stderr, "Failed to own name %s. Bailing out." % BUS_NAME
438
 
        raise SystemExit (1)
439
 
    
 
437
        raise SystemExit(1)
 
438
 
440
439
    daemon = Daemon()
441
440
    GObject.MainLoop().run()