~unity-lens-videos/unity-lens-video/remote-videos

« back to all changes in this revision

Viewing changes to src/unity-scope-video-remote

  • Committer: David Callé
  • Date: 2012-01-30 09:24:47 UTC
  • Revision ID: davidc@framli.eu-20120130092447-ojcccg0q6640r15x
* Copy video-local branch
* Setup the scope architecture
* Pass to second category for testing

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
from gi.repository import GLib, GObject, Gio
 
5
from gi.repository import Dee
 
6
from gi.repository import Unity
 
7
import commands, gio
 
8
 
 
9
BUS_NAME = "net.launchpad.scope.video.remote"
 
10
FOLDER = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
 
11
CACHE = "%s/.cache/video-scope" % GLib.get_home_dir()
 
12
DB = "video.db"
 
13
 
 
14
class Daemon:
 
15
        def __init__ (self):
 
16
                self.scope = Unity.Scope.new ("/net/launchpad/scope/video/remote")
 
17
                self.scope.search_in_global = True
 
18
                self.scope.connect ("search-changed", self.on_search_changed)
 
19
                self.scope.connect ("filters-changed", lambda scope : self.scope.queue_search_changed(Unity.SearchType.DEFAULT))
 
20
                self.scope.export()
 
21
 
 
22
        def on_search_changed (self, scope, search=None, search_type=0, cancellable=None):
 
23
                if search:
 
24
                        search_string = search.props.search_string.strip()
 
25
                        print 'Search changed to %s' % search_string
 
26
                else:
 
27
                        search_string = ''
 
28
                if search_type == Unity.SearchType.DEFAULT:
 
29
                        model = self.scope.props.results_model
 
30
                else:
 
31
                        model = self.scope.props.global_results_model
 
32
                model.clear()
 
33
                self.update_results_model (search_string, model, search_type)
 
34
                model.flush_revision_queue ()
 
35
                if search:
 
36
                        search.finished()
 
37
 
 
38
        def update_results_model(self, search, model, search_type):
 
39
                if not gio.File(CACHE).query_exists():
 
40
                        gio.File(CACHE).make_directory()
 
41
                GLib.spawn_command_line_async('updatedb -o %s/%s -l 0 -U %s' % (CACHE, DB, FOLDER))
 
42
                result_set = self.videolocal(search)
 
43
                for i in result_set:
 
44
                        title = i[0]
 
45
                        comment = i[1]
 
46
                        uri = i[2]
 
47
                        dnd_uri = i[2]
 
48
                        icon_hint = i[3]
 
49
                        model.append (uri, icon_hint, 1,"text/html", title, comment, dnd_uri)
 
50
 
 
51
        def videolocal(self, search):
 
52
                result_list = []
 
53
                search_escaped = search.replace(' ', '\ ')
 
54
                results = commands.getoutput('locate -id %s/%s %s*%s*' % (CACHE, DB, FOLDER, search_escaped)).split('\n')
 
55
                if results:
 
56
                        for video in results:
 
57
                                if self.is_video(video):
 
58
                                        title = self.get_name(video)
 
59
                                        comment = ''
 
60
                                        uri = 'file://%s' % video
 
61
                                        icon = self.get_icon(video, title)
 
62
                                        if title:
 
63
                                                item = []
 
64
                                                item.append(title)
 
65
                                                item.append(comment)
 
66
                                                item.append(uri)
 
67
                                                item.append(icon)
 
68
                                                result_list.append(item)
 
69
                        return result_list
 
70
 
 
71
        def is_file(self, uri):
 
72
                f = gio.File(uri)
 
73
                file_type =  f.query_file_type(gio.FILE_TYPE_REGULAR)
 
74
                if file_type is gio.FILE_TYPE_REGULAR:
 
75
                        return True
 
76
 
 
77
        def is_video(self, uri):
 
78
                f = gio.File(uri)
 
79
                content_type = f.query_info('standard::content-type').get_content_type()
 
80
                if 'video' in content_type:
 
81
                        return True
 
82
 
 
83
        def get_name(self, uri):
 
84
                f = gio.File(uri)
 
85
                name = f.query_info(gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)
 
86
                display_name = name.get_attribute_as_string(gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)
 
87
                return display_name
 
88
 
 
89
        def get_icon(self, uri, name):
 
90
                """
 
91
                This method checks several locations for a video thumbnail.
 
92
                1) <filename>.jpg file in the same folder (not activated for now)
 
93
                1) Nautilus thumbnails
 
94
                2) Cached thumbnails generated by the scope
 
95
                If nothing has been found, it tries to generate a thumbnail with Totem, stores and uses it.
 
96
                If the generation fails or is slow, it fallbacks to the standard video icon.
 
97
                """
 
98
                icon_path = None
 
99
                thumb_name = uri.replace(FOLDER, '').replace('/', '_')
 
100
                icon_check = '%s/thumb_%s' % (CACHE, thumb_name)
 
101
#               if not icon_path:
 
102
#                       print 'Check for local cover'
 
103
#                       local_cover = uri.replace('.%s' % uri.split('.')[-1], '.jpg')
 
104
#                       if self.is_file(local_cover):
 
105
#                               icon_path = local_cover
 
106
                if not icon_path:
 
107
                        print 'Check for Nautilus thumb'
 
108
                        f = gio.File(uri)
 
109
                        icon = f.query_info(gio.FILE_ATTRIBUTE_THUMBNAIL_PATH)
 
110
                        icon_path = icon.get_attribute_as_string(gio.FILE_ATTRIBUTE_THUMBNAIL_PATH)
 
111
                if not icon_path:
 
112
                        print 'No Nautilus thumb : Check for cached thumb'
 
113
                        if self.is_file(icon_check):
 
114
                                icon_path = icon_check
 
115
                if not icon_path:
 
116
                        print "No Cached thumb : generating thumb"
 
117
                        GLib.spawn_command_line_async('totem-video-thumbnailer \"%s\" \"%s/thumb_%s\"' % (uri,CACHE,thumb_name))
 
118
                        print 'Check for cached thumb (again)'
 
119
                        if self.is_file(icon_check):
 
120
                                icon_path = icon_check
 
121
                if not icon_path:
 
122
                        print 'Nothing found or thumb is still being generated : icon fallback'
 
123
                        icon_path = 'video'
 
124
                return icon_path
 
125
 
 
126
 
 
127
if __name__ == "__main__":
 
128
        session_bus_connection = Gio.bus_get_sync (Gio.BusType.SESSION, None)
 
129
        session_bus = Gio.DBusProxy.new_sync (session_bus_connection, 0, None,
 
130
                                              'org.freedesktop.DBus',
 
131
                                              '/org/freedesktop/DBus',
 
132
                                              'org.freedesktop.DBus', None)
 
133
        result = session_bus.call_sync('RequestName',
 
134
                                       GLib.Variant ("(su)", (BUS_NAME, 0x4)),
 
135
                                       0, -1, None)
 
136
                                       
 
137
        # Unpack variant response with signature "(u)". 1 means we got it.
 
138
        result = result.unpack()[0]
 
139
        
 
140
        if result != 1 :
 
141
                print >> sys.stderr, "Failed to own name %s. Bailing out." % BUS_NAME
 
142
                raise SystemExit (1)
 
143
        
 
144
        daemon = Daemon()
 
145
        GObject.MainLoop().run()