~submarine/unity-scope-reddit/trunk

« back to all changes in this revision

Viewing changes to src/unity_reddit_daemon.py

  • Committer: Tarmac
  • Author(s): David Callé
  • Date: 2013-08-15 14:38:33 UTC
  • mfrom: (1.1.10 reddit)
  • Revision ID: tarmac-20130815143833-xs2jw1jqztjn0jxx
Better query handling and many installer fixes.

Approved by David Callé, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
PROVIDER_CREDITS = _('Powered by Reddit')
36
36
SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/'
37
37
PROVIDER_ICON = SVG_DIR+'service-reddit.svg'
38
 
DEFAULT_RESULT_ICON = SVG_DIR+'result-info.svg'
 
38
DEFAULT_RESULT_ICON = SVG_DIR+'service-reddit.svg'
39
39
DEFAULT_RESULT_MIMETYPE = 'text/html'
40
40
DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT
41
41
 
42
42
 
43
 
c1 = {'id'      :'hot',
44
 
      'name'    :_('Hot'),
45
 
      'icon'    :SVG_DIR+'group-installed.svg',
46
 
      'renderer':Unity.CategoryRenderer.VERTICAL_TILE}
47
 
c2 = {'id'      :'new', 
48
 
      'name'    :_('New'),
49
 
      'icon'    :SVG_DIR+'group-installed.svg',
50
 
      'renderer':Unity.CategoryRenderer.VERTICAL_TILE}
51
 
c2 = {'id'      :'controversial', 
52
 
      'name'    :_('Controversial'),
53
 
      'icon'    :SVG_DIR+'group-installed.svg',
54
 
      'renderer':Unity.CategoryRenderer.VERTICAL_TILE}
55
 
c2 = {'id'      :'top', 
56
 
      'name'    :_('Top'),
57
 
      'icon'    :SVG_DIR+'group-installed.svg',
58
 
      'renderer':Unity.CategoryRenderer.VERTICAL_TILE}
59
 
CATEGORIES = [c1, c2]
 
43
c1 = {'id'      :'results',
 
44
      'name'    :_('Posts'),
 
45
      'icon'    :SVG_DIR+'group-installed.svg',
 
46
      'renderer':Unity.CategoryRenderer.VERTICAL_TILE}
 
47
CATEGORIES = [c1]
60
48
 
61
49
FILTERS = []
62
50
 
66
54
m2 = {'id'   :'author',
67
55
      'type' :'s',
68
56
      'field':Unity.SchemaFieldType.OPTIONAL}
69
 
EXTRA_METADATA = [m1, m2]
 
57
m3 = {'id'   :'domain',
 
58
      'type' :'s',
 
59
      'field':Unity.SchemaFieldType.OPTIONAL}
 
60
m4 = {'id'   :'subreddit',
 
61
      'type' :'s',
 
62
      'field':Unity.SchemaFieldType.OPTIONAL}
 
63
m5 = {'id'   :'comments',
 
64
      'type' :'i',
 
65
      'field':Unity.SchemaFieldType.OPTIONAL}
 
66
EXTRA_METADATA = [m1, m2, m3, m4, m5]
70
67
 
71
68
def search(search, filters):
72
69
    '''
83
80
    extras metadata fields (variant)
84
81
    '''
85
82
    results = []
 
83
    uri = ''
86
84
    if not search:
87
 
        return results
88
 
    search = urllib.parse.quote(search)
89
 
    cats = ['hot', 'new', 'controversial', 'top']
90
 
    for cat in cats:
91
 
        uri = '%sr/%s/%s.json?limit=25' % (SEARCH_URI, search, cat)
92
 
        print(uri)
93
 
        data = None
94
 
        try:
95
 
            response = urllib.request.urlopen(uri).read()
96
 
            data = json.loads(response.decode('utf-8'))
97
 
        except Exception as error:
98
 
            print(error)
99
 
            if cat == 'hot':
100
 
                return results
 
85
        uri = '%shot.json?limit=25' % (SEARCH_URI)
 
86
    elif len(search) < 3:
 
87
        return results
 
88
    else:
 
89
        search_cleaned = urllib.parse.quote(search.split('#')[0])
 
90
        uri = '%sr/%s/hot.json?limit=25' % (SEARCH_URI, search_cleaned)
 
91
    print(uri)
 
92
    data = None
 
93
    try:
 
94
        hdr = { 'User-Agent' : 'unity-scope-reddit' }
 
95
        req = urllib.request.Request(url=uri, 
 
96
                                     headers=hdr)
 
97
        response = urllib.request.urlopen(req).read()
 
98
        data = json.loads(response.decode('utf-8'))
 
99
    except Exception as error:
 
100
        print(error)
 
101
        return results
 
102
    if not data or not 'data' in data:
 
103
        return results
 
104
    for d in data ['data']['children']:
 
105
        if d['data']['over_18'] is True and not '#nsfw' in search:
 
106
            ann_icon = Unity.AnnotatedIcon.new(Gio.ThemedIcon.new(DEFAULT_RESULT_ICON))
 
107
            ann_icon.props.ribbon = "NSFW"
 
108
            icon = ann_icon.to_string()
 
109
            target = ''
 
110
        else:
 
111
            if d['data']['thumbnail'] != 'self':
 
112
                icon = d['data']['thumbnail']
101
113
            else:
102
 
                continue
103
 
        if not data or not 'data' in data:
104
 
            return results
105
 
        for d in data ['data']['children']:
106
 
            if d['data']['over_18'] is True:
107
114
                icon = None
108
 
            else:
109
 
                icon = d['data']['thumbnail']
110
 
            results.append({'uri':'%s%s' % (SEARCH_URI, d['data']['permalink']),
111
 
                            'title':d['data']['title'],
112
 
                            'icon':icon,
113
 
                            'target':GLib.Variant('s', d['data']['url']),
114
 
                            'author':GLib.Variant('s', d['data']['author']),
115
 
                            'category':cats.index(cat)})
 
115
            target = d['data']['url']
 
116
        comment = d['data']['selftext']
 
117
        results.append({'uri':'%s%s' % (SEARCH_URI, d['data']['permalink']),
 
118
                        'title':d['data']['title'],
 
119
                        'icon':icon,
 
120
                        'target':target,
 
121
                        'author':d['data']['author'],
 
122
                        'subreddit':d['data']['subreddit'],
 
123
                        'comment':comment,
 
124
                        'comments':d['data']['num_comments'],
 
125
                        'domain':d['data']['domain']})
116
126
    return results
117
127
 
118
128
 
149
159
                    i['comment'] = ''
150
160
                if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '':
151
161
                    i['dnd_uri'] = i['uri']
152
 
                i['metadata'] = {}
153
 
                if EXTRA_METADATA:
154
 
                    for e in i:
155
 
                        for m in EXTRA_METADATA:
156
 
                            if m['id'] == e:
157
 
                                i['metadata'][e] = i[e]
158
 
                i['metadata']['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS)
159
 
                result = Unity.ScopeResult.create(str(i['uri']), str(i['icon']),
160
 
                                                  i['category'], i['result_type'],
161
 
                                                  str(i['mimetype']), str(i['title']),
162
 
                                                  str(i['comment']), str(i['dnd_uri']),
163
 
                                                  i['metadata'])
164
 
                result_set.add_result(result)
 
162
                result_set.add_result(**i)
165
163
        except Exception as error:
166
164
            print (error)
167
165
 
 
166
class Preview (Unity.ResultPreviewer):
 
167
 
 
168
    def do_run(self):
 
169
        if self.result.metadata['target'].get_string().split('.')[-1] in ['jpg', 'png']:
 
170
            image = Gio.FileIcon.new (Gio.file_new_for_uri(self.result.metadata['target'].get_string()))
 
171
        else:
 
172
            image = Gio.FileIcon.new (Gio.file_new_for_uri(self.result.icon_hint))
 
173
        if self.result.comment != self.result.title and self.result.comment != '':
 
174
            description = self.result.comment
 
175
        elif len(self.result.title) > 23:
 
176
            description = self.result.title
 
177
        else:
 
178
            description = ''
 
179
        preview = Unity.GenericPreview.new(self.result.title, description, image)
 
180
        preview.add_info(Unity.InfoHint.new('comments', _('Comments'), None, str(self.result.metadata['comments'].get_int32())))
 
181
        preview.add_info(Unity.InfoHint.new('subreddit', _('Submitted to'), None, "r/%s" % (self.result.metadata['subreddit'].get_string())))
 
182
        if not self.result.metadata['domain'].get_string().startswith("self."):
 
183
            preview.add_info(Unity.InfoHint.new('domain', _('Source'), None, self.result.metadata['domain'].get_string()))
 
184
        preview.props.subtitle = self.result.metadata['author'].get_string()
 
185
        icon = Gio.FileIcon.new (Gio.file_new_for_path(PROVIDER_ICON))
 
186
        open_action = Unity.PreviewAction.new("open", _("View on Reddit"), icon)
 
187
        preview.add_action(open_action)
 
188
        return preview
 
189
 
168
190
class Scope (Unity.AbstractScope):
169
191
    def __init__(self):
170
192
        Unity.AbstractScope.__init__(self)
216
238
        se = MySearch (search_context)
217
239
        return se
218
240
 
 
241
    def do_create_previewer(self, result, metadata):
 
242
        rp = Preview()
 
243
        rp.set_scope_result(result)
 
244
        rp.set_search_metadata(metadata)
 
245
        return rp
 
246
 
219
247
def load_scope():
220
248
    return Scope()