2
# -*- coding: utf-8 -*-
4
from gi.repository import GLib, GObject, Gio
5
from gi.repository import Dee
6
from gi.repository import Unity
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()
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))
22
def on_search_changed (self, scope, search=None, search_type=0, cancellable=None):
24
search_string = search.props.search_string.strip()
25
print 'Search changed to %s' % search_string
28
if search_type == Unity.SearchType.DEFAULT:
29
model = self.scope.props.results_model
31
model = self.scope.props.global_results_model
33
self.update_results_model (search_string, model, search_type)
34
model.flush_revision_queue ()
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)
49
model.append (uri, icon_hint, 1,"text/html", title, comment, dnd_uri)
51
def videolocal(self, search):
53
search_escaped = search.replace(' ', '\ ')
54
results = commands.getoutput('locate -id %s/%s %s*%s*' % (CACHE, DB, FOLDER, search_escaped)).split('\n')
57
if self.is_video(video):
58
title = self.get_name(video)
60
uri = 'file://%s' % video
61
icon = self.get_icon(video, title)
68
result_list.append(item)
71
def is_file(self, uri):
73
file_type = f.query_file_type(gio.FILE_TYPE_REGULAR)
74
if file_type is gio.FILE_TYPE_REGULAR:
77
def is_video(self, uri):
79
content_type = f.query_info('standard::content-type').get_content_type()
80
if 'video' in content_type:
83
def get_name(self, 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)
89
def get_icon(self, uri, name):
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.
99
thumb_name = uri.replace(FOLDER, '').replace('/', '_')
100
icon_check = '%s/thumb_%s' % (CACHE, thumb_name)
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
107
print 'Check for Nautilus thumb'
109
icon = f.query_info(gio.FILE_ATTRIBUTE_THUMBNAIL_PATH)
110
icon_path = icon.get_attribute_as_string(gio.FILE_ATTRIBUTE_THUMBNAIL_PATH)
112
print 'No Nautilus thumb : Check for cached thumb'
113
if self.is_file(icon_check):
114
icon_path = icon_check
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
122
print 'Nothing found or thumb is still being generated : icon fallback'
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)),
137
# Unpack variant response with signature "(u)". 1 means we got it.
138
result = result.unpack()[0]
141
print >> sys.stderr, "Failed to own name %s. Bailing out." % BUS_NAME
145
GObject.MainLoop().run()