1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 # libplayers.py -- get list of potential playback apps
23 # thomas perl <thp@perli.net> 20060329
31 from ConfigParser
import RawConfigParser
38 from gpodder
.liblogger
import log
42 # where are the .desktop files located?
43 userappsdirs
= [ '/usr/share/applications/', '/usr/local/share/applications/', '/usr/share/applications/kde/' ]
45 # the name of the section in the .desktop files
46 sect
= 'Desktop Entry'
48 class PlayerListModel(gtk
.ListStore
):
49 C_ICON
, C_NAME
, C_COMMAND
, C_CUSTOM
= range(4)
52 gtk
.ListStore
.__init
__(self
, gtk
.gdk
.Pixbuf
, str, str, bool)
54 def insert_app(self
, pixbuf
, name
, command
):
55 self
.append((pixbuf
, name
, command
, False))
57 def get_command(self
, index
):
58 return self
[index
][self
.C_COMMAND
]
60 def get_index(self
, value
):
61 for index
, row
in enumerate(self
):
62 if value
== row
[self
.C_COMMAND
]:
66 name
= _('Command: %s') % value
67 if last_row
[self
.C_CUSTOM
]:
68 last_row
[self
.C_COMMAND
] = value
69 last_row
[self
.C_NAME
] = name
71 self
.append((None, name
, value
, True))
76 def is_separator(cls
, model
, iter):
77 return model
.get_value(iter, cls
.C_COMMAND
) == ''
79 class UserApplication(object):
80 def __init__(self
, name
, cmd
, mime
, icon
):
87 if self
.icon
is not None:
88 # Load it from an absolute filename
89 if os
.path
.exists(self
.icon
):
91 return gtk
.gdk
.pixbuf_new_from_file_at_size(self
.icon
, 24, 24)
92 except gobject
.GError
, ge
:
95 # Load it from the current icon theme
96 (icon_name
, extension
) = os
.path
.splitext(os
.path
.basename(self
.icon
))
97 theme
= gtk
.IconTheme()
98 if theme
.has_icon(icon_name
):
99 return theme
.load_icon(icon_name
, 24, 0)
101 def is_mime(self
, mimetype
):
102 return self
.mime
.find(mimetype
+'/') != -1
105 class UserAppsReader(object):
106 def __init__(self
, mimetypes
):
108 self
.mimetypes
= mimetypes
109 self
.__has
_read
= False
110 self
.__finished
= threading
.Event()
111 self
.__has
_sep
= False
112 self
.apps
.append(UserApplication(_('Default application'), 'default', ';'.join((mime
+'/*' for mime
in self
.mimetypes
)), gtk
.STOCK_OPEN
))
114 def add_separator(self
):
115 self
.apps
.append(UserApplication('', '', ';'.join((mime
+'/*' for mime
in self
.mimetypes
)), ''))
116 self
.__has
_sep
= True
122 self
.__has
_read
= True
123 log('start reader', bench_start
=True)
124 for dir in userappsdirs
:
125 if os
.path
.exists( dir):
126 for file in glob
.glob(os
.path
.join(dir, '*.desktop')):
127 self
.parse_and_append( file)
128 log('end reader', bench_end
=True)
129 self
.__finished
.set()
131 def parse_and_append( self
, filename
):
133 parser
= RawConfigParser()
134 parser
.read([filename
])
135 if not parser
.has_section(sect
):
138 # Find out if we need it by comparing mime types
139 app_mime
= parser
.get(sect
, 'MimeType')
140 for needed_type
in self
.mimetypes
:
141 if app_mime
.find(needed_type
+'/') != -1:
142 log('Player found: %s', filename
, sender
=self
)
143 app_name
= parser
.get(sect
, 'Name')
144 app_cmd
= parser
.get(sect
, 'Exec')
145 app_icon
= parser
.get(sect
, 'Icon')
146 if not self
.__has
_sep
:
148 self
.apps
.append(UserApplication(app_name
, app_cmd
, app_mime
, app_icon
))
153 def get_model(self
, mimetype
):
154 self
.__finished
.wait()
156 model
= PlayerListModel()
157 for app
in self
.apps
:
158 if app
.is_mime(mimetype
):
159 model
.insert_app(app
.get_icon(), app
.name
, app
.cmd
)