3 # This file is part of Jamaendo.
4 # Copyright (c) 2010 Kristoffer Gronlund
6 # Jamaendo 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 # Jamaendo 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 Jamaendo. If not, see <http://www.gnu.org/licenses/>.
19 # Player code heavily based on http://thpinfo.com/2008/panucci/:
20 # A resuming media player for Podcasts and Audiobooks
21 # Copyright (c) 2008-05-26 Thomas Perl <thpinfo.com>
22 # (based on http://pygstdocs.berlios.de/pygst-tutorial/seeking.html)
24 # Jamaendo jamendo.com API wrapper licensed under the New BSD License;
25 # see module for details.
33 from settings import settings
37 gobject.threads_init()
39 log = logging.getLogger(__name__)
46 if util.platform == 'maemo':
47 log.critical('Using GTK widgets, install "python2.5-hildon" '
48 'for this to work properly.')
50 log.critical('This ui only works in maemo')
53 from dbus.mainloop.glib import DBusGMainLoop
55 DBusGMainLoop(set_as_default=True)
59 from postoffice import postoffice
60 from playerwindow import open_playerwindow
61 from search import SearchWindow
62 from featured import FeaturedWindow
63 from radios import RadiosWindow
64 from favorites import FavoritesWindow
66 class PlaylistsWindow(hildon.StackableWindow):
68 hildon.StackableWindow.__init__(self)
69 self.set_title("Playlists")
71 label = gtk.Label("Playlists")
72 vbox = gtk.VBox(False, 0)
73 vbox.pack_start(label, True, True, 0)
82 def create_window(self):
83 self.app = hildon.Program()
84 self.window = hildon.StackableWindow()
85 self.app.add_window(self.window)
87 self.window.set_title("jamaendo")
88 self.window.connect("destroy", self.destroy)
90 self.CONFDIR = os.path.expanduser('~/MyDocs/.jamaendo')
91 jamaendo.set_cache_dir(self.CONFDIR)
92 settings.set_filename(os.path.join(self.CONFDIR, 'ui_settings'))
95 postoffice.connect('request-album-cover', self.on_request_cover)
97 def save_settings(self):
100 def create_menu(self):
101 self.menu = hildon.AppMenu()
103 #search = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
104 #search.set_label("Search")
105 #search.connect("clicked", self.on_search)
106 #self.menu.append(search)
108 #player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
109 #player.set_label("Open player")
110 #player.connect("clicked", self.on_player)
111 #self.menu.append(player)
113 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
114 player.set_label("Favorites")
115 player.connect("clicked", self.on_favorites)
116 self.menu.append(player)
118 #player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
119 #player.set_label("Playlists")
120 #player.connect("clicked", self.on_playlists)
121 #self.menu.append(player)
123 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
124 player.set_label("Settings")
125 player.connect("clicked", self.on_settings)
126 self.menu.append(player)
129 # Don't use localdb ATM
130 #refresh = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
131 #refresh.set_label("Refresh")
132 #refresh.connect("clicked", self.on_refresh)
133 #self.menu.append(refresh)
135 menu_about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
136 menu_about.set_label("About")
137 menu_about.connect("clicked", self.show_about, self.window)
138 self.menu.append(menu_about)
139 gtk.about_dialog_set_url_hook(self.open_link, None)
142 self.window.set_app_menu(self.menu)
145 def setup_widgets(self):
146 bgimg = util.find_resource('bg.png')
148 background, mask = gtk.gdk.pixbuf_new_from_file(bgimg).render_pixmap_and_mask()
149 self.window.realize()
150 self.window.window.set_back_pixmap(background, False)
152 bbox = gtk.HButtonBox()
153 alignment = gtk.Alignment(xalign=0.2, yalign=0.925, xscale=1.0)
155 bbox.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
157 self.window.add(alignment)
159 self.add_mainscreen_button("Featured", "Most listened to", self.on_featured)
160 self.add_mainscreen_button("Radios", "The best in free music", self.on_radios)
161 self.add_mainscreen_button("Search", "Search for artists/albums", self.on_search)
163 self.window.show_all()
165 def add_mainscreen_button(self, title, subtitle, callback):
166 btn = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT,
167 hildon.BUTTON_ARRANGEMENT_VERTICAL)
168 btn.set_text(title, subtitle)
169 btn.set_property('width-request', 225)
170 btn.connect('clicked', callback)
173 def on_request_cover(self, albumid, size):
174 jamaendo.get_album_cover_async(self.got_album_cover, int(albumid), size)
176 def got_album_cover(self, albumid, size, cover):
177 postoffice.notify('album-cover', albumid, size, cover)
179 #def add_featured_button(self):
180 # self.featured_sel = hildon.TouchSelector(text=True)
181 # self.featured_sel.append_text("Albums of the week")
182 # self.featured_sel.append_text("Tracks of the week")
183 # self.featured_sel.append_text("New releases")
184 # btn = hildon.PickerButton(gtk.HILDON_SIZE_THUMB_HEIGHT,
185 # hildon.BUTTON_ARRANGEMENT_VERTICAL)
186 # btn.set_text("Featured", "Most listened to")
187 # btn.set_property('width-request', 225)
188 # btn.set_selector(self.featured_sel)
189 # self.featured_btn = btn
192 def destroy(self, widget):
193 postoffice.disconnect('request-album-cover', self.on_request_cover)
196 def show_about(self, w, win):
197 dialog = gtk.AboutDialog()
198 dialog.set_program_name("jamaendo")
199 dialog.set_website("http://github.com/krig")
200 dialog.set_website_label("http://github.com/krig")
201 dialog.set_version(VERSION)
202 dialog.set_license("""Copyright (c) 2010, Kristoffer Gronlund
205 Redistribution and use in source and binary forms, with or without
206 modification, are permitted provided that the following conditions are met:
207 * Redistributions of source code must retain the above copyright
208 notice, this list of conditions and the following disclaimer.
209 * Redistributions in binary form must reproduce the above copyright
210 notice, this list of conditions and the following disclaimer in the
211 documentation and/or other materials provided with the distribution.
212 * Neither the name of Jamaendo nor the
213 names of its contributors may be used to endorse or promote products
214 derived from this software without specific prior written permission.
216 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
217 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
218 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
219 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
220 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
221 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
222 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
223 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
224 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
225 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
227 dialog.set_authors(("Kristoffer Gronlund <kristoffer.gronlund@purplescout.se>",
228 "Based on Panucci, written by Thomas Perl <thpinfo.com>"))
229 dialog.set_comments("""Jamaendo plays music from the music catalog of JAMENDO.
231 JAMENDO is an online platform that distributes musical works under Creative Commons licenses.""")
232 gtk.about_dialog_set_email_hook(self.open_link, dialog)
233 gtk.about_dialog_set_url_hook(self.open_link, dialog)
234 dialog.connect( 'response', lambda dlg, response: dlg.destroy())
235 for parent in dialog.vbox.get_children():
236 for child in parent.get_children():
237 if isinstance(child, gtk.Label):
238 child.set_selectable(False)
239 child.set_alignment(0.0, 0.5)
243 def open_link(self, d, url, data):
244 print "url: %s" % (url)
246 webbrowser.open_new(url)
249 #def on_refresh(self, button):
250 # dialog = RefreshDialog()
255 def on_featured(self, button):
256 dialog = hildon.PickerDialog(self.window)
257 sel = hildon.TouchSelector(text=True)
258 for feature, _ in FeaturedWindow.features:
259 sel.append_text(feature)
260 dialog.set_selector(sel)
261 dialog.set_title("Featured")
262 if dialog.run() == gtk.RESPONSE_OK:
263 txt = sel.get_current_text()
264 self.featuredwnd = FeaturedWindow(txt)
265 self.featuredwnd.show_all()
268 def on_radios(self, button):
269 self.radioswnd = RadiosWindow()
270 self.radioswnd.show_all()
272 def on_search(self, button):
273 self.searchwnd = SearchWindow()
274 self.searchwnd.show_all()
276 def on_playlists(self, button):
277 self.playlistswnd = PlaylistsWindow()
278 self.playlistswnd.show_all()
280 def on_settings(self, button):
281 dialog = gtk.Dialog()
282 dialog.set_title("Settings")
283 dialog.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK )
285 tbl = gtk.Table(1, 2)
286 tbl.attach(gtk.Label("Username:"), 0, 1, 0, 1)
287 entry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
288 entry.set_placeholder("jamendo.com username")
290 entry.set_text(settings.user)
291 tbl.attach(entry, 1, 2, 0, 1)
292 vbox.pack_start(tbl, True, True, 2)
294 result = dialog.run()
295 val = entry.get_text()
298 if val and result == gtk.RESPONSE_OK:
299 print "new user name:", val
304 def on_favorites(self, button):
305 self.favoriteswnd = FavoritesWindow()
306 self.favoriteswnd.show_all()
308 def on_player(self, button):
309 open_playerwindow([])
312 def on_search(self, button):
314 self.searchbar.show()
316 self.searchstore = gtk.ListStore(gobject.TYPE_STRING)
317 iter = self.searchstore.append()
318 self.searchstore.set(iter, 0, "Test1")
319 iter = self.searchstore.append()
320 self.searchstore.set(iter, 0, "Test2")
321 self.searchbar = hildon.FindToolbar("Search", self.searchstore, 0)
322 self.searchbar.set_active(0)
323 self.window.add_toolbar(self.searchbar)
324 self.searchbar.show()
328 ossohelper.application_init('org.jamaendo', '0.1')
332 self.window.show_all()
334 ossohelper.application_exit()
336 if __name__=="__main__":