├── modules ├── __init__.py ├── constants.py ├── errors.py ├── get_themepack.py ├── get_imagepack.py ├── generate_changelog.py ├── clBrowserInterface.py ├── clDownloader.py ├── clEntry.py ├── clEvent.py ├── clXMLRPC.py ├── clThreadedDownload.py └── notification.py ├── extended_modules ├── __init__.py ├── bookmarks.glade └── clBookmarkDialog.py ├── clLayouts ├── default_layouts │ └── __init__.py └── __init__.py ├── plugins ├── torrent-peer │ ├── pytorrent │ │ ├── __init__.py │ │ ├── daemon.py │ │ ├── client.py │ │ ├── connection.py │ │ └── torrent.py │ ├── torrent-peer.info │ └── __init__.py ├── jamlists │ ├── 100.png │ ├── jamlists.info │ └── jamlists.info~ ├── rating │ ├── star1.png │ ├── star2.png │ ├── star3.png │ ├── star4.png │ ├── star5.png │ ├── rating.png │ ├── rating.info │ ├── rating.info~ │ └── patch ├── lyrics │ ├── lyrics.png │ └── lyrics.info ├── imagepack │ ├── package.png │ ├── imagepack.info │ └── imagepack.glade ├── listenstats │ ├── listenstats.png │ ├── listenstats.info │ └── listenstats.info~ ├── artist_browser │ ├── artist_browser.png │ ├── artist_browser.info │ ├── artist_browser.info~ │ └── __init__.py ├── spread-torrent │ ├── spread-torrent.png │ └── spread-torrent.info ├── radios │ ├── radios.info │ └── radios.info~ ├── jam_query │ ├── jam_query.info │ ├── jam_query.info~ │ └── __init__.py ├── example │ ├── example.info │ ├── example.info~ │ └── __init__.py ├── randomplayback │ ├── randomplayback.info │ └── randomplayback.info~ ├── webkit-plugin │ ├── webkit.info~ │ └── webkit-plugin.info ├── downloadGUI │ ├── downloadGUI.info │ ├── downloadGUI.info~ │ └── downloadGUI.glade ├── search │ ├── search.info │ └── search.info~ ├── PVC │ ├── PVC.info │ ├── PVC.info~ │ ├── progressdialog.glade │ ├── PVC.glade_window │ └── PVC.glade ├── mmhotkeys │ ├── mmhotkeys.info │ ├── mmhotkeys.info~ │ └── __init__.py ├── mozplug │ ├── mozplug.info │ ├── mozplug.info~ │ └── mozplug.glade ├── configtool │ ├── configtool.info~ │ ├── configtool.info │ └── configtool.glade ├── lastfm │ ├── lastfm.info │ ├── lastfm.info~ │ ├── patch │ ├── __init__.py.BASE │ ├── __init__.py.OTHER.moved │ └── __init__.py.THIS ├── nowplaying │ ├── nowplaying.info │ ├── nowplaying.info~ │ └── __init__.py ├── starred_albums │ ├── starred_albums.info │ └── starred_albums.info~ ├── librefm │ ├── librefm.info │ ├── librefm.info~ │ ├── patch │ ├── __init__.py.BASE │ ├── __init__.py.OTHER.moved │ └── __init__.py.THIS ├── jamscrobble │ ├── librefm.info~ │ ├── jamscrobble.info │ └── patch └── README ├── images ├── cd.png ├── juk.png ├── money.png ├── radio.png ├── star.png ├── burn_cd.png ├── burn_usb.png ├── calendar.png ├── personal.png ├── playlist.png ├── plugin.png ├── plugin2D.png ├── pyjama.png ├── radio2.png ├── shuffle.png ├── folder_06.png ├── kdmconfig.png ├── clip_note_1.png ├── file-audio-cd.png ├── file-mp3-cd.png ├── green_beetle.png ├── pyjama_anim.gif ├── blue_grey_tag_T.png ├── hspbp-burnstation.png ├── license_images │ ├── pd.png │ ├── artlibre.png │ ├── cc_big │ │ ├── by.png │ │ ├── by-nc.png │ │ ├── by-nd.png │ │ ├── by-sa.png │ │ ├── by-nc-nd.png │ │ ├── by-nc-sa.png │ │ ├── sampling-plus.png │ │ └── nc-sampling-plus.png │ └── cc_small │ │ ├── by.png │ │ ├── by-nc.png │ │ ├── by-nd.png │ │ ├── by-sa.png │ │ ├── by-nc-nd.png │ │ ├── by-nc-sa.png │ │ ├── sampling-plus.png │ │ └── nc-sampling-plus.png ├── preferences_plugin.png ├── view-media-equalizer.png ├── info.txt ├── info.txt~ └── pyjama.xpm ├── locale ├── bg │ └── LC_MESSAGES │ │ └── pyjama.mo ├── ca │ └── LC_MESSAGES │ │ └── pyjama.mo ├── da │ └── LC_MESSAGES │ │ └── pyjama.mo ├── de │ └── LC_MESSAGES │ │ └── pyjama.mo ├── eo │ └── LC_MESSAGES │ │ └── pyjama.mo ├── es │ └── LC_MESSAGES │ │ └── pyjama.mo ├── fr │ └── LC_MESSAGES │ │ └── pyjama.mo ├── gl │ └── LC_MESSAGES │ │ └── pyjama.mo ├── hu │ └── LC_MESSAGES │ │ └── pyjama.mo ├── it │ └── LC_MESSAGES │ │ └── pyjama.mo ├── pl │ └── LC_MESSAGES │ │ └── pyjama.mo ├── sv │ └── LC_MESSAGES │ │ └── pyjama.mo └── en_GB │ └── LC_MESSAGES │ └── pyjama.mo ├── burnstation.txt ├── pyjama.desktop ├── themes └── README ├── eq_presets ├── preparerelease.py ├── usb-automount.sh ├── pyjama.cfg └── about.glade /modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extended_modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clLayouts/default_layouts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/torrent-peer/pytorrent/__init__.py: -------------------------------------------------------------------------------- 1 | from client import TorrentClient -------------------------------------------------------------------------------- /images/cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/cd.png -------------------------------------------------------------------------------- /images/juk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/juk.png -------------------------------------------------------------------------------- /images/money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/money.png -------------------------------------------------------------------------------- /images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/radio.png -------------------------------------------------------------------------------- /images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/star.png -------------------------------------------------------------------------------- /images/burn_cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/burn_cd.png -------------------------------------------------------------------------------- /images/burn_usb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/burn_usb.png -------------------------------------------------------------------------------- /images/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/calendar.png -------------------------------------------------------------------------------- /images/personal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/personal.png -------------------------------------------------------------------------------- /images/playlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/playlist.png -------------------------------------------------------------------------------- /images/plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/plugin.png -------------------------------------------------------------------------------- /images/plugin2D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/plugin2D.png -------------------------------------------------------------------------------- /images/pyjama.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/pyjama.png -------------------------------------------------------------------------------- /images/radio2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/radio2.png -------------------------------------------------------------------------------- /images/shuffle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/shuffle.png -------------------------------------------------------------------------------- /images/folder_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/folder_06.png -------------------------------------------------------------------------------- /images/kdmconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/kdmconfig.png -------------------------------------------------------------------------------- /images/clip_note_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/clip_note_1.png -------------------------------------------------------------------------------- /images/file-audio-cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/file-audio-cd.png -------------------------------------------------------------------------------- /images/file-mp3-cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/file-mp3-cd.png -------------------------------------------------------------------------------- /images/green_beetle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/green_beetle.png -------------------------------------------------------------------------------- /images/pyjama_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/pyjama_anim.gif -------------------------------------------------------------------------------- /plugins/jamlists/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/jamlists/100.png -------------------------------------------------------------------------------- /plugins/rating/star1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/star1.png -------------------------------------------------------------------------------- /plugins/rating/star2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/star2.png -------------------------------------------------------------------------------- /plugins/rating/star3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/star3.png -------------------------------------------------------------------------------- /plugins/rating/star4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/star4.png -------------------------------------------------------------------------------- /plugins/rating/star5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/star5.png -------------------------------------------------------------------------------- /images/blue_grey_tag_T.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/blue_grey_tag_T.png -------------------------------------------------------------------------------- /plugins/lyrics/lyrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/lyrics/lyrics.png -------------------------------------------------------------------------------- /plugins/rating/rating.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/rating/rating.png -------------------------------------------------------------------------------- /images/hspbp-burnstation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/hspbp-burnstation.png -------------------------------------------------------------------------------- /images/license_images/pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/pd.png -------------------------------------------------------------------------------- /images/preferences_plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/preferences_plugin.png -------------------------------------------------------------------------------- /plugins/imagepack/package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/imagepack/package.png -------------------------------------------------------------------------------- /images/view-media-equalizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/view-media-equalizer.png -------------------------------------------------------------------------------- /locale/bg/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/bg/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/ca/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/ca/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/da/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/da/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/de/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/de/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/eo/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/eo/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/es/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/es/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/fr/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/fr/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/gl/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/gl/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/hu/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/hu/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/it/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/it/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/pl/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/pl/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /locale/sv/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/sv/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /images/license_images/artlibre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/artlibre.png -------------------------------------------------------------------------------- /locale/en_GB/LC_MESSAGES/pyjama.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/locale/en_GB/LC_MESSAGES/pyjama.mo -------------------------------------------------------------------------------- /images/license_images/cc_big/by.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by.png -------------------------------------------------------------------------------- /plugins/listenstats/listenstats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/listenstats/listenstats.png -------------------------------------------------------------------------------- /images/license_images/cc_big/by-nc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by-nc.png -------------------------------------------------------------------------------- /images/license_images/cc_big/by-nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by-nd.png -------------------------------------------------------------------------------- /images/license_images/cc_big/by-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by-sa.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by.png -------------------------------------------------------------------------------- /images/license_images/cc_big/by-nc-nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by-nc-nd.png -------------------------------------------------------------------------------- /images/license_images/cc_big/by-nc-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/by-nc-sa.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by-nc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by-nc.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by-nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by-nd.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by-sa.png -------------------------------------------------------------------------------- /plugins/artist_browser/artist_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/artist_browser/artist_browser.png -------------------------------------------------------------------------------- /plugins/spread-torrent/spread-torrent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/plugins/spread-torrent/spread-torrent.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by-nc-nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by-nc-nd.png -------------------------------------------------------------------------------- /images/license_images/cc_small/by-nc-sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/by-nc-sa.png -------------------------------------------------------------------------------- /images/license_images/cc_big/sampling-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/sampling-plus.png -------------------------------------------------------------------------------- /images/license_images/cc_big/nc-sampling-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_big/nc-sampling-plus.png -------------------------------------------------------------------------------- /images/license_images/cc_small/sampling-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/sampling-plus.png -------------------------------------------------------------------------------- /images/license_images/cc_small/nc-sampling-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stef/burnstation2/master/images/license_images/cc_small/nc-sampling-plus.png -------------------------------------------------------------------------------- /plugins/radios/radios.info: -------------------------------------------------------------------------------- 1 | name = Radios 2 | description = Jamendo radios 3 | order = 100 4 | author = Daniel Nögel 5 | License = GPLv3 6 | copyright = 2009 by Daniel Nögel 7 | homepage = http://xn--ngel-5qa.de 8 | -------------------------------------------------------------------------------- /plugins/rating/rating.info: -------------------------------------------------------------------------------- 1 | Name = Rating 2 | Description = Allows you to rate tracks and albums 3 | Version = 0.2 4 | Author = Daniel Nögel 5 | Copyright = Copyright 2009 by Daniel Nögel 6 | Order = 200 7 | license = GPLv3 8 | -------------------------------------------------------------------------------- /plugins/radios/radios.info~: -------------------------------------------------------------------------------- 1 | name = Radios 2 | description = Jamendo radios 3 | order = 100 4 | author = Daniel Nögel 5 | License = GPLv3 6 | copyright = 2009 by Daniel Nögel 7 | haspreferences = False 8 | homepage = http://xn--ngel-5qa.de 9 | -------------------------------------------------------------------------------- /plugins/jam_query/jam_query.info: -------------------------------------------------------------------------------- 1 | Name = Jamendo Query Indicator 2 | Author = Daniel Nögel 3 | Copyright = Copyright (c) 2009 by Daniel Nögel 4 | Description = Shows a dialog while jamendo is being queried 5 | Order = 200 6 | license = GPLv3 7 | -------------------------------------------------------------------------------- /plugins/lyrics/lyrics.info: -------------------------------------------------------------------------------- 1 | Name=Lyrics 2 | Description=Show a track's lyrics 3 | Author=Daniel Nögel 4 | Copyright=Copyright (c) 2009 by Daniel Nögel 5 | Homepage=http://www.launchpad.net/pyjama 6 | Version=0.1 7 | Order=600 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/listenstats/listenstats.info: -------------------------------------------------------------------------------- 1 | Name = Listen Statistics 2 | description = Generates stats about what you listen to 3 | Version = 0.4 4 | Order = 200 5 | Author = Daniel Nögel 6 | Copyright = Copyright 2009 by Daniel Nögel 7 | license = GPLv3 8 | -------------------------------------------------------------------------------- /plugins/rating/rating.info~: -------------------------------------------------------------------------------- 1 | Name = Rating 2 | Description = Allows you to rate tracks and albums 3 | Version = 0.2 4 | Author = Daniel Nögel 5 | Copyright = Copyright 2009 by Daniel Nögel 6 | Order = 200 7 | haspreferences = True 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/example/example.info: -------------------------------------------------------------------------------- 1 | Name=Plugin Example 2 | Version=0.1 3 | Order=100 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Just a pyjama plugin example 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /burnstation.txt: -------------------------------------------------------------------------------- 1 | Ez a lemez a Burnstation 2.0-ás verziójával készült. A Burnstation álatl elérhető összes anyag a Creative Commons licenc alá tartozik. Így ezen zenék ilyen terjesztése teljesen legális, a licenc bárkinek megengedi a terjesztést és korlátlan használatot. 2 | -------------------------------------------------------------------------------- /plugins/jam_query/jam_query.info~: -------------------------------------------------------------------------------- 1 | Name = Jamendo Query Indicator 2 | Author = Daniel Nögel 3 | Copyright = Copyright (c) 2009 by Daniel Nögel 4 | Description = Shows a dialog while jamendo is being queried 5 | haspreferences=False 6 | Order = 200 7 | license = GPLv3 8 | -------------------------------------------------------------------------------- /plugins/randomplayback/randomplayback.info: -------------------------------------------------------------------------------- 1 | Name = Random Playback 2 | author = Daniel Nögel 3 | Version = 0.3 4 | Description=Play random songs 5 | order = 190 6 | copyright=Copyright 2009 by Daniel Nögel 7 | homepage= http://launchpad.net/pyjama 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/webkit-plugin/webkit.info~: -------------------------------------------------------------------------------- 1 | Name=Mozilla Plugin 2 | Version=0.4 3 | Order=10000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Implements a firefox browser 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /pyjama.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Encoding=UTF-8 4 | Name=Pyjama Music Player 5 | Comment=Jamendo Music Player 6 | Exec=pyjama 7 | Icon=pyjama 8 | Terminal=false 9 | Type=Application 10 | Categories=AudioVideo;Player; 11 | GenericName[de_DE]= 12 | -------------------------------------------------------------------------------- /plugins/listenstats/listenstats.info~: -------------------------------------------------------------------------------- 1 | Name = Listen Statistics 2 | description = Generates stats about what you listen to 3 | Version = 0.4 4 | Order = 200 5 | Author = Daniel Nögel 6 | Copyright = Copyright 2009 by Daniel Nögel 7 | haspreferences = True 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/artist_browser/artist_browser.info: -------------------------------------------------------------------------------- 1 | Name = Artist Browser 2 | Author = Daniel Nögel 3 | Homepage = http://launchpad.net/pyjama 4 | Version = 0.1 5 | Order = 108 6 | description = Browsing artists on jamendo 7 | copyright = Copyright (c) 2009 by Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/downloadGUI/downloadGUI.info: -------------------------------------------------------------------------------- 1 | name=Dowload GUI 2 | version=0.2 3 | order=8000 4 | homepage=http://launchpad.net/pyjama 5 | author=Daniel Nögel 6 | description = A simple GUI downloader for jamendo database dumps 7 | copyright = Copyright (c) 2009 Daniel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/search/search.info: -------------------------------------------------------------------------------- 1 | Name=Database Search 2 | Version=0.3.1 3 | Order=50 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = search the databse for artists, albums and tracks 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/torrent-peer/torrent-peer.info: -------------------------------------------------------------------------------- 1 | name = Pyjama Torrent Peer 2 | order = 100 3 | version = 0.1 4 | copyright = Copyright 2009 by Daniel Nögel 5 | haspreferences = False 6 | description = A torrent peer for spreading jamendo's albums 7 | author = Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/PVC/PVC.info: -------------------------------------------------------------------------------- 1 | Name = Pyjama Version Control 2 | Version = 0.1 3 | Order = 10000 4 | Author = Daniel Nögel 5 | Copyright = Copyright 2009 by Daniel Nögel 6 | homepage = http://launchpad.net/pyjama 7 | Description = Checks for new pyjama versions and installs them 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/imagepack/imagepack.info: -------------------------------------------------------------------------------- 1 | Name = Imagepack 2 | Description = Make browsing jamendo faster by getting an imagepack 3 | Author = Daniel Nögel 4 | Version = 0.1 5 | Order = 9000 6 | homepage = http://launchpad.net/pyjama 7 | copyright = (c) 2009 by Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/jamlists/jamlists.info: -------------------------------------------------------------------------------- 1 | Name = Jamlist 2 | author = Daniel Nögel 3 | Version = 0.3 4 | Description=Showing some general jamendo playlists like the "top 100" 5 | order = 180 6 | copyright=Copyright 2009 by Daniel Nögel 7 | homepage= http://launchpad.net/pyjama 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/mmhotkeys/mmhotkeys.info: -------------------------------------------------------------------------------- 1 | Version=0.1.1 2 | Order=30 3 | Name=Multimedia Hotkeys 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Binds pyjama to your keyboard's multimedia key 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/mozplug/mozplug.info: -------------------------------------------------------------------------------- 1 | Name=Mozilla Plugin 2 | Version=0.4 3 | Order=10000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Implements a firefox browser 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | autoload = false 10 | -------------------------------------------------------------------------------- /plugins/configtool/configtool.info~: -------------------------------------------------------------------------------- 1 | Name=Configtool 2 | Version=0.3.2 3 | Order=32000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Generic config parser 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = False 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/example/example.info~: -------------------------------------------------------------------------------- 1 | Name=Plugin Example 2 | Version=0.1 3 | Order=100 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Just a pyjama plugin example 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = True 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/mozplug/mozplug.info~: -------------------------------------------------------------------------------- 1 | Name=Mozilla Plugin 2 | Version=0.4 3 | Order=10000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Implements a firefox browser 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = True 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/randomplayback/randomplayback.info~: -------------------------------------------------------------------------------- 1 | Name = Random Playback 2 | author = Daniel Nögel 3 | Version = 0.3 4 | Description=Play random songs 5 | order = 190 6 | haspreferences=False 7 | copyright=Copyright 2009 by Daniel Nögel 8 | homepage= http://launchpad.net/pyjama 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/webkit-plugin/webkit-plugin.info: -------------------------------------------------------------------------------- 1 | Name=Webkit Plugin 2 | Version=0.1 3 | Order=10000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Implements a webkit browser 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | autoload = false 10 | -------------------------------------------------------------------------------- /plugins/lastfm/lastfm.info: -------------------------------------------------------------------------------- 1 | Name=last.fm plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski 5 | Homepage = http://launchpad.net/pyjama 6 | Description = Simple plugin for scrobbling music from Jamendo to last.fm 7 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 8 | License = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/downloadGUI/downloadGUI.info~: -------------------------------------------------------------------------------- 1 | name=Dowload GUI 2 | version=0.2 3 | order=8000 4 | homepage=http://launchpad.net/pyjama 5 | author=Daniel Nögel 6 | haspreferences=False 7 | description = A simple GUI downloader for jamendo database dumps 8 | copyright = Copyright (c) 2009 Daniel 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/artist_browser/artist_browser.info~: -------------------------------------------------------------------------------- 1 | Name = Artist Browser 2 | Author = Daniel Nögel 3 | Homepage = http://launchpad.net/pyjama 4 | Version = 0.1 5 | Order = 108 6 | haspreferences=False 7 | description = Browsing artists on jamendo 8 | copyright = Copyright (c) 2009 by Daniel Nögel 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/jamlists/jamlists.info~: -------------------------------------------------------------------------------- 1 | Name = Jamlist 2 | author = Daniel Nögel 3 | Version = 0.3 4 | Description=Showing some general jamendo playlists like the "top 100" 5 | order = 180 6 | haspreferences=False 7 | copyright=Copyright 2009 by Daniel Nögel 8 | homepage= http://launchpad.net/pyjama 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/nowplaying/nowplaying.info: -------------------------------------------------------------------------------- 1 | Name=Now playing notification 2 | Version=0.1 3 | Order=100 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Show notifications when a new song is being played and execute a script. 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/search/search.info~: -------------------------------------------------------------------------------- 1 | Name=Database Search 2 | Version=0.3.1 3 | Order=50 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = search the databse for artists, albums and tracks 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = False 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/PVC/PVC.info~: -------------------------------------------------------------------------------- 1 | Name = Pyjama Version Control 2 | Version = 0.1 3 | Order = 100 4 | Author = Daniel Nögel 5 | Copyright = Copyright 2009 by Daniel Nögel 6 | homepage = http://launchpad.net/pyjama 7 | Description = Checks for new pyjama versions and installs them 8 | haspreferences = False 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/mmhotkeys/mmhotkeys.info~: -------------------------------------------------------------------------------- 1 | Version=0.1.1 2 | Order=30 3 | Name=Multimedia Hotkeys 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Binds pyjama to your keyboard's multimedia key 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = False 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/starred_albums/starred_albums.info: -------------------------------------------------------------------------------- 1 | Name=Starred Albums 2 | Version=0.4 3 | Order=8001 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Imports a user's stared albums from jamendo and let you star any album on pyjama 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/spread-torrent/spread-torrent.info: -------------------------------------------------------------------------------- 1 | Name=Spread Torrent (Potato) 2 | Version=0.1 3 | Order=9010 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Loads and spreads torrents from jamendo which needs seeding. 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | license = GPLv3 9 | autoload = false 10 | -------------------------------------------------------------------------------- /plugins/configtool/configtool.info: -------------------------------------------------------------------------------- 1 | Name=Configtool 2 | Version=0.3.3 3 | Order=32000 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | copyright = Copyright (c) 2009 Daniel Nögel 7 | license = GPLv3 8 | description = Generic config parser - only for advanced users. 9 | Please use pyjama's preferences-dialog instead. 10 | -------------------------------------------------------------------------------- /plugins/lastfm/lastfm.info~: -------------------------------------------------------------------------------- 1 | Name=last.fm plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski 5 | Homepage = http://launchpad.net/pyjama 6 | Description = Simple plugin for scrobbling music from Jamendo to last.fm 7 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 8 | License = GPLv3 9 | haspreferences = True 10 | -------------------------------------------------------------------------------- /plugins/librefm/librefm.info: -------------------------------------------------------------------------------- 1 | Name=libre.fm plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski, Daniel Nögel (porting last.fm plugin) 5 | Homepage = http://launchpad.net/pyjama 6 | Description = Simple plugin for scrobbling music from Jamendo to libre.fm 7 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 8 | License = GPLv3 9 | -------------------------------------------------------------------------------- /plugins/nowplaying/nowplaying.info~: -------------------------------------------------------------------------------- 1 | Name=Now playing notification 2 | Version=0.1 3 | Order=100 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Show notifications when a new song is being played and execute a script. 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = True 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/starred_albums/starred_albums.info~: -------------------------------------------------------------------------------- 1 | Name=Starred Albums 2 | Version=0.4 3 | Order=800 4 | author= Daniel Nögel 5 | homepage = http://launchpad.net/pyjama 6 | description = Imports a user's stared albums from jamendo and let you star any album on pyjama 7 | copyright = Copyright (c) 2009 Daniel Nögel 8 | haspreferences = False 9 | license = GPLv3 10 | -------------------------------------------------------------------------------- /plugins/librefm/librefm.info~: -------------------------------------------------------------------------------- 1 | Name=libre.fm plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski, Daniel Nögel (porting last.fm plugin) 5 | Homepage = http://launchpad.net/pyjama 6 | Description = Simple plugin for scrobbling music from Jamendo to libre.fm 7 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 8 | License = GPLv3 9 | haspreferences = True 10 | -------------------------------------------------------------------------------- /plugins/jamscrobble/librefm.info~: -------------------------------------------------------------------------------- 1 | Name=libre.fm plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski, Daniel Nögel (porting last.fm plugin) 5 | Homepage = http://launchpad.net/pyjama 6 | Description = Simple plugin for scrobbling music from Jamendo to libre.fm 7 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 8 | License = GPLv3 9 | haspreferences = True 10 | -------------------------------------------------------------------------------- /themes/README: -------------------------------------------------------------------------------- 1 | This folder is preserved for the standard-theme, which 2 | is delivered with pyjama. It is going to be copied to 3 | /usr/share/apps/pyjama during installation. Copying 4 | other themes - which are not set to be standard-theme 5 | in constants.py - will have NO EFFECT. 6 | Themes you want to install HAVE to be placed into the 7 | folder 8 | ~/.pyjama/themes. 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugins/jamscrobble/jamscrobble.info: -------------------------------------------------------------------------------- 1 | Name=Jamendo Scrobble Plugin 2 | Version=0.1 3 | Order=100 4 | Author=Sebastian "prmtl" Kalinowski, Daniel Nögel (porting last.fm plugin) 5 | Homepage = http://launchpad.net/pyjama 6 | Copyright = Copyright (c) 2009 Sebastian Kalinowski 7 | License = GPLv3 8 | autoload = false 9 | Description = Simple plugin for scrobbling music to jamendo.com: Right now jamendo does not support the current audioscrobbler protocol so this plugin cannot be used right now. 10 | -------------------------------------------------------------------------------- /eq_presets: -------------------------------------------------------------------------------- 1 | # 2 | # Equalizer Presets 3 | # 4 | # You can enter presets here line by line 5 | # 6 | # A preset consists of an id-string and n values 7 | # for n being the number of bands on the equalizer. 8 | # 9 | # Right now pyjama only comes with a 10 band equalizer. 10 | # 11 | # So for now you'll have to enter 10(!) values for the EQ. 12 | # Any preset with more or less than 10 values will not be 13 | # loaded, yet. 14 | # 15 | # 16 | # Your preset's name may not contain spaces 17 | # Range: -24.0 to 12.0 18 | # Bands: 29 59 119 227 474 947 1980 3700 7500 15000 hz 19 | 20 | # 21 | # Default Presets 22 | # 23 | Default 0 0 0 0 0 0 0 0 0 0 24 | Rock 5,7 1,9 -2,5 -4,6 -5,5 -8,8 -4,8 -0,2 4,1 10,4 25 | Hall -6 -3 0 3 6 6 3 0 -3 -6 26 | #Test 1 2 3 4 5 6 7 8 9 0 27 | #Test2 -24 -20 -18 -16 -14 -12 -10 -0 -6 -10 28 | -------------------------------------------------------------------------------- /plugins/torrent-peer/pytorrent/daemon.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | import signal 4 | import time 5 | 6 | class Daemon(object): 7 | term = signal.SIGTERM 8 | kill = signal.SIGKILL 9 | 10 | def __init__(self, executable): 11 | self.executable = executable 12 | self.pid = None 13 | self.process = None 14 | 15 | def start(self): 16 | self.process = subprocess.Popen(self.executable) 17 | self.pid = self.process.pid 18 | 19 | def stop(self): 20 | if self.process: 21 | pid = self.process.pid 22 | 23 | for i in range(0, 10): 24 | if self.process.poll() is not None: 25 | return 26 | os.kill(pid, self.term) 27 | time.sleep(0.1) 28 | 29 | for i in range(0, 10): 30 | if self.process.poll() is not None: 31 | return 32 | os.kill(pid, self.kill) 33 | time.sleep(0.1) 34 | -------------------------------------------------------------------------------- /plugins/lastfm/patch: -------------------------------------------------------------------------------- 1 | 32,33c32,33 2 | < self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 3 | < self.password=self.pyjama.settings.get_value('LASTFM','PASS') 4 | --- 5 | > self.login=self.pyjama.settings.get_value('LASTFM','LOGIN', None) 6 | > self.password=self.pyjama.settings.get_value('LASTFM','PASS', None) 7 | 37a38,40 8 | > if self.login is None or self.password is None: 9 | > return 10 | > 11 | 45c48 12 | < raise 13 | --- 14 | > #raise 15 | 201d203 16 | < password.set_text(pass_value) 17 | 202a205 18 | > password.set_text(pass_value) 19 | 212c215 20 | < if result == 1: 21 | --- 22 | > if result == -3:#gtk.RESPONSE_OK: 23 | 221a225,232 24 | > if check.get_active(): 25 | > try: 26 | > # pyjama has own last.fm clien id 'pyj' 27 | > scrobbler.login(str(login.get_text()), str(password.get_text()), client=('pyj','0.3')) 28 | > except Exception, e: 29 | > logging.error(e) 30 | > #raise 31 | > 32 | -------------------------------------------------------------------------------- /plugins/librefm/patch: -------------------------------------------------------------------------------- 1 | 32,33c32,33 2 | < self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 3 | < self.password=self.pyjama.settings.get_value('LASTFM','PASS') 4 | --- 5 | > self.login=self.pyjama.settings.get_value('LASTFM','LOGIN', None) 6 | > self.password=self.pyjama.settings.get_value('LASTFM','PASS', None) 7 | 37a38,40 8 | > if self.login is None or self.password is None: 9 | > return 10 | > 11 | 45c48 12 | < raise 13 | --- 14 | > #raise 15 | 201d203 16 | < password.set_text(pass_value) 17 | 202a205 18 | > password.set_text(pass_value) 19 | 212c215 20 | < if result == 1: 21 | --- 22 | > if result == -3:#gtk.RESPONSE_OK: 23 | 221a225,232 24 | > if check.get_active(): 25 | > try: 26 | > # pyjama has own last.fm clien id 'pyj' 27 | > scrobbler.login(str(login.get_text()), str(password.get_text()), client=('pyj','0.3')) 28 | > except Exception, e: 29 | > logging.error(e) 30 | > #raise 31 | > 32 | -------------------------------------------------------------------------------- /plugins/jamscrobble/patch: -------------------------------------------------------------------------------- 1 | 32,33c32,33 2 | < self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 3 | < self.password=self.pyjama.settings.get_value('LASTFM','PASS') 4 | --- 5 | > self.login=self.pyjama.settings.get_value('LASTFM','LOGIN', None) 6 | > self.password=self.pyjama.settings.get_value('LASTFM','PASS', None) 7 | 37a38,40 8 | > if self.login is None or self.password is None: 9 | > return 10 | > 11 | 45c48 12 | < raise 13 | --- 14 | > #raise 15 | 201d203 16 | < password.set_text(pass_value) 17 | 202a205 18 | > password.set_text(pass_value) 19 | 212c215 20 | < if result == 1: 21 | --- 22 | > if result == -3:#gtk.RESPONSE_OK: 23 | 221a225,232 24 | > if check.get_active(): 25 | > try: 26 | > # pyjama has own last.fm clien id 'pyj' 27 | > scrobbler.login(str(login.get_text()), str(password.get_text()), client=('pyj','0.3')) 28 | > except Exception, e: 29 | > logging.error(e) 30 | > #raise 31 | > 32 | -------------------------------------------------------------------------------- /preparerelease.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | 6 | VERSION = raw_input().strip() 7 | 8 | def replace(filename): 9 | fh = open(filename, "r") 10 | content = fh.read() 11 | content = content.replace("_VERSION_", VERSION) 12 | fh.close() 13 | 14 | fh = open(filename.replace("_draft", ""), "w") 15 | fh.write(content) 16 | fh.close() 17 | 18 | def replace_line(filename): 19 | line_to_search_for = "#!!Version line " 20 | rep = False 21 | 22 | fh = open(filename, "r") 23 | content = fh.read() 24 | fh.close() 25 | 26 | output = "" 27 | for line in content.split("\n"): 28 | if line_to_search_for in line: 29 | rep = True 30 | line = "VERSION=\"%s\" %s" % (VERSION, line_to_search_for) 31 | # print "replaced" 32 | output += line + "\n" 33 | 34 | # if not rep: 35 | # print "Did not replace any line" 36 | 37 | 38 | fh = open(filename, "w") 39 | fh.write(output[0:-1]) 40 | fh.close() 41 | 42 | replace("about.glade_draft") 43 | replace("control_draft") 44 | 45 | replace_line("modules/functions.py") 46 | 47 | print VERSION 48 | -------------------------------------------------------------------------------- /modules/constants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import sys 21 | import tempfile 22 | 23 | ############# 24 | # CONSTANTS # 25 | ############# 26 | 27 | INSTALL_DIR_POSIX = "/usr/share/apps/pyjama" 28 | INSTALL_DIR = "/usr/share/apps/pyjama" 29 | 30 | if "tmpdir" in sys.argv: 31 | PYJAMA_HOME_DIRECTORY_NAME = tempfile.mkdtemp("pyjama") 32 | else: 33 | # If you want to change pyjama's home directory name, 34 | # please edit this line: 35 | PYJAMA_HOME_DIRECTORY_NAME = ".pyjama" 36 | -------------------------------------------------------------------------------- /plugins/rating/patch: -------------------------------------------------------------------------------- 1 | — starhscale.py 2006-07-25 18:40:54.000000000 -0700 2 | +++ starhscale-treitter.py 2006-08-19 14:15:07.000000000 -0700 3 | @@ -142,7 +142,7 @@ 4 | 5 | def __init__(self, max_stars=5, stars=0): 6 | - ”"Initialization, numstars is the total number 7 | + ”"Initialization, max_stars is the total number 8 | of stars that may be visible, and stars is the current 9 | number of stars to draw”"” 10 | 11 | @@ -170,7 +170,7 @@ 12 | # and button click and button press events 13 | 14 | self.window = gtk.gdk.Window( 15 | - self.get_parent_window(), 16 | + parent=self.get_parent_window(), 17 | width=self.allocation.width, 18 | height=self.allocation.height, 19 | window_type=gdk.WINDOW_CHILD, 20 | @@ -252,7 +252,6 @@ 21 | y = event.y 22 | state = event.state 23 | 24 | - new_stars = 0 25 | if (state & gtk.gdk.BUTTON1_MASK): 26 | # loop through the sizes and see if the 27 | # number of stars should change 28 | @@ -268,7 +267,7 @@ 29 | return True 30 | 31 | def check_for_new_stars(self, xPos): 32 | - ”"This function will determin how many stars 33 | + ”"This function will determine how many stars 34 | will be show based on an x coordinate. If the 35 | number of stars changes the widget will be invalidated 36 | and the new number drawn”"” 37 | @@ -308,13 +307,13 @@ 38 | ”"set the maximum number of stars”"” 39 | 40 | if (self.max_stars != max_value): 41 | - ”"Save the old max incase it is less then the 42 | + ”"Save the old max incase it is less than the 43 | current number of stars, in which case we will 44 | have to redraw”"” 45 | 46 | if (max_value > 0): 47 | self.max_stars = max_value 48 | - #reinit the sizes list (should really be a sperate function 49 | + #reinit the sizes list (should really be a separate function) 50 | self.sizes = [] 51 | for count in range(0,self.max_stars): 52 | self.sizes.append((count * PIXMAP_SIZE) + BORDER_WIDTH) 53 | -------------------------------------------------------------------------------- /modules/errors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | ## @package errors 21 | # This module holds several exceptions that might 22 | # be raised by pyjama. 23 | 24 | # 25 | # Jamendo Errors 26 | # 27 | ## From this Class any Jamendo exception derives 28 | class JamendoQueryException(Exception): 29 | pass 30 | 31 | ## This exception will be raised when the user 32 | # queries jamendo to frequently (1s limit) 33 | class ToFast(JamendoQueryException): 34 | pass 35 | 36 | ## This exception is raised when interaction with 37 | # jamendo failed for some reasion. Pyjama will 38 | # popup an error dialog in those cases, too. 39 | class ConnectionError(JamendoQueryException): 40 | pass 41 | 42 | 43 | 44 | # 45 | # Database Errors 46 | # 47 | class DatabaseQueryException(Exception): 48 | def __init__(self): 49 | self.inst = None 50 | self.traceback = None 51 | 52 | 53 | ## This Exception will be raised when querying 54 | # the database failed. Pyjama will also popup 55 | # and error dialog with traceback infos. 56 | class QueryException(DatabaseQueryException): 57 | pass 58 | -------------------------------------------------------------------------------- /plugins/artist_browser/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2009 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import os 21 | 22 | import clArtistBrowser 23 | from modules import functions 24 | 25 | class main(): 26 | def __init__(self, pyjama): 27 | self.__pyjama = pyjama 28 | self.__pyjama.Events.connect_event("alldone", self.ev_alldone) 29 | 30 | def ev_alldone(self): 31 | # Register Layout 32 | self.__pyjama.layouts.register_layout("artistbrowser", clArtistBrowser.ArtistBrowser(self.__pyjama)) 33 | 34 | # Create menu entry: 35 | menu = self.__pyjama.window.menubar 36 | entry = menu.append_entry(menu.get_rootmenu("Browse"), _("Artists") + " (experimental)", "artistbrowser") 37 | entry.connect("activate", self.cb_show_alrtist_browser) 38 | menu.set_item_image(entry, os.path.join(functions.install_dir(), "images", "star.png")) 39 | # entry.set_sensitive(False) 40 | menu.show() 41 | 42 | def cb_show_alrtist_browser(self, widget): 43 | self.__pyjama.layouts.show_layout("artistbrowser", 10, 1, "0-9", who_called = "clArtistBrowser.__init__") 44 | -------------------------------------------------------------------------------- /modules/get_themepack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import os 21 | from time import time 22 | import functions 23 | 24 | # Gettext - Übersetzung 25 | functions.translation_gettext() 26 | #def _(string): 27 | # return string 28 | 29 | 30 | ################################################################### 31 | # 32 | # download and extrackt themes 33 | # RETURNS: 0 = ok, 1 = download error, 2 = extraction error 34 | # 35 | def download_pack(): 36 | home=functions.preparedirs() 37 | print ("Downloading themepack") 38 | ret = os.system("wget -cO %s xn--ngel-5qa.de/pyjama/release/themepack.tar.gz" % os.path.join(home, "themepack.tar.gz")) 39 | if ret <> 0: 40 | print ("Error downloading the themepack") 41 | return 1 42 | else: 43 | print ("Extracting themepack to '~/.pyjama/themes'") 44 | ret = os.system("tar -C %s -xf %s" % (home, os.path.join(home, "themepack.tar.gz"))) 45 | if ret <> 0: 46 | print ("Error extracting the themepack") 47 | return 2 48 | else: 49 | print ("All done") 50 | return 0 51 | 52 | -------------------------------------------------------------------------------- /plugins/README: -------------------------------------------------------------------------------- 1 | A short guide to plugins for pyjama 2 | +-----------------------------------+ 3 | 4 | Pyjama uses a new plugin system since version 0.1.29. 5 | This is a short guide how to do plugins for pyjama now. 6 | 7 | Requirements 8 | +------------+ 9 | 1) plugins have to be stored in pyjama's plugin folder 10 | 2) every plugin has its own folder there 11 | 3) each plugin needs a .info file in its folder 12 | 4) each plugin needs a file called "__init__.py" in its folder 13 | 14 | .info file 15 | +----------+ 16 | 1) this file has to have the same name as its folder 17 | 2) it holds: 18 | - "name" to store the plugin's full name 19 | - "version" to store the plugin's current version 20 | - "order" to influence in which order the plugins are loaded 21 | the higher this value is the later pyjama will load the plugin 22 | - "author" to store the author's name 23 | - "description" for a short description of the plugin 24 | - "copyright" for a short copyright line 25 | - "license" the plugin's license 26 | - "homepage" 27 | 28 | A proper .info file might look like this: 29 | 30 | Name = Example Plugin 123 31 | Order = 500 32 | Version = 0.17 33 | Author = Me 34 | Description = Just testing 35 | Copyright = By me 2009-FFFFFF 36 | License = GPLv3 37 | homepage = http://www.xn--ngel-5qa.de 38 | 39 | __init__.py 40 | +-----------+ 41 | * this file is needed to treat the while directory as a module 42 | * it needs to have a class called "main" 43 | * pyjama will pass a object holding all pyjama objects to this class 44 | 45 | Example 46 | +-------+ 47 | the directory scheme should be something like this: 48 | 49 | pyjama/ 50 | plugins/ 51 | my_plugin/ 52 | __init__.py 53 | my_plugin.info 54 | anotherplugin/ 55 | __init__.py 56 | anotherplugin.info 57 | 58 | !! Please have a look at pyjama's example plugin - it is quite simple !! 59 | -------------------------------------------------------------------------------- /usb-automount.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ksh 2 | # This file is part of burnstation2. 3 | 4 | # burnstation2 is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | 9 | # burnstation2 is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | 14 | # You should have received a copy of the GNU General Public License 15 | # along with burnstation2. If not, see . 16 | 17 | # (C) 2010 by Stefan Marsiske, 18 | 19 | # depends on pmount, dbus-monitor 20 | 21 | LABEL=burnstation 22 | MOUNTDIR=/media/$LABEL 23 | DEVICE=/tmp/mounted-usb 24 | 25 | #TODO improvement, do not mount the biggest but the partition with the most free space 26 | 27 | rm $DEVICE 28 | 29 | function add { 30 | read object 31 | object="${object##*/}" 32 | object="${object%\"}" 33 | [[ ${#object} -eq 3 ]] && { 34 | grep "${object}[0-9]" /proc/partitions | sed 's/ */ /g' | cut -d' ' -f4,5 | sort -rn | cut -d' ' -f2 | while read part; do 35 | echo "trying $part" 36 | pmount -s -t vfat -p /dev/null "/dev/$part" "$LABEL" 2>/dev/null && { 37 | echo "${part}" >"$DEVICE" 38 | echo ok 39 | return 40 | } 41 | done 42 | } 43 | } 44 | 45 | function remove { 46 | read object 47 | object="${object##*/}" 48 | object="${object%\"}" 49 | [[ ${#object} -eq "$(cat $DEVICE 2>/dev/null)" ]] && { 50 | rm "$DEVICE" 51 | } 52 | } 53 | 54 | dbus-monitor --system "type='signal',interface='org.freedesktop.UDisks'" | 55 | while read signal; do 56 | case "${signal}" in 57 | *member=DeviceAdded) add;; 58 | *member=DeviceRemoved) remove;; 59 | esac 60 | done 61 | -------------------------------------------------------------------------------- /modules/get_imagepack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | ## @package get_imagepack 21 | # This module just holds a function 22 | # to download and extract an image pack 23 | 24 | import os 25 | from time import time 26 | 27 | import functions 28 | 29 | # Gettext - Übersetzung 30 | functions.translation_gettext() 31 | #def _(string): 32 | # return string 33 | 34 | 35 | ## Download and extrackt images 36 | # @return: 37 | # - 0 = ok 38 | # - 1 = download error 39 | # - 2 = extraction error 40 | # 41 | def download_pack(): 42 | home=functions.preparedirs() 43 | print ("Downloading imagepack") 44 | ret = os.system("wget -cO %s xn--ngel-5qa.de/pyjama/release/imagepack.tar.gz" % os.path.join(home, "imagepack.tar.gz")) 45 | if ret <> 0: 46 | print ("Error downloading the imagepack") 47 | return 1 48 | else: 49 | print ("Extracting imagepack to '~/.pyjama/images'") 50 | ret = os.system("tar -C %s -xf %s" % (home, os.path.join(home, "imagepack.tar.gz"))) 51 | if ret <> 0: 52 | print ("Error extracting the imagepack") 53 | return 2 54 | else: 55 | print ("All done") 56 | return 0 57 | 58 | -------------------------------------------------------------------------------- /pyjama.cfg: -------------------------------------------------------------------------------- 1 | # This is Pyjama's configuration file 2 | # Please note: # and ; in any option at any place 3 | # will cause errors! Please don't even use those 4 | # signs to comment out values except you comment 5 | # out the whole line by using those chars as the 6 | # first sign in a line. 7 | 8 | [URLs] 9 | # Most probably you do not want to change this values 10 | # since they are essential for pyjama 11 | 12 | VERSION_URL = http://xn--ngel-5qa.de/pyjama_version 13 | # WHAT IS THE ALBUM URL 14 | ALBUM_URL = http://www.jamendo.com/en/album/URL 15 | 16 | [PATHs] 17 | # WHERE PYJAMA IS TO BE FOUND 18 | INSTALL_DIR_POSIX = /usr/share/apps/pyjama 19 | INSTALL_DIR = /usr/share/apps/pyjama 20 | 21 | [JAMENDO] 22 | # vars concerning interaction with jamendo 23 | 24 | # HOW OFTEN SHOULD VARIABLE INFORMATION BE RELOADED FROM JAMENDO IN SECONDS 25 | CACHING_TIME_SHORT = 172800 26 | # HOW OFTEN SHOULD CONSTANT INFORMATION BE RELOADED FROM JAMENDO IN SECONDS 27 | CACHING_TIME_LONG = 5184000 28 | # Which format should torrent-downloads have? 29 | FORMAT = mp32 30 | # Which format should streams have? 31 | format_stream = mp31 32 | 33 | [PYJAMA] 34 | # some options concerning user interaction 35 | # and skinning.. 36 | 37 | SHOW_TOOLBAR_TEXT = True 38 | FIRST_RUN = True 39 | # STANDARD PYJAMA GTK SCHEME 40 | STANDARD_THEME = None 41 | # SHOW WINDOW IN TASKBAR? 42 | SHOW_WINDOW_IN_TASKBAR = False 43 | # HOW LONG SHOULD NOTIFICATIONS BE SHOWN IN MS 44 | NOTIFICATION_DELAY = 5000 45 | # HOW BIG SHOULD COVERS IN NOTIFICATIONS BE? (PX) 46 | NOTIFICATION_COVER_SIZE = 75 47 | 48 | similar_albums = 5 49 | 50 | [PERFORMANCE] 51 | # most of this values have been found to be 52 | # the fastest on the most machines. 53 | 54 | # MAXIMUM SIMULTANEOUS THREAD DOWNLOADS 55 | MAX_THREADS = 50 56 | # HOW MANY SECONDS TO WAIT FOR THREADS 57 | THREAD_WAIT = 1 58 | # HOW MANY VIEWS SHOULD BE STORED IN HISTORY 59 | HISTORY_SIZE = 20 60 | # MAXIMUM # RESULTS FOR QUERIES 61 | DB_SEARCH_LIMIT = 100 62 | # EVERY WHAT SHOULD THE PLAYER BE CHECKED 63 | # SHOULD NOT BE CHANGED 64 | TIMER_INTERVAL = 1024 65 | # SET TO A LOWER VALUE IF TOOLTIPS SHOULD STUCK 66 | TOOLTIP_DELAY = 100 67 | 68 | [SOUND] 69 | # nothing usefull ;) 70 | 71 | # WHAT SOUND SHOULD BE SET ON START 72 | DEFAULT_VOL = 75 73 | # THE HIGHEST POSSIBLE VOLUME (0 to 1000) // > 100 MEANS DIGITAL AMPLIFICATION 74 | # 100 SHOULD BE MAXIMUM! 75 | VOL_MAX = 130 76 | 77 | [PLUGINS] 78 | # ADD BLACKLISTED PLUGINS HERE SEPERATED BY SPACE 79 | BLACKLIST = configtool mozplug webkit-plugin 80 | -------------------------------------------------------------------------------- /plugins/mozplug/mozplug.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | True 9 | 10 | 11 | True 12 | 13 | 14 | True 15 | gtk-go-back 16 | 17 | 18 | False 19 | 20 | 21 | 22 | 23 | True 24 | gtk-refresh 25 | 26 | 27 | False 28 | 29 | 30 | 31 | 32 | True 33 | gtk-go-forward 34 | 35 | 36 | False 37 | 38 | 39 | 40 | 41 | False 42 | 43 | 44 | 45 | 46 | True 47 | 48 | 49 | 1 50 | 51 | 52 | 53 | 54 | True 55 | 2 56 | 57 | 58 | False 59 | 2 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /modules/generate_changelog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import subprocess 4 | import sys 5 | 6 | try: 7 | pipe = subprocess.Popen("bzr log", shell=True, stdout=subprocess.PIPE) 8 | logfile = pipe.communicate()[0] 9 | except ValueError: 10 | print("Error with my Pipe") 11 | sys.exit(-1) 12 | 13 | revisions = logfile.split("------------------------------------------------------------") 14 | revisions.reverse() 15 | revisions = revisions[:-1] 16 | 17 | 18 | class REVISION: 19 | def __init__(self, rev): 20 | self.revision=None 21 | self.comitter=None 22 | self.branch=None 23 | self.timestamp=None 24 | self.message=None 25 | 26 | lines = rev.split("\n")[1:] 27 | self.revision = lines[0].strip().replace("revno: ", "") 28 | self.comitter = lines[1] 29 | self.branch = lines[2] 30 | self.timestamp = lines[3] 31 | self.message="\n".join(lines[4:]).strip() 32 | 33 | def __str__(self): 34 | ret = """revision: %s 35 | committer: %s 36 | branch: %s 37 | timestamp: %s 38 | message: %s 39 | """ % (self.revision, self.comitter, self.branch, self.timestamp, self.message) 40 | return ret 41 | 42 | revlist = [] 43 | for rev in revisions: 44 | r = REVISION(rev) 45 | revlist.append(r) 46 | 47 | def get_revision(rev): 48 | return revisions[rev-1] 49 | 50 | def get_revisions(fromrev, torev): 51 | return revisions[fromrev-1: torev] 52 | 53 | 54 | #while 1: 55 | # print(60*"*") 56 | # print("Got %i revisions" % len(revlist)) 57 | # print("Lates revision: %s" % revlist[len(revlist)-1].revision) 58 | # print("") 59 | # print("What do you want to do?") 60 | # print("""NUM = Show that revision 61 | #RANGE (1-10) = Print those revisions 62 | #EXIT = Exit 63 | # """) 64 | # ret = raw_input("Your Choice: ") 65 | # print(60*"*") 66 | 67 | # if "-" in ret: 68 | # try: 69 | # fr, to = ret.split("-") 70 | # for r in revlist: 71 | # if (r.revision) >= (fr) and (r.revision) <= (to): 72 | # print r 73 | # except OSError: 74 | # print("That was no valid range") 75 | # elif ret.lower() == "exit": 76 | # sys.exit() 77 | # elif ret.isdigit(): 78 | # print 30*"=" 79 | # found = False 80 | # for rev in revlist: 81 | # if rev.revision == str(ret): 82 | # found = True 83 | # print rev 84 | # if not found: 85 | # print("The revision %s was not found" % ret) 86 | # print 30*"=" 87 | -------------------------------------------------------------------------------- /images/info.txt: -------------------------------------------------------------------------------- 1 | Source of images used by Pyjama: 2 | 3 | | Images | Source / Author | License | 4 | +-------------------------+---------------------------------+------------------------+ 5 | | money.png | | | 6 | | cd.png | Ubuntu's human theme | GPL | 7 | +-------------------------+---------------------------------+------------------------+ 8 | | juk.png | | | 9 | | kdmconfig.png | | | 10 | | personal.png | Tulliana icon theme | GPL | 11 | +-------------------------+---------------------------------+------------------------+ 12 | | pyjama_new.png | Spayder 26 | CC BY-SA-NC 3.0 | 13 | +-------------------------+---------------------------------+------------------------+ 14 | | folder_06.png | | | 15 | | clip_note_1.png | | | 16 | | green_beetle.png | | | 17 | | blue_grey_tag_T.png | | | 18 | | calendar.png | | | 19 | | radio.png | | | 20 | | spread-torrent.png | | | 21 | | cd.png | wpclipart.com | Public domain | 22 | +-------------------------+---------------------------------+------------------------+ 23 | | playlist.png | | | 24 | | plugin??.png | | | 25 | | suffle.png | myself | GPL | 26 | +-------------------------+---------------------------------+------------------------+ 27 | | license_images | creativecommons.com | CC?? | 28 | +-------------------------+---------------------------------+------------------------+ 29 | | preferences_plugin.png | iconlook.com / Oxygen-Icons | LGPL | 30 | | view-media-equalizer.png| iconlook.com | LGPL | 31 | +-------------------------+---------------------------------+------------------------+| 32 | -------------------------------------------------------------------------------- /images/info.txt~: -------------------------------------------------------------------------------- 1 | Source of images used by Pyjama: 2 | 3 | | Images | Source / Author | License | 4 | +-------------------------+---------------------------------+------------------------+ 5 | | money.png | | | 6 | | cd.png | Ubuntu's human theme | GPL | 7 | +-------------------------+---------------------------------+------------------------+ 8 | | juk.png | | | 9 | | kdmconfig.png | | | 10 | | personal.png | Tulliana icon theme | GPL | 11 | +-------------------------+---------------------------------+------------------------+ 12 | | pyjama_new.png | Spayder 26 | CC BY-SA-NC 3.0 | 13 | +-------------------------+---------------------------------+------------------------+ 14 | | folder_06.png | | | 15 | | clip_note_1.png | | | 16 | | green_beetle.png | | | 17 | | blue_grey_tag_T.png | | | 18 | | calendar.png | | | 19 | | radio.png | | | 20 | | spread-torrent.png | | | 21 | | cd.png | wpclipart.com | Public domain | 22 | +-------------------------+---------------------------------+------------------------+ 23 | | playlist.png | | | 24 | | plugin??.png | | | 25 | | suffle.png | myself | GPL | 26 | +-------------------------+---------------------------------+------------------------+ 27 | | license_images | creativecommons.com | CC?? | 28 | +-------------------------+---------------------------------+------------------------+ 29 | | preferences_plugin.png | iconlook.com / Oxygen-Icons | LGPL | 30 | | view-media-equalizer.png| iconlook.com | LGPL | 31 | +-------------------------+---------------------------------+------------------------+| 32 | -------------------------------------------------------------------------------- /plugins/torrent-peer/pytorrent/client.py: -------------------------------------------------------------------------------- 1 | from daemon import Daemon 2 | from connection import TransmissionConnection, Command, TorrentGetCommand, TorrentGetListCommand 3 | from torrent import Torrent 4 | import base64 5 | import urllib2 6 | 7 | def session_property(key): 8 | return property(lambda x: x._session.get(key)) 9 | 10 | class TorrentClient(object): 11 | def __init__(self, hostname=None, port=9090): 12 | self.daemon = None 13 | if not hostname: 14 | self.daemon = Daemon(["transmission-daemon", "-f", "-p", str(port)]) 15 | self.daemon.start() 16 | hostname = "localhost" 17 | self._connection = TransmissionConnection(hostname, port) 18 | self._session = self._connection.execute(Command("session-get")) 19 | 20 | def __del__(self): 21 | if self.daemon: 22 | self.daemon.stop() 23 | 24 | def add_torrent(self, auto=None, metadata=None, filename=None, file=None, url=None): 25 | if auto: 26 | if isinstance(auto, str): 27 | if "://" in auto: 28 | data = urllib2.urlopen(auto).read() 29 | else: 30 | data = open(auto, "r").read() 31 | elif hasattr(auto, "read"): 32 | data = auto.read() 33 | elif hasattr(auto, "content"): 34 | data = auto.content 35 | else: 36 | raise AttributeError() 37 | else: 38 | if metadata: 39 | data = metadata 40 | elif filename: 41 | data = open(filename, "r").read() 42 | elif url: 43 | data = urllib2.urlopen(url).read() 44 | elif file: 45 | data = file.read() 46 | 47 | data = base64.encodestring(data) 48 | 49 | command = Command("torrent-add") 50 | command["metainfo"] = data 51 | command["paused"] = True 52 | 53 | torrent = self._connection.execute(command) 54 | return self.get_torrent(torrent["torrent-added"]["id"]) 55 | 56 | def get_torrent(self, id): 57 | command = TorrentGetCommand(Torrent.static_fields, id) 58 | torrent = self._connection.execute(command) 59 | return Torrent(self, torrent) 60 | 61 | def _get_torrents(self): 62 | command = TorrentGetListCommand(Torrent.static_fields) 63 | list = self._connection.execute(command) 64 | torrent_list = map(lambda t: Torrent(self, t), list) 65 | return torrent_list 66 | 67 | download_dir = session_property("download-dir") 68 | torrents = property(_get_torrents) 69 | -------------------------------------------------------------------------------- /plugins/torrent-peer/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # ---------------------------------------------------------------------------- 20 | 21 | from pytorrent import TorrentClient 22 | from pytorrent.connection import TransmissionException 23 | 24 | import time 25 | import sys 26 | import os 27 | 28 | 29 | class main(): 30 | def __init__(self, pyjama): 31 | pass 32 | 33 | 34 | 35 | #torrent_file = "./torrent" 36 | #if not os.path.exists(torrent_file): 37 | # print "Nicht vorhanden" 38 | # sys.exit(1) 39 | # 40 | ## spawn a transmission daemon 41 | try: 42 | client = TorrentClient() 43 | except: 44 | print(60*"#") 45 | print("You need to have the transmission torrent daemon installed") 46 | print("Look out for the package 'transmission-cli' or 'transmission'") 47 | print(60*"#") 48 | raise 49 | # 50 | ## add our torrent file and start it 51 | #try: 52 | # torrent = client.add_torrent(torrent_file) 53 | # for i, file in enumerate(torrent.files): 54 | # if i != 1: 55 | # file.wanted = False 56 | # else: 57 | # print "\t"+str(i)+")", file.name+":", file.size, "Bytes" 58 | # torrent.start() 59 | #except TransmissionException: 60 | # print "Torrent already in queue" 61 | # for t in client.torrents: 62 | # for i, file in enumerate(t.files): 63 | # if i == 1: 64 | # file.wanted = True 65 | # torrent = t 66 | ## print some initial information 67 | #print "Downloading:", torrent.name 68 | 69 | ## as long as the torrent is not finished print out some download status 70 | #while not torrent.finished: 71 | # sizes = str(torrent.downloaded_size)+"/"+str(torrent.size) 72 | # print sizes, "Bytes", "@", torrent.download_rate, "B/s" 73 | # time.sleep(1) 74 | ## thats it. the file has been downloaded 75 | #print "file download finished." 76 | -------------------------------------------------------------------------------- /extended_modules/bookmarks.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 5 7 | GTK_WIN_POS_CENTER_ON_PARENT 8 | 300 9 | 200 10 | True 11 | GDK_WINDOW_TYPE_HINT_DIALOG 12 | True 13 | True 14 | 15 | 16 | True 17 | 2 18 | 19 | 20 | True 21 | True 22 | GTK_POLICY_AUTOMATIC 23 | GTK_POLICY_AUTOMATIC 24 | 25 | 26 | True 27 | True 28 | False 29 | False 30 | 31 | 32 | 33 | 34 | 1 35 | 36 | 37 | 38 | 39 | True 40 | GTK_BUTTONBOX_END 41 | 42 | 43 | True 44 | True 45 | True 46 | ok 47 | 0 48 | 49 | 50 | 51 | 52 | False 53 | GTK_PACK_END 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /modules/clBrowserInterface.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | ## @package clBrowserInterface 21 | # Manages pyjama's browser interface 22 | 23 | # 24 | # You are probably looking for the integrated webbrowser or PMC 25 | # have a look at mozplug-plugin in the first case or pmc in 26 | # the second one! 27 | # This file only manages urls and opens them in your default 28 | # browser or mozplug 29 | # 30 | 31 | import webbrowser 32 | 33 | ## Browser Interface class 34 | class Browser(): 35 | ## Constructor 36 | # @param self Object Pointer 37 | # @param pyjama Pyjama Reference 38 | def __init__(self, pyjama): 39 | ## Pyjama Reference 40 | self.pyjama = pyjama 41 | self.pyjama.Events.add_event("open_url") 42 | self.pyjama.Events.connect_event("open_url", self.ev_open_url) 43 | ## The current Browser to be used 44 | self.browser = self.webbrowser # user's default browser 45 | 46 | ## Set a new browser 47 | # @param self Object Pointer 48 | # @param function_to_call Function to when a browser is opend 49 | def set_browser(self, function_to_call): 50 | self.browser = function_to_call 51 | 52 | ## Set the browser to be used to default 53 | # @param self Object Pointer 54 | def set_default_browser(self): 55 | self.browser = self.webbrowser 56 | 57 | ## called when then "open_url" event is raised 58 | # @param self Object Pointer 59 | # @param url The url that has been passed to the "open_url" event 60 | # @param force_default When set to True, the url is opened in the default browser 61 | # default value is False 62 | def ev_open_url(self, url, force_default=False): 63 | if force_default: 64 | self.webbrowser(url) 65 | else: 66 | self.browser(url) 67 | 68 | ################################################################### 69 | # 70 | # Open a given URL in the standard webbrowser 71 | # RETURNS: ? 72 | # 73 | ## The default webbrowser 74 | # @param self Object Pointer 75 | # @param url The URL to open 76 | def webbrowser(self, url): 77 | return webbrowser.open_new_tab(url) # mod_webbrowser is the module webbrowser // some naming issues :) 78 | -------------------------------------------------------------------------------- /plugins/mmhotkeys/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2009 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | 21 | # This script was inspired by Chris Brown's gnome-media-keys script for amarok 22 | 23 | import gobject 24 | import os, sys 25 | 26 | try: 27 | import dbus 28 | from dbus import glib 29 | except Exception, inst: 30 | print "python-dbus and libdbus-glib needed for mmhotkeys" 31 | raise 32 | 33 | # 34 | # Checks 35 | # 36 | 37 | # Check if Gnome Settings Daemon is running: 38 | ret = os.popen("ps -C gnome-settings-daemon|grep settings").read() 39 | if ret == "": 40 | print "gnome-settings-daemon not running" 41 | raise(ImportError, "gnome-settings-daemon not running") 42 | 43 | # Gnome Version for dbus selection 44 | VERSION = os.popen('LANG=C gnome-about --gnome-version|grep Version|cut -d \" \" -f 2').read() 45 | if VERSION == "": VERSION = "2.18" 46 | 47 | class main(): 48 | def __init__(self, pyjama): 49 | self.pyjama = pyjama 50 | 51 | bus = dbus.SessionBus() 52 | # Connect to signal: 53 | if VERSION > "2.20": 54 | try: 55 | object = bus.get_object("org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys") 56 | object.connect_to_signal("MediaPlayerKeyPressed", self.ev_key_pressed, dbus_interface='org.gnome.SettingsDaemon.MediaKeys') 57 | except: 58 | print "Error connecting to SettingsDaemon." 59 | raise 60 | else: 61 | try: 62 | object = bus.get_object("org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon") 63 | object.connect_to_signal("MediaPlayerKeyPressed", self.ev_key_pressed, dbus_interface="org.gnome.SettingsDaemon") 64 | except: 65 | print "Error connecting to SettingsDaemon." 66 | raise 67 | 68 | def ev_key_pressed(self, *keys): 69 | for key in keys: 70 | if key == "Play": 71 | self.pyjama.window.on_bPlay_clicked(None) 72 | elif key == "Pause": 73 | self.pyjama.window.on_bPlay_clicked(None) 74 | elif key == "Stop": 75 | self.pyjama.window.on_bStop_clicked(None) 76 | elif key == "Next": 77 | self.pyjama.window.on_bNext_clicked(None) 78 | elif key == "Previous": 79 | self.pyjama.window.on_bPrev_clicked(None) 80 | 81 | 82 | -------------------------------------------------------------------------------- /plugins/jam_query/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import gtk, gobject 21 | from threading import Thread 22 | from time import sleep 23 | 24 | class main(): 25 | def __init__(self, pyjama): 26 | self.__pyjama = pyjama 27 | 28 | self.dialo = gtk.MessageDialog(self.__pyjama.window, 0, gtk.MESSAGE_INFO, 0, _("Jamendo is being queried")) 29 | 30 | self.dialog = gtk.Dialog() 31 | self.dialog.set_modal(True) 32 | self.dialog.set_title("Querying Jamendo") 33 | label = gtk.Label("If this query wan't cached, yet, it will be cached now.\nPlease notice that I cannot influence jamendo's response time") 34 | label.set_justify(gtk.JUSTIFY_CENTER) 35 | self.dialog.vbox.pack_start(label, False, True) 36 | label.show() 37 | 38 | 39 | self.__pyjama.Events.connect_event("jamendo-query", self.ev_jamendo_query) 40 | # self.__pyjama.Events.connect_event("alldone", self.ev_alldone) 41 | 42 | # self.running = False 43 | 44 | # self.statusbar = gtk.Statusbar() 45 | # self.statusbar.set_has_resize_grip(True) 46 | # self.statusbar.push(self.statusbar.get_context_id("Status"), _("Querying Jamendo")) 47 | 48 | # self.progressbar = gtk.ProgressBar() 49 | # self.progressbar.set_pulse_step(0.1) 50 | # self.progressbar.show() 51 | # self.statusbar.add(self.progressbar) 52 | 53 | 54 | # def ev_alldone(self): 55 | # self.__pyjama.window.vbox.pack_end(self.statusbar, False, True, 0) 56 | 57 | def ev_jamendo_query(self, status): 58 | if status == "start": 59 | self.dialog.show() 60 | self.dialog.present() 61 | # self.running = True 62 | # gobject.timeout_add(2, self.cb_pulse_bar) 63 | # thr = Thread(target = self.cb_pulse_bar, args = ()) 64 | # thr.start() 65 | # self.statusbar.show() 66 | self.__pyjama.window.do_events() 67 | #~ self.__pyjama.x.start() 68 | #~ self.__pyjama.window.do_events() 69 | elif status == "end": 70 | self.dialog.hide() 71 | #~ self.__pyjama.x.stop() 72 | #~ self.__pyjama.window.do_events() 73 | # self.statusbar.hide() 74 | # self.running = False 75 | 76 | 77 | # def cb_pulse_bar(self): 78 | # i = 0 79 | # while self.running: 80 | # i += 1 81 | # self.progressbar.pulse() 82 | # self.__pyjama.window.do_events() 83 | # sleep (0.01) 84 | ## print ("as") 85 | # #return self.running 86 | # print i 87 | 88 | -------------------------------------------------------------------------------- /plugins/nowplaying/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import gtk 21 | import os 22 | 23 | class main(): 24 | def __init__(self, pyjama): 25 | self.pyjama = pyjama 26 | ev = self.pyjama.Events 27 | # ev.nowplaying += self.notification 28 | ev.connect_event("nowplaying", self.notification) 29 | 30 | self.pyjama.preferences.register_plugin("Nowplaying", self.register_preferences, self.save_preferences) 31 | 32 | # def notification(self, artist, album, track, icon, size = None): 33 | def notification(self, track): 34 | icon = self.pyjama.get_album_image(track.album_id) 35 | size = self.pyjama.settings.get_value("PYJAMA", 'notification_cover_size') 36 | 37 | artist = track.artist_name 38 | album = track.album_name 39 | track = track.name 40 | 41 | # if "listenstats" in self.pyjama.plugins.loaded: 42 | # print "listenstats" 43 | 44 | self.pyjama.icon.show_notification(caption =_("Now playing"), text = "%s:\n%s" % (artist, track), img = icon, size = size) 45 | 46 | # 47 | # Script 48 | # 49 | script = self.pyjama.settings.get_value("NOWPLAYING", 'EXECUTE', "") 50 | if script != "": 51 | try: 52 | os.system("%s \"%s\" \"%s\" \"%s\"" % (script, artist.replace("\"", "\\\""), album.replace("\"", "\\\""), track.replace("\"", "\\\""))) 53 | # print("nowplaying: %s executed" % script) 54 | except: 55 | print ("An error occured while executing %s" % script) 56 | 57 | def register_preferences(self): 58 | script = self.pyjama.settings.get_value("NOWPLAYING", 'EXECUTE', "") 59 | vbox = gtk.VBox() 60 | 61 | hbox = gtk.HBox() 62 | self.entry = gtk.Entry() 63 | self.entry.set_text(script) 64 | self.entry.show() 65 | lbl = gtk.Label("Script to execute") 66 | lbl.show() 67 | tt = """Pyjama will execute this script any time a new song is played and pass some song infos to it. 68 | Please make that script executable or enter a command like sh /home/USER/my_script.sh. 69 | 70 | Pyjama will pass the artist as first, the album as second and the track as third param to the script. 71 | """ 72 | lbl.set_tooltip_markup(tt) 73 | self.entry.set_tooltip_markup(tt) 74 | 75 | hbox.pack_start(lbl, False, True, 10) 76 | hbox.pack_end(self.entry, True, True, 10) 77 | 78 | vbox.pack_start(hbox, False, True, 10) 79 | 80 | vbox.show_all() 81 | return vbox 82 | 83 | def save_preferences(self): 84 | self.pyjama.settings.set_value("NOWPLAYING", 'EXECUTE', self.entry.get_text(), str) 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /plugins/torrent-peer/pytorrent/connection.py: -------------------------------------------------------------------------------- 1 | import httplib 2 | import simplejson 3 | import time 4 | import exceptions 5 | import socket 6 | 7 | class TransmissionException(exceptions.Exception): 8 | def __init__(self, command, error): 9 | self.command = command or "" 10 | self.error = error or "" 11 | 12 | def __str__(self): 13 | return self.command+" failed: "+self.error 14 | 15 | class TransmissionConnection: 16 | def __init__(self, host, port): 17 | self._host = host 18 | self._port = port 19 | self._httpconn = None 20 | self._connect() 21 | 22 | def _connect(self): 23 | for i in range(0, 10): 24 | try: 25 | self._httpconn = httplib.HTTPConnection(self._host, self._port) 26 | self._httpconn.connect() 27 | return 28 | except: 29 | time.sleep(0.5) 30 | 31 | def execute(self, command): 32 | try: 33 | command_str = str(command) 34 | self._httpconn.request("POST", "/transmission/rpc", command_str) 35 | response = self._httpconn.getresponse() 36 | result_str = response.read() 37 | result = simplejson.loads(result_str) 38 | if result["result"] != "success": 39 | raise TransmissionException(command.method, result["result"]) 40 | else: 41 | return command.extract_result(result) 42 | except socket.error: 43 | self._connect() 44 | return self.execute(command) 45 | 46 | 47 | class Command: 48 | def __init__(self, method): 49 | self.method = method 50 | self.arguments = {} 51 | 52 | def extract_result(self, data): 53 | return data["arguments"] 54 | 55 | def __str__(self): 56 | map = {} 57 | map["method"] = self.method 58 | map["arguments"] = self.arguments 59 | return simplejson.dumps(map) 60 | 61 | def __setitem__(self, k, v): 62 | self.arguments[k] = v 63 | 64 | def __getitem__(self, k): 65 | return self.arguments[k] 66 | 67 | class TorrentCommand(Command): 68 | def __init__(self, method, ids=None): 69 | Command.__init__(self, method) 70 | if ids and not isinstance(ids, list): 71 | ids = [ids] 72 | self.ids = ids 73 | 74 | def __str__(self): 75 | if self.ids: 76 | self.arguments["ids"] = self.ids 77 | return Command.__str__(self) 78 | 79 | class TorrentGetListCommand(TorrentCommand): 80 | def __init__(self, fields=[], ids=None): 81 | TorrentCommand.__init__(self, "torrent-get", ids) 82 | 83 | if not isinstance(fields, list): 84 | fields = [fields] 85 | self.fields = fields 86 | 87 | def extract_result(self, data): 88 | return data["arguments"]["torrents"] 89 | 90 | def __str__(self): 91 | self.arguments["fields"] = self.fields 92 | return TorrentCommand.__str__(self) 93 | 94 | class TorrentGetCommand(TorrentGetListCommand): 95 | def extract_result(self, data): 96 | return data["arguments"]["torrents"][0] 97 | 98 | class TorrentGetFileCommand(TorrentGetListCommand): 99 | def __init__(self, torrent_id, file_id): 100 | TorrentGetListCommand.__init__(self, "files", torrent_id) 101 | self.file_id = file_id 102 | 103 | def extract_result(self, data): 104 | return data["arguments"]["torrents"][0]["files"][self.file_id] 105 | -------------------------------------------------------------------------------- /plugins/imagepack/imagepack.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 5 7 | False 8 | center 9 | 300 10 | 200 11 | True 12 | dialog 13 | False 14 | False 15 | 16 | 17 | True 18 | vertical 19 | 2 20 | 21 | 22 | True 23 | label 24 | 25 | 26 | 10 27 | 1 28 | 29 | 30 | 31 | 32 | True 33 | 34 | 35 | False 36 | 10 37 | 2 38 | 39 | 40 | 41 | 42 | True 43 | end 44 | 45 | 46 | gtk-cancel 47 | True 48 | True 49 | True 50 | True 51 | 52 | 53 | False 54 | False 55 | 0 56 | 57 | 58 | 59 | 60 | gtk-ok 61 | True 62 | True 63 | True 64 | True 65 | 66 | 67 | False 68 | False 69 | 1 70 | 71 | 72 | 73 | 74 | False 75 | end 76 | 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /plugins/example/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ## @package ExamplePlugin 4 | # Example Plugin Module. 5 | # Every single plugin needs to come as a module in a directory. 6 | # Every folder containing a file named "FOLDERNAME.info" 7 | # will be recogniced as a plugin. 8 | # Furthermore the folder needs to contain a file "__init__.py" 9 | # which holds a class named "main". 10 | # When loading a plugin pyjama will pass the object "pyjama" 11 | # which holds all the other objects. 12 | # 13 | # For more informations have a look at the plugin interface. 14 | 15 | try: 16 | import gtk 17 | except: 18 | print "Error: Gtk not found" 19 | raise 20 | 21 | ## Example Plugin class main called by Pyjama 22 | class main(): 23 | ## The Constructor 24 | # @param self Object pointer 25 | # @param pyjama Reference to the pyjama object 26 | def __init__(self, pyjama): 27 | ## Here we store the pyjama object reference 28 | self.pyjama = pyjama 29 | 30 | # Let's register a preferences page: 31 | self.pyjama.preferences.register_plugin("Example", self.create_preferences, self.save_preferences) 32 | 33 | ## You cannot directly access the plugins 34 | # object of pyjama in your init function 35 | # since it is created after all plugins 36 | # have been initialised. 37 | # Following line will fail:\n 38 | # plugins = self.pyjama.plugins <-- ERROR\n 39 | # Connect to the "alldone" event, if you 40 | # want pyjama to call your plugin after 41 | # everythin else is done! 42 | self.Events = self.pyjama.Events 43 | self.Events.connect_event("alldone", self.ev_alldone) 44 | 45 | 46 | 47 | ## This function will be called after pyjama 48 | # has been loaded and you have connected to 49 | # the "alldone" event 50 | # Now you can access any other plugins... 51 | def ev_alldone(self): 52 | if "nowplaying" in self.pyjama.plugins.loaded: 53 | # print "Plugin 'nowplaying' can be found!' 54 | pass 55 | 56 | ## This function creates a vbox, 57 | # puts some widgets on it and returns 58 | # it. 59 | # @param self Object Pointer 60 | def create_preferences(self): 61 | # get some infos about the plugin 62 | plugin_infos = self.pyjama.plugins.plugins_by_name["example"] 63 | txt = "This is an exmaple preferences dialog\nor at least could be one.\nI can tell you something about me:\n\nAuthor: %s\nName: %s\nDescription: %s" % (plugin_infos['author'], plugin_infos['name'], plugin_infos['description']) 64 | 65 | # 66 | # Create the vbox and some widgets 67 | # 68 | vbox = gtk.VBox() 69 | 70 | lbl = gtk.Label() 71 | lbl.set_markup(txt) 72 | 73 | # as I need to access the entry widget 74 | # when the values needs to be saved, 75 | # i connect it to the class-object 76 | self.entry = gtk.Entry() 77 | self.entry.set_text("I am the default text") 78 | 79 | vbox.pack_start(lbl, False, True, 10) 80 | vbox.pack_start(self.entry, False, False, 10) 81 | 82 | vbox.show_all() 83 | return vbox 84 | 85 | ## Will be called when the user closed 86 | # the preferences dialog with "ok" and 87 | # when this plugin's vbox was shown before. 88 | # @param self Object Pointer 89 | def save_preferences(self): 90 | print("'%s' was entered into the entry-widget" % self.entry.get_text()) 91 | 92 | # We could now also save this value: 93 | #self.pyjama.settings.set_value("EXAMPLE_PLUGIN", "entry_value", self.entry.get_text()) 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /modules/clDownloader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import pycurl 5 | import functions 6 | import time 7 | import os 8 | import threading 9 | import copy 10 | import magic 11 | 12 | class Downloader(threading.Thread): 13 | def __init__(self, pyjama): 14 | threading.Thread.__init__(self) 15 | self.pyjama = pyjama 16 | self.queue = [] 17 | self.running = False 18 | self.retries = {} 19 | 20 | def run(self): 21 | self.running = True 22 | while(self.running): 23 | if not self.is_queue_empty(): 24 | self.download(self.queue_shift()) 25 | time.sleep(3) 26 | 27 | def quit(self): 28 | self.running = False 29 | 30 | def is_queue_empty(self): 31 | if len(self.queue) == 0: 32 | return True 33 | else: 34 | return False 35 | 36 | def queue_shift(self): 37 | tmp = self.queue[0] 38 | del self.queue[0] 39 | return tmp 40 | 41 | def queue_push(self, track): 42 | if not os.path.isfile(self.get_local_name(track)) and track not in self.queue: 43 | self.queue.append(track) 44 | 45 | def priorize_burn(self, tracks): 46 | pl = [] 47 | for track in tracks: 48 | if track.local != None: 49 | if track in self.queue: 50 | del self.queue[self.queue.index(track)] 51 | pl.append(track) 52 | self.queue = pl + self.queue 53 | 54 | def get_local_name(self, track): 55 | tmp = os.path.join(functions.install_dir(), "cache") 56 | tmp = os.path.join(tmp, str(track.artist_id)) 57 | tmp = os.path.join(tmp, str(track.album_id)) 58 | return os.path.join(tmp, str(track.id)) + '.mp3' 59 | 60 | def download(self, track): 61 | uri = track.stream #.replace('mp31', 'mp32') 62 | if uri in self.retries: 63 | if self.retries[uri]>9: 64 | return 65 | time.sleep(self.retries[uri]**2) 66 | tmp = os.path.join(functions.install_dir(), "cache") 67 | if not os.path.isdir(tmp): 68 | os.mkdir(tmp) 69 | if not os.path.isdir(os.path.join(tmp, str(track.artist_id))): 70 | os.mkdir(os.path.join(tmp, str(track.artist_id))) 71 | tmp = os.path.join(tmp, str(track.artist_id)) 72 | if not os.path.isdir(os.path.join(tmp, str(track.album_id))): 73 | os.mkdir(os.path.join(tmp, str(track.album_id))) 74 | tmp = os.path.join(tmp, str(track.album_id)) 75 | target = os.path.join(tmp, str(track.id)) + '.mp3' 76 | #print "[!] downloading %s to %s" % (uri, target) 77 | cmd='(wget -c -O %s.part -q "%s" && mv %s.part %s)' % (target, uri, target, target) 78 | #print "[!] command:", cmd 79 | os.system(cmd) 80 | mp3 = magic.open(magic.MAGIC_NONE) 81 | mp3.load() 82 | type = mp3.file(target) 83 | print uri 84 | print 'file type',type 85 | if type[:4] == 'MPEG' or type[:5] == 'Audio': 86 | track.local = target 87 | else: 88 | os.unlink(target) 89 | self.retries[uri]=self.retries.get(uri,0)+1 90 | print "[!] failed to download %s, putting back in queue (retry:%d)" % (target,self.retries[uri]) 91 | self.queue_push(track) 92 | 93 | def get_status(self): 94 | tmp = [] 95 | for track in self.pyjama.player.playlist: 96 | if track in self.queue: 97 | tmp.append((track, 'Q')) 98 | elif track.stream in self.retries: 99 | tmp.append((track, 'F')) 100 | else: 101 | tmp.append((track, 'D')) 102 | return tmp 103 | -------------------------------------------------------------------------------- /plugins/PVC/progressdialog.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 5 7 | True 8 | GTK_WIN_POS_CENTER_ON_PARENT 9 | GDK_WINDOW_TYPE_HINT_DIALOG 10 | 11 | 12 | True 13 | 2 14 | 15 | 16 | True 17 | 18 | 19 | 20 | 21 | 22 | True 23 | 24 | 25 | True 26 | 27 | 28 | 29 | 30 | 0 31 | True 32 | Downloading lates 33 | version of Pyjama 34 | True 35 | 36 | 37 | False 38 | False 39 | 7 40 | 1 41 | 42 | 43 | 44 | 45 | False 46 | 5 47 | 1 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 2 56 | 57 | 58 | 59 | 60 | True 61 | GTK_BUTTONBOX_END 62 | 63 | 64 | 65 | 66 | 67 | True 68 | True 69 | True 70 | gtk-cancel 71 | True 72 | 0 73 | 74 | 75 | 1 76 | 77 | 78 | 79 | 80 | False 81 | GTK_PACK_END 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /modules/clEntry.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import sys 21 | import getopt 22 | import gtk 23 | 24 | ################################################################### 25 | # 26 | # an entry dialog - taken from: 27 | # http://www.rexx.com/~dkuhlman/python_201/python_201.html#SECTION008220000000000000000 28 | # 29 | class EntryDialog( gtk.Dialog): 30 | def __init__(self, message="", default_text='', modal= True): 31 | gtk.Dialog.__init__(self) 32 | self.connect("destroy", self.quit) 33 | self.connect("delete_event", self.quit) 34 | if modal: 35 | self.set_modal(True) 36 | box = gtk.VBox(spacing=10) 37 | box.set_border_width(10) 38 | self.vbox.pack_start(box) 39 | box.show() 40 | if message: 41 | label = gtk.Label(message) 42 | box.pack_start(label) 43 | label.show() 44 | self.entry = gtk.Entry() 45 | self.entry.set_text(default_text) 46 | self.entry.connect("activate", self.click) 47 | box.pack_start(self.entry) 48 | self.entry.show() 49 | self.entry.grab_focus() 50 | button = gtk.Button("OK") 51 | button.connect("clicked", self.click) 52 | button.set_flags(gtk.CAN_DEFAULT) 53 | self.action_area.pack_start(button) 54 | button.show() 55 | button.grab_default() 56 | button = gtk.Button("Cancel") 57 | button.connect("clicked", self.quit) 58 | button.set_flags(gtk.CAN_DEFAULT) 59 | self.action_area.pack_start(button) 60 | button.show() 61 | self.ret = None 62 | def quit(self, w=None, event=None): 63 | self.hide() 64 | self.destroy() 65 | gtk.main_quit() 66 | def click(self, button): 67 | self.ret = self.entry.get_text() 68 | self.quit() 69 | 70 | def input_box(title="Input Box", message="", default_text='', 71 | modal= True): 72 | win = EntryDialog(message, default_text, modal=modal) 73 | win.set_title(title) 74 | win.show() 75 | gtk.main() 76 | return win.ret 77 | 78 | def test(): 79 | result = input_box(title='Test #2', 80 | message='Enter a valuexxx:', 81 | default_text='a default value') 82 | if result is None: 83 | print 'Canceled' 84 | else: 85 | print 'result: "%s"' % result 86 | 87 | USAGE_TEXT = """ 88 | Usage: 89 | python simple_dialog.py [options] 90 | Options: 91 | -h, --help Display this help message. 92 | Example: 93 | python simple_dialog.py 94 | """ 95 | 96 | def usage(): 97 | print USAGE_TEXT 98 | sys.exit(-1) 99 | 100 | def main(): 101 | args = sys.argv[1:] 102 | try: 103 | opts, args = getopt.getopt(args, 'h', ['help']) 104 | except: 105 | usage() 106 | relink = 1 107 | for opt, val in opts: 108 | if opt in ('-h', '--help'): 109 | usage() 110 | if len(args) != 0: 111 | usage() 112 | test() 113 | 114 | if __name__ == '__main__': 115 | main() 116 | #import pdb 117 | #pdb.run('main()') 118 | 119 | -------------------------------------------------------------------------------- /about.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 7 | 5 8 | About Pyjama 9 | False 10 | GTK_WIN_POS_CENTER_ON_PARENT 11 | GDK_WINDOW_TYPE_HINT_DIALOG 12 | False 13 | Pyjama 14 | 0.3.0.78 15 | 2008-2009 by Daniel Nögel 16 | http://xn--ngel-5qa.de/pyjama 17 | Pyjama's Homepage 18 | Pyjama: Python Jamendo Mediacenter 19 | Copyright (C) 2009 Daniel Nögel 20 | 21 | This program is free software: you can redistribute it and/or modify 22 | it under the terms of the GNU General Public License as published by 23 | the Free Software Foundation, version 3 of the License. 24 | 25 | This program is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU General Public License for more details. 29 | 30 | You should have received a copy of the GNU General Public License 31 | along with this program. If not, see <http://www.gnu.org/licenses/>. 32 | Daniel Nögel 33 | Andres Jalinton, Javier Navarro, Manuel Alejandro Jiménez Quintero, Miguel Anxo Bouzada, Manuel Fernandez Sampere (spanish) 34 | Giasone, Guybrush88, Giuseppe Terrasi, Cecco (italian) 35 | Pierre Rudloff, remed, Mathieu Pasquet, OrelEagle, Quentin Theuret, Baptiste Dartheny (french) 36 | Funatiker (german) 37 | Sebastian Kalinowski (polish) 38 | Yasen Pramatarov, Borislav Manolov(bulgarian) 39 | Jordi Puiggené, animarval (catalan) 40 | Jimmy Frydkær Jensen (danish) 41 | Miguel Anxo Bouzada (galician) 42 | Baptiste Barthenay, Michael Moroni (esperanto) 43 | alleinsora (swedish) 44 | 45 | ~Spayder26 (Pyjama image) 46 | Ubuntu's human theme (money.png, cd.png) 47 | Tulliana icon theme (juk.png, kdmconfig.png, personal.png) 48 | creativecommong.org (CC License images) 49 | Oxygen-Icons (preferences_plugin.png) 50 | wpclipart.com (any other image) 51 | 52 | images/pyjama.png 53 | 54 | 55 | True 56 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 57 | 2 58 | 59 | 60 | 61 | 62 | 63 | True 64 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 65 | GTK_BUTTONBOX_END 66 | 67 | 68 | False 69 | GTK_PACK_END 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /modules/clEvent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | # This Script was found on: 21 | # http://www.valuedlessons.com/2008/04/events-in-python.html 22 | 23 | 24 | ## @package clEvent 25 | # Pyjama's custom event module 26 | 27 | ## The EventHandler class represents the Event itself. 28 | # A EventHandler is created for earch plugin created. 29 | # Usually you do not have to use this class. 30 | # Please have a look at clEvent.Events 31 | class EventHandler: 32 | def __init__(self): 33 | ## List of functions which will be called by this EventHandler 34 | self.handlers = [] #set() 35 | 36 | ## Adds an function to the handler list 37 | def handle(self, handler): 38 | #self.handlers.insert(0,handler) 39 | self.handlers.append(handler) 40 | return self 41 | 42 | ## Removes a function from the handler list 43 | def unhandle(self, handler): 44 | try: 45 | self.handlers.remove(handler) 46 | except: 47 | raise ValueError("Handler is not handling this event, so cannot unhandle it.") 48 | return self 49 | 50 | ## Calls each function in the handler list 51 | # @param *args Arguments 52 | # @param **kargs Keyword arguments 53 | def fire(self, *args, **kargs): 54 | for handler in self.handlers: 55 | # if "alldone" in str(handler): print handler 56 | handler(*args, **kargs) 57 | 58 | ## Returns the number of functions connected to this event 59 | def getHandlerCount(self): 60 | return len(self.handlers) 61 | 62 | __iadd__ = handle 63 | __isub__ = unhandle 64 | __call__ = fire 65 | __len__ = getHandlerCount 66 | 67 | ## Pyjama's event class is the EventHandler class interface 68 | class Events: 69 | def __init__(self): 70 | # self.pluginloaded = EventHandler() 71 | # self.nowplaying = EventHandler() 72 | # self.alldone = EventHandler() 73 | ## A dictionary with all events created 74 | self.dict = {} 75 | 76 | ## Creates a new event 77 | # @param self Object Pointer 78 | # @param eventname The new event's name 79 | # @return None 80 | def add_event(self, eventname): 81 | self.dict[eventname] = EventHandler() 82 | 83 | ## Connects to an existing event 84 | # @param self Object Pointer 85 | # @param eventname Name of the event to connect to 86 | # @param fkt The function to call when this event is raised 87 | # @return None 88 | def connect_event(self, eventname, fkt): 89 | self.dict[eventname] += fkt 90 | 91 | ## Disconnects a function from an event 92 | # @param self Object Pointer 93 | # @param eventname Name of the event to disconnect from 94 | # @param fkt The function to disconnect 95 | # @return None 96 | def disconnect_event(self, eventname, fkt, *argv): 97 | self.dict[eventname] -= fkt 98 | 99 | ## Raises an event 100 | # @param self Object Pointer 101 | # @param eventname Name of the event to raise 102 | # @param *argv Arguments to pass to the connected functions 103 | # @param *kargs Keyword arguments to pass to the connected functions 104 | # @return None 105 | def raise_event(self, eventname, *argv, **kargs): 106 | self.dict[eventname](*argv, **kargs) 107 | 108 | -------------------------------------------------------------------------------- /modules/clXMLRPC.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | ## @package clXMLRPC 21 | # This module will - perhaps - be used for inter process 22 | # communication later. 23 | # Since I just need this feature in order to connect pyjama 24 | # with jamendo playlists, I will use a more failsafe mechanism 25 | # for the time being. 26 | 27 | 28 | from SimpleXMLRPCServer import SimpleXMLRPCServer 29 | 30 | import socket 31 | socket.setdefaulttimeout(3) 32 | import xmlrpclib 33 | 34 | from threading import Thread 35 | import gtk 36 | 37 | class ClientOnlyException(Exception): 38 | pass 39 | 40 | class XmlrpcHandler: 41 | def __init__(self, pyjama): 42 | self.pyjama = pyjama 43 | 44 | def test(self, inte): 45 | return True 46 | 47 | def load_playlist(self, playlist_file): 48 | print ("Got playlist %s" % playlist_file) 49 | self.pyjama.playlist_to_load = playlist_file 50 | 51 | def get_curplaying(self): 52 | return self.pyjama.player.cur_playing 53 | 54 | def get_state(self): 55 | return self.pyjama.player.status 56 | 57 | def playpause(self): 58 | gtk.gdk.threads_enter() 59 | self.pyjama.window.on_bPlay_clicked(None) 60 | gtk.gdk.threads_leave() 61 | 62 | #~ def pause(self): 63 | #~ self.pyjama.window.cb_bC 64 | 65 | def next(self): 66 | gtk.gdk.threads_enter() 67 | self.pyjama.window.on_bNext_clicked(None) 68 | gtk.gdk.threads_leave() 69 | 70 | def prev(self): 71 | gtk.gdk.threads_enter() 72 | self.pyjama.window.on_bPrev_clicked(None) 73 | gtk.gdk.threads_leave() 74 | 75 | #~ def print_string(self, string): 76 | #~ print string 77 | 78 | class XMLRPC: 79 | def __init__(self, pyjama, clientonly=False): 80 | self.pyjama = pyjama 81 | self.clientonly = clientonly 82 | 83 | self.connect_or_create() 84 | 85 | def connect_or_create(self): 86 | self.server = None 87 | self.role = None 88 | ## check if a server is running 89 | # if not, serve 90 | try: 91 | self.server = xmlrpclib.ServerProxy("http://localhost:50506", allow_none=True) 92 | self.server.test(23) 93 | self.role = "client" 94 | print ("Found XMLRPC-Server on localhost:50506") 95 | except socket.error, inst: 96 | if self.clientonly: 97 | raise ClientOnlyException, "No server found" 98 | thr = Thread(target = self.serve, args = ()) 99 | thr.start() 100 | self.role = "server" 101 | 102 | def send_playlist(self, playlist_file): 103 | self.server.load_playlist(playlist_file) 104 | 105 | # run by client 106 | def test(self): 107 | if self.role == "client": 108 | try: 109 | self.server.test(23) 110 | except: 111 | print ("Server no more running") 112 | self.connect_or_create() 113 | 114 | 115 | def quit(self): 116 | if self.role == "server": 117 | try: 118 | self.server.shutdown() 119 | except Exception, inst: 120 | print ("Error shutting down the XMLRPC-server: %s" % inst) 121 | 122 | def serve(self): 123 | self.server = SimpleXMLRPCServer(("localhost", 50506), allow_none=True) 124 | self.server.register_instance(XmlrpcHandler(self.pyjama)) 125 | print ("Running XMLRPC-Server on localhost:50506") 126 | self.server.serve_forever() 127 | return self.server 128 | -------------------------------------------------------------------------------- /plugins/configtool/configtool.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 550 7 | 320 8 | 5 9 | Pyjama Configtool 10 | True 11 | GTK_WIN_POS_CENTER_ON_PARENT 12 | GDK_WINDOW_TYPE_HINT_DIALOG 13 | 14 | 15 | True 16 | 2 17 | 18 | 19 | True 20 | True 21 | GTK_POS_LEFT 22 | True 23 | True 24 | 25 | 26 | True 27 | True 28 | False 29 | GTK_WRAP_WORD_CHAR 30 | 10 31 | 10 32 | Configtool is a simple dynamic config editor for Pyjama. 33 | Please take care when editing your config file. If you should have made a mistake and Pyjama does not run properly any more, just delete the file "~/.pyjama/pyjama.cfg". 34 | Please notice, that some values will only take effect after restarting Pyjama. 35 | 36 | 37 | 38 | 39 | True 40 | <b>About</b> 41 | True 42 | 43 | 44 | tab 45 | False 46 | 47 | 48 | 49 | 50 | 2 51 | 52 | 53 | 54 | 55 | True 56 | GTK_BUTTONBOX_END 57 | 58 | 59 | True 60 | True 61 | True 62 | gtk-cancel 63 | True 64 | 0 65 | 66 | 67 | 68 | 69 | True 70 | True 71 | True 72 | gtk-apply 73 | True 74 | 0 75 | 76 | 77 | 1 78 | 79 | 80 | 81 | 82 | False 83 | GTK_PACK_END 84 | 1 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /plugins/downloadGUI/downloadGUI.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 270 7 | 130 8 | 5 9 | Download 10 | False 11 | True 12 | center-on-parent 13 | dialog 14 | True 15 | False 16 | False 17 | 18 | 19 | True 20 | 2 21 | 22 | 23 | True 24 | 25 | 26 | True 27 | In order to keep your database up to date, 28 | you will have to get the latest database 29 | dump from jamendo from time to time. 30 | True 31 | True 32 | 33 | 34 | False 35 | 10 36 | 0 37 | 38 | 39 | 40 | 41 | True 42 | 43 | 44 | 10 45 | 1 46 | 47 | 48 | 49 | 50 | 1 51 | 52 | 53 | 54 | 55 | True 56 | end 57 | 58 | 59 | gtk-close 60 | True 61 | True 62 | True 63 | True 64 | 65 | 66 | False 67 | False 68 | 0 69 | 70 | 71 | 72 | 73 | gtk-save 74 | True 75 | True 76 | True 77 | True 78 | 79 | 80 | False 81 | False 82 | 1 83 | 84 | 85 | 86 | 87 | gtk-ok 88 | True 89 | True 90 | True 91 | 92 | 93 | False 94 | False 95 | 2 96 | 97 | 98 | 99 | 100 | False 101 | end 102 | 0 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /plugins/PVC/PVC.glade_window: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 400 7 | 250 8 | True 9 | center 10 | dialog 11 | True 12 | True 13 | 14 | 15 | True 16 | 17 | 18 | True 19 | True 20 | never 21 | automatic 22 | in 23 | 24 | 25 | True 26 | True 27 | False 28 | word 29 | fill 30 | 10 31 | 10 32 | False 33 | 34 | 35 | 36 | 37 | 0 38 | 39 | 40 | 41 | 42 | True 43 | 10 44 | 10 45 | start 46 | 47 | 48 | gtk-ok 49 | True 50 | True 51 | True 52 | True 53 | True 54 | top 55 | 56 | 57 | False 58 | False 59 | 0 60 | 61 | 62 | 63 | 64 | gtk-refresh 65 | True 66 | True 67 | True 68 | True 69 | top 70 | 71 | 72 | False 73 | False 74 | 1 75 | 76 | 77 | 78 | 79 | gtk-preferences 80 | True 81 | True 82 | True 83 | True 84 | True 85 | top 86 | 87 | 88 | False 89 | False 90 | 20 91 | 2 92 | 93 | 94 | 95 | 96 | False 97 | False 98 | 1 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /clLayouts/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | ## @package clLayouts 21 | # This module manages the different layouts for pyjama 22 | # e.g. AlbumBrowser, AlbumLayout and ArtistLayout 23 | 24 | import gtk 25 | import time 26 | 27 | 28 | ## Handling the Layouts. 29 | # You'll have to register your custon Layout 30 | # here. 31 | class Layouts(): 32 | ## The Constructor 33 | def __init__(self, pyjama): 34 | self.__pyjama = pyjama 35 | ## Dictionary filled with layouts later 36 | self.layouts = {} 37 | ## Dictionary filled with the layouts' toolbars later 38 | self.toolbars = {} 39 | ## Holds the currently shown layout 40 | self.current_layout = None 41 | 42 | self.__pyjama.Events.add_event("show_layout") 43 | 44 | ## Registers a layout. 45 | # Each Layout needs a methode draw() and a subclass called ToolBar(). 46 | # See \ref layout-draw and \ref layout-toolbar. 47 | # @param self Object Pointer 48 | # @param layout_name The name of the layout to register 49 | # @param layout_class The layout class to call when you want you Layout to be shown 50 | # @return None 51 | def register_layout(self, layout_name, layout_class): 52 | self.layouts[layout_name] = layout_class 53 | self.toolbars[layout_name] = layout_class.ToolBar(self.__pyjama) 54 | self.__pyjama.window.vbMainLayout.pack_start(self.toolbars[layout_name], False, True) 55 | 56 | ## Show a layout 57 | # This methode is the central layout function. 58 | # When you've registered your layout, you can show it 59 | # calling this function. 60 | # @param self Object Pointer 61 | # @param layout The layout to show (as registered in register_layout() before) 62 | # @param data1 Optional - Data you want to pass to your layout's draw() methode 63 | # @param data2 Optional - Data you want to pass to your layout's draw() methode 64 | # @param data3 Optional - Data you want to pass to your layout's draw() methode 65 | # @param data4 Optional - Data you want to pass to your layout's draw() methode 66 | # @param fromhistory Optional bool - default is False - If set to True the page won't be 67 | # stored in hinstory 68 | # @param who_called Optional - for debugging perpose only - which methode called this? 69 | # @return None 70 | # @todo 71 | # - use *args or **kargs as params instead of data(n) 72 | def show_layout(self, layout, data1=None, data2=None, data3=None, data4=None, fromhistory=False, who_called=""): 73 | if self.__pyjama.debug: 74 | print ("Called by: %s" % who_called) 75 | 76 | # hiding the last layout's toolbar 77 | if self.current_layout != None and layout != self.current_layout: 78 | self.toolbars[self.current_layout].hide() 79 | 80 | # Unset Layout Info 81 | self.__pyjama.window.LayoutInfo.set_text("") 82 | self.__pyjama.window.LayoutInfo.set_image(None) 83 | 84 | # 85 | # History 86 | # 87 | if self.__pyjama.historyCurrent != {} and fromhistory==False: 88 | self.__pyjama.historyBack.append(self.__pyjama.historyCurrent) 89 | if fromhistory == False: 90 | self.__pyjama.historyForward = [] 91 | self.__pyjama.historyCurrent = {'layout':layout, 'data1':data1, 'data2':data2, 'data3':data3, 'data4':data4} 92 | self.__pyjama.window.toolbar.bHistoryForward.set_sensitive(len(self.__pyjama.historyForward)>0) 93 | self.__pyjama.window.toolbar.bHistoryBack.set_sensitive(len(self.__pyjama.historyBack)>0) 94 | 95 | # 96 | # insert Layout into scrolledwindow 97 | # 98 | if self.current_layout != None: 99 | self.__pyjama.window.scrolledwindow.remove(self.__pyjama.window.scrolledwindow.child) 100 | # For non-scrollable widgets - no scrollbars for some reasons 101 | # self.__pyjama.window.scrolledwindow.add_with_viewport(self.layouts[layout]) 102 | if isinstance(self.layouts[layout], gtk.Layout): 103 | self.__pyjama.window.scrolledwindow.add(self.layouts[layout]) 104 | else: 105 | self.__pyjama.window.scrolledwindow.add_with_viewport(self.layouts[layout]) 106 | # Setting Scrollbars 107 | self.__pyjama.window.scrolledwindow.set_vadjustment(gtk.Adjustment(value=0, lower=0, upper=0, step_incr=0, page_incr=0, page_size=0)) 108 | 109 | self.current_layout = layout 110 | 111 | # showing the toolbar 112 | self.toolbars[layout].show() 113 | # calling the layout's draw method:, 114 | self.layouts[layout].draw(data1, data2, data3, data4) 115 | self.__pyjama.window.do_events() 116 | -------------------------------------------------------------------------------- /extended_modules/clBookmarkDialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | '''Tree View/editable Cells 3 | 4 | This demo demonstrates the use of editable cells in a Gtkself.treeview.. 5 | If you're new to the Gtkself.treeview. widgets and associates, look into the 6 | GtkListStore example first.''' 7 | # pygtk version: Maik Hertha 8 | 9 | import gobject 10 | import gtk 11 | 12 | # columns 13 | ( 14 | COLUMN_NAME, 15 | COLUMN_HASH, 16 | COLUMN_EDITABLE 17 | ) = range(3) 18 | 19 | 20 | class Dialog(gtk.Dialog): 21 | def __init__(self, parent=None, bookmarks=[]): 22 | gtk.Dialog.__init__(self) 23 | 24 | self.bookmarks = bookmarks 25 | self.deleted = [] 26 | 27 | self.set_modal(True) 28 | self.set_title(_("Bookmarks")) 29 | self.set_border_width(5) 30 | self.set_default_size(320, 400) 31 | 32 | 33 | label = gtk.Label(_("Here you can edit your Bookmarks. Doubleclick on a field to change its name.\nSelect a field by singleclicking it and delete it with clicking 'remove'")) 34 | label.set_line_wrap(True) 35 | label.set_single_line_mode(False) 36 | self.vbox.pack_start(label, expand=False, fill=True) 37 | 38 | sw = gtk.ScrolledWindow() 39 | sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) 40 | sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) 41 | self.vbox.pack_start(sw) 42 | 43 | # create model 44 | model = self.__create_model() 45 | 46 | # create tree view 47 | self.treeview = gtk.TreeView(model) 48 | self.treeview.set_rules_hint(True) 49 | self.treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) 50 | 51 | self.__add_columns(self.treeview) 52 | 53 | sw.add(self.treeview) 54 | 55 | # some buttons 56 | hbox = gtk.HBox(True, 4) 57 | self.vbox.pack_start(hbox, False, False) 58 | 59 | # button = gtk.Button(stock=gtk.STOCK_ADD) 60 | # button.connect("clicked", self.on_add_item_clicked, model) 61 | # hbox.pack_start(button) 62 | 63 | button = gtk.Button(stock=gtk.STOCK_REMOVE) 64 | button.connect("clicked", self.on_remove_item_clicked, self.treeview) 65 | hbox.pack_start(button) 66 | 67 | self.add_button(gtk.STOCK_CANCEL, -1) 68 | self.add_button(gtk.STOCK_OK, 1) 69 | 70 | self.populate_list(self.bookmarks) 71 | 72 | self.show_all() 73 | 74 | def __create_model(self): 75 | 76 | # create list store 77 | model = gtk.ListStore( 78 | gobject.TYPE_STRING, 79 | gobject.TYPE_STRING, 80 | gobject.TYPE_BOOLEAN 81 | ) 82 | return model 83 | 84 | # # add items 85 | # for item in bookmarks: 86 | # iter = model.append() 87 | 88 | # model.set (iter, 89 | # COLUMN_NAME, item[COLUMN_NAME], 90 | # COLUMN_HASH, item[COLUMN_HASH], 91 | # COLUMN_EDITABLE, True 92 | # ) 93 | # return model 94 | 95 | 96 | def __add_columns(self, treeview): 97 | 98 | model = treeview.get_model() 99 | 100 | # # number column 101 | # renderer = gtk.CellRendererText() 102 | # renderer.connect("edited", self.on_cell_edited, model) 103 | # renderer.set_data("column", COLUMN_NUMBER) 104 | 105 | # column = gtk.self.treeview.Column("Number", renderer, text=COLUMN_NUMBER, 106 | # HASH=COLUMN_HASH) 107 | # self.treeview..append_column(column) 108 | 109 | # NAME column 110 | renderer = gtk.CellRendererText() 111 | renderer.connect("edited", self.on_cell_edited, model) 112 | renderer.set_data("column", COLUMN_NAME) 113 | 114 | column = gtk.TreeViewColumn(_("Your Bookmarks"), renderer, text=COLUMN_NAME, editable=COLUMN_EDITABLE) 115 | treeview.append_column(column) 116 | 117 | def populate_list(self, bookmark_list): 118 | model = self.treeview.get_model() 119 | for item in bookmark_list: 120 | new_item = [item['name'], item['hash']] 121 | #bookmarks.append(new_item) 122 | 123 | iter = model.append() 124 | model.set (iter, 125 | COLUMN_NAME, new_item[COLUMN_NAME], 126 | COLUMN_HASH, new_item[COLUMN_HASH], 127 | COLUMN_EDITABLE, True 128 | ) 129 | 130 | # def on_add_item_clicked(self, button, model): 131 | # new_item = ["Description here", True] 132 | # bookmarks.append(new_item) 133 | 134 | # iter = model.append() 135 | # model.set (iter, 136 | # COLUMN_NAME, new_item[COLUMN_NAME], 137 | # COLUMN_HASH, new_item[COLUMN_HASH] 138 | # ) 139 | 140 | 141 | def on_remove_item_clicked(self, button, treeview): 142 | 143 | selection = treeview.get_selection() 144 | model, iter = selection.get_selected() 145 | 146 | if iter: 147 | path = model.get_path(iter)[0] 148 | model.remove(iter) 149 | 150 | # del self.bookmarks[ path ] 151 | self.deleted.append({"name":self.bookmarks[path]['name'], "hash":self.bookmarks[path]['hash']}) 152 | del self.bookmarks[path] 153 | 154 | 155 | def on_cell_edited(self, cell, path_string, new_text, model): 156 | 157 | iter = model.get_iter_from_string(path_string) 158 | path = model.get_path(iter)[0] 159 | column = cell.get_data("column") 160 | 161 | if column == COLUMN_NAME: 162 | old_text = model.get_value(iter, column) 163 | self.bookmarks[path]['name'] = new_text 164 | 165 | model.set(iter, column, self.bookmarks[path]['name']) 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /plugins/lastfm/__init__.py.BASE: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 32 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 33 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 34 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 35 | 36 | # login to last.fm 37 | try: 38 | # pyjama has own last.fm clien id 'pyj' 39 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 40 | self.scrobbler.login(self.login, self.password) 41 | except Exception, e: 42 | logging.error(e) 43 | self.scrobbler = None 44 | raise 45 | logging.debug('last.fm plugin loaded') 46 | 47 | 48 | def ev_nowplaying(self,track): 49 | """ for sending now playing notification to last.fm """ 50 | logging.debug('nowplaying: %s' % track) 51 | 52 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 53 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 54 | logging.warn('cat\' send nowplaying info to last.fm') 55 | else: 56 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 57 | else: 58 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 59 | 60 | def ev_scrobble(self,track): 61 | """ for scrobbling to last.fm """ 62 | logging.debug('track: %s' % track) 63 | 64 | 65 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 66 | try: 67 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 68 | except Exception, e: 69 | logging.error(e) 70 | raise 71 | 72 | if not self.scrobbler.flush(): 73 | logging.warn('last.fm plugin: can\'t scrobble song') 74 | else: 75 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 76 | 77 | 78 | 79 | else: 80 | logging.debug('song doesn\' scrobbled - scrobbling is off') 81 | 82 | 83 | 84 | 85 | class Preferences(): 86 | ## Preferences Constructor 87 | # @param self Object Pointer 88 | # @param pyjama Again we have a pyjama object reference passed to our class 89 | def __init__(self, pyjama): 90 | # get settings 91 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 92 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 93 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 94 | 95 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 96 | 97 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 98 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 99 | dialog.set_title(_("last.fm Plugin Preferences")) 100 | dialog.set_default_size(100,100) 101 | 102 | hbox = gtk.HBox() 103 | dialog.vbox.pack_start(hbox, False, True) 104 | hbox.show() 105 | 106 | hbox2 = gtk.HBox() 107 | dialog.vbox.pack_start(hbox2, False, True) 108 | hbox2.show() 109 | 110 | 111 | # scrobble check button 112 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 113 | check.set_active(scrobble_value) 114 | dialog.vbox.pack_start(check, False, True) 115 | 116 | # login field 117 | llabel=gtk.Label(_('Login:')) 118 | hbox.pack_start(llabel, False, True) 119 | 120 | login = gtk.Entry(max=0) 121 | login.set_text(login_value) 122 | hbox.pack_end(login, False, True) 123 | 124 | # password field 125 | plabel=gtk.Label(_('Password:')) 126 | hbox2.pack_start(plabel, False, True) 127 | 128 | password = gtk.Entry(max=0) 129 | password.set_text(pass_value) 130 | password.set_visibility(False) 131 | hbox2.pack_end(password, False, True) 132 | 133 | dialog.show_all() 134 | result = dialog.run() 135 | dialog.destroy() 136 | # set new settings 137 | if result == 1: 138 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 139 | logging.debug('new login: %s' % login.get_text()) 140 | 141 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 142 | logging.debug('new pass: %s' % password.get_text()) 143 | 144 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 145 | logging.debug('new scrobble vaule: %s' % check.get_active()) 146 | 147 | 148 | -------------------------------------------------------------------------------- /plugins/librefm/__init__.py.BASE: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 32 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 33 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 34 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 35 | 36 | # login to last.fm 37 | try: 38 | # pyjama has own last.fm clien id 'pyj' 39 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 40 | self.scrobbler.login(self.login, self.password) 41 | except Exception, e: 42 | logging.error(e) 43 | self.scrobbler = None 44 | raise 45 | logging.debug('last.fm plugin loaded') 46 | 47 | 48 | def ev_nowplaying(self,track): 49 | """ for sending now playing notification to last.fm """ 50 | logging.debug('nowplaying: %s' % track) 51 | 52 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 53 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 54 | logging.warn('cat\' send nowplaying info to last.fm') 55 | else: 56 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 57 | else: 58 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 59 | 60 | def ev_scrobble(self,track): 61 | """ for scrobbling to last.fm """ 62 | logging.debug('track: %s' % track) 63 | 64 | 65 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 66 | try: 67 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 68 | except Exception, e: 69 | logging.error(e) 70 | raise 71 | 72 | if not self.scrobbler.flush(): 73 | logging.warn('last.fm plugin: can\'t scrobble song') 74 | else: 75 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 76 | 77 | 78 | 79 | else: 80 | logging.debug('song doesn\' scrobbled - scrobbling is off') 81 | 82 | 83 | 84 | 85 | class Preferences(): 86 | ## Preferences Constructor 87 | # @param self Object Pointer 88 | # @param pyjama Again we have a pyjama object reference passed to our class 89 | def __init__(self, pyjama): 90 | # get settings 91 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 92 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 93 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 94 | 95 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 96 | 97 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 98 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 99 | dialog.set_title(_("last.fm Plugin Preferences")) 100 | dialog.set_default_size(100,100) 101 | 102 | hbox = gtk.HBox() 103 | dialog.vbox.pack_start(hbox, False, True) 104 | hbox.show() 105 | 106 | hbox2 = gtk.HBox() 107 | dialog.vbox.pack_start(hbox2, False, True) 108 | hbox2.show() 109 | 110 | 111 | # scrobble check button 112 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 113 | check.set_active(scrobble_value) 114 | dialog.vbox.pack_start(check, False, True) 115 | 116 | # login field 117 | llabel=gtk.Label(_('Login:')) 118 | hbox.pack_start(llabel, False, True) 119 | 120 | login = gtk.Entry(max=0) 121 | login.set_text(login_value) 122 | hbox.pack_end(login, False, True) 123 | 124 | # password field 125 | plabel=gtk.Label(_('Password:')) 126 | hbox2.pack_start(plabel, False, True) 127 | 128 | password = gtk.Entry(max=0) 129 | password.set_text(pass_value) 130 | password.set_visibility(False) 131 | hbox2.pack_end(password, False, True) 132 | 133 | dialog.show_all() 134 | result = dialog.run() 135 | dialog.destroy() 136 | # set new settings 137 | if result == 1: 138 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 139 | logging.debug('new login: %s' % login.get_text()) 140 | 141 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 142 | logging.debug('new pass: %s' % password.get_text()) 143 | 144 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 145 | logging.debug('new scrobble vaule: %s' % check.get_active()) 146 | 147 | 148 | -------------------------------------------------------------------------------- /plugins/lastfm/__init__.py.OTHER.moved: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 32 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 33 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 34 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 35 | 36 | # login to last.fm 37 | try: 38 | # pyjama has own last.fm clien id 'pyj' 39 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 40 | self.scrobbler.login(self.login, self.password) 41 | except Exception, e: 42 | logging.error(e) 43 | self.scrobbler = None 44 | raise 45 | logging.debug('last.fm plugin loaded') 46 | 47 | 48 | def ev_nowplaying(self,track): 49 | """ for sending now playing notification to last.fm """ 50 | logging.debug('nowplaying: %s' % track) 51 | 52 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 53 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 54 | logging.warn('cat\' send nowplaying info to last.fm') 55 | else: 56 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 57 | else: 58 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 59 | 60 | def ev_scrobble(self,track): 61 | """ for scrobbling to last.fm """ 62 | logging.debug('track: %s' % track) 63 | 64 | 65 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 66 | try: 67 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 68 | except Exception, e: 69 | logging.error(e) 70 | raise 71 | 72 | if not self.scrobbler.flush(): 73 | logging.warn('last.fm plugin: can\'t scrobble song') 74 | else: 75 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 76 | 77 | 78 | 79 | else: 80 | logging.debug('song doesn\' scrobbled - scrobbling is off') 81 | 82 | 83 | 84 | 85 | class Preferences(): 86 | ## Preferences Constructor 87 | # @param self Object Pointer 88 | # @param pyjama Again we have a pyjama object reference passed to our class 89 | def __init__(self, pyjama): 90 | # get settings 91 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 92 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 93 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 94 | 95 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 96 | 97 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 98 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 99 | dialog.set_title(_("last.fm Plugin Preferences")) 100 | dialog.set_default_size(100,100) 101 | 102 | hbox = gtk.HBox() 103 | dialog.vbox.pack_start(hbox, False, True) 104 | hbox.show() 105 | 106 | hbox2 = gtk.HBox() 107 | dialog.vbox.pack_start(hbox2, False, True) 108 | hbox2.show() 109 | 110 | 111 | # scrobble check button 112 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 113 | check.set_active(scrobble_value) 114 | dialog.vbox.pack_start(check, False, True) 115 | 116 | # login field 117 | llabel=gtk.Label(_('Login:')) 118 | hbox.pack_start(llabel, False, True) 119 | 120 | login = gtk.Entry(max=0) 121 | login.set_text(login_value) 122 | hbox.pack_end(login, False, True) 123 | 124 | # password field 125 | plabel=gtk.Label(_('Password:')) 126 | hbox2.pack_start(plabel, False, True) 127 | 128 | password = gtk.Entry(max=0) 129 | password.set_text(pass_value) 130 | password.set_visibility(False) 131 | hbox2.pack_end(password, False, True) 132 | 133 | dialog.show_all() 134 | result = dialog.run() 135 | dialog.destroy() 136 | # set new settings 137 | if result == 1: 138 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 139 | logging.debug('new login: %s' % login.get_text()) 140 | 141 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 142 | logging.debug('new pass: %s' % password.get_text()) 143 | 144 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 145 | logging.debug('new scrobble vaule: %s' % check.get_active()) 146 | 147 | 148 | -------------------------------------------------------------------------------- /plugins/librefm/__init__.py.OTHER.moved: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 32 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 33 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 34 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 35 | 36 | # login to last.fm 37 | try: 38 | # pyjama has own last.fm clien id 'pyj' 39 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 40 | self.scrobbler.login(self.login, self.password) 41 | except Exception, e: 42 | logging.error(e) 43 | self.scrobbler = None 44 | raise 45 | logging.debug('last.fm plugin loaded') 46 | 47 | 48 | def ev_nowplaying(self,track): 49 | """ for sending now playing notification to last.fm """ 50 | logging.debug('nowplaying: %s' % track) 51 | 52 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 53 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 54 | logging.warn('cat\' send nowplaying info to last.fm') 55 | else: 56 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 57 | else: 58 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 59 | 60 | def ev_scrobble(self,track): 61 | """ for scrobbling to last.fm """ 62 | logging.debug('track: %s' % track) 63 | 64 | 65 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 66 | try: 67 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 68 | except Exception, e: 69 | logging.error(e) 70 | raise 71 | 72 | if not self.scrobbler.flush(): 73 | logging.warn('last.fm plugin: can\'t scrobble song') 74 | else: 75 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 76 | 77 | 78 | 79 | else: 80 | logging.debug('song doesn\' scrobbled - scrobbling is off') 81 | 82 | 83 | 84 | 85 | class Preferences(): 86 | ## Preferences Constructor 87 | # @param self Object Pointer 88 | # @param pyjama Again we have a pyjama object reference passed to our class 89 | def __init__(self, pyjama): 90 | # get settings 91 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 92 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 93 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 94 | 95 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 96 | 97 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 98 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 99 | dialog.set_title(_("last.fm Plugin Preferences")) 100 | dialog.set_default_size(100,100) 101 | 102 | hbox = gtk.HBox() 103 | dialog.vbox.pack_start(hbox, False, True) 104 | hbox.show() 105 | 106 | hbox2 = gtk.HBox() 107 | dialog.vbox.pack_start(hbox2, False, True) 108 | hbox2.show() 109 | 110 | 111 | # scrobble check button 112 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 113 | check.set_active(scrobble_value) 114 | dialog.vbox.pack_start(check, False, True) 115 | 116 | # login field 117 | llabel=gtk.Label(_('Login:')) 118 | hbox.pack_start(llabel, False, True) 119 | 120 | login = gtk.Entry(max=0) 121 | login.set_text(login_value) 122 | hbox.pack_end(login, False, True) 123 | 124 | # password field 125 | plabel=gtk.Label(_('Password:')) 126 | hbox2.pack_start(plabel, False, True) 127 | 128 | password = gtk.Entry(max=0) 129 | password.set_text(pass_value) 130 | password.set_visibility(False) 131 | hbox2.pack_end(password, False, True) 132 | 133 | dialog.show_all() 134 | result = dialog.run() 135 | dialog.destroy() 136 | # set new settings 137 | if result == 1: 138 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 139 | logging.debug('new login: %s' % login.get_text()) 140 | 141 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 142 | logging.debug('new pass: %s' % password.get_text()) 143 | 144 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 145 | logging.debug('new scrobble vaule: %s' % check.get_active()) 146 | 147 | 148 | -------------------------------------------------------------------------------- /plugins/torrent-peer/pytorrent/torrent.py: -------------------------------------------------------------------------------- 1 | from connection import Command, TorrentGetCommand, TorrentGetFileCommand, TorrentCommand 2 | import os.path 3 | 4 | STOPPED = "stopped" 5 | CHECKING = "checking" 6 | DOWNLOADING = "downloading" 7 | SEEDING = "seeding" 8 | 9 | def static_property(key): 10 | return property(lambda x: x._properties.get(key)) 11 | 12 | def dynamic_property(key): 13 | def query(self): 14 | command = TorrentGetCommand(key, self._id) 15 | torrent = self._connection.execute(command) 16 | return torrent.get(key) 17 | return property(query) 18 | 19 | def dynamic_file_property(key): 20 | def query(self): 21 | command = TorrentGetFileCommand(self._torrent._id, self._id) 22 | file = self._connection.execute(command) 23 | return file.get(key) 24 | return property(query) 25 | 26 | class File(object): 27 | def __init__(self, torrent, id, data): 28 | self._client = torrent._client 29 | self._connection = torrent._connection 30 | self._torrent = torrent 31 | self._id = id 32 | self._name = data["name"] 33 | self._properties = data 34 | 35 | def _get_finished(self): 36 | return self.downloaded_size == self.size 37 | 38 | def _get_wanted(self): 39 | command = TorrentGetCommand("wanted", self._torrent._id) 40 | torrent = self._connection.execute(command) 41 | return torrent["wanted"][self._id] == 1 42 | 43 | def _set_wanted(self, value): 44 | if value: 45 | field = "files-wanted" 46 | else: 47 | field = "files-unwanted" 48 | command = TorrentCommand("torrent-set", self._torrent._id) 49 | command[field] = [self._id] 50 | self._connection.execute(command) 51 | 52 | def _get_path(self): 53 | return os.path.join(self._client.download_dir, self._name) 54 | 55 | def __str__(self): 56 | return self._name 57 | 58 | id = property(lambda x: x._id) 59 | name = property(lambda x: x._name) 60 | path = property(_get_path) 61 | finished = property(_get_finished) 62 | wanted = property(_get_wanted, _set_wanted) 63 | size = static_property("length") 64 | downloaded_size = dynamic_file_property("bytesCompleted") 65 | 66 | class Torrent(object): 67 | static_fields = ["id", "name", "dateAdded", 68 | "announceResponse", "announceURL", 69 | "comment", "creator", 70 | "dateCreated", "hashString", 71 | "files", "totalSize"] 72 | 73 | def __init__(self, client, data): 74 | self._client = client 75 | self._connection = client._connection 76 | self._id = data["id"] 77 | self._name = data["name"] 78 | self._properties = data 79 | self._files = [] 80 | for id, file in enumerate(data["files"]): 81 | self._files.append(File(self, id, file)) 82 | 83 | def remove(self): 84 | command = TorrentCommand("torrent-remove", self._id) 85 | self._connection.execute(command) 86 | self._id = None 87 | self._name = None 88 | self._properties = {} 89 | 90 | def start(self): 91 | command = TorrentCommand("torrent-start", self._id) 92 | self._connection.execute(command) 93 | 94 | def stop(self): 95 | command = TorrentCommand("torrent-stop", self._id) 96 | self._connection.execute(command) 97 | 98 | def _get_downloaded_size(self): 99 | command = TorrentGetCommand("files", self._id) 100 | torrent = self._connection.execute(command) 101 | size = 0 102 | for file in torrent["files"]: 103 | size += file["bytesCompleted"] 104 | return size 105 | 106 | def _get_status(self): 107 | command = TorrentGetCommand("status", self._id) 108 | status = self._connection.execute(command)["status"] 109 | if status & 1 or status & 2: 110 | return CHECKING 111 | elif status & 4: 112 | return DOWNLOADING 113 | elif status & 8: 114 | return SEEDING 115 | else: 116 | return STOPPED 117 | 118 | def _get_finished(self): 119 | for file in self.files: 120 | if not file.finished: 121 | return False 122 | return True 123 | 124 | def __str__(self): 125 | return self._name 126 | 127 | id = property(lambda x: x._id) 128 | name = property(lambda x: x._name) 129 | files = property(lambda x: x._files) 130 | file = property(lambda x: x._files[0]) 131 | status = property(_get_status) 132 | finished= property(_get_finished) 133 | 134 | date_added = static_property("dateAdded") 135 | announce_response = static_property("announceResponse") 136 | announce_url = static_property("announceURL") 137 | comment = static_property("comment") 138 | creator = static_property("creator") 139 | date_created = static_property("dateCreated") 140 | hash = static_property("hashString") 141 | size = static_property("totalSize") 142 | downloaded_size = property(_get_downloaded_size) 143 | 144 | eta = dynamic_property("eta") 145 | leechers = dynamic_property("leechers") 146 | peers = dynamic_property("peers") 147 | peers_connected = dynamic_property("peersConnected") 148 | peers_getting = dynamic_property("peersGettingFromUs") 149 | peers_sending = dynamic_property("peersSendingToUs") 150 | download_rate = dynamic_property("rateDownload") 151 | upload_rate = dynamic_property("rateUpload") 152 | seeders = dynamic_property("seeders") 153 | weebseeds_sending = dynamic_property("webseedsSendingToUs") 154 | 155 | 156 | -------------------------------------------------------------------------------- /images/pyjama.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * pyjama_xpm[] = { 3 | "32 32 166 2", 4 | " c None", 5 | ". c #023331", 6 | "+ c #043D35", 7 | "@ c #03413C", 8 | "# c #05453D", 9 | "$ c #054F47", 10 | "% c #04554E", 11 | "& c #035954", 12 | "* c #025B57", 13 | "= c #025856", 14 | "- c #005757", 15 | "; c #005858", 16 | "> c #015A5A", 17 | ", c #035956", 18 | "' c #04473E", 19 | ") c #044943", 20 | "! c #025956", 21 | "~ c #015554", 22 | "{ c #005151", 23 | "] c #004D4D", 24 | "^ c #004A4A", 25 | "/ c #015352", 26 | "( c #004C4C", 27 | "_ c #005454", 28 | ": c #015755", 29 | "< c #035955", 30 | "[ c #025B58", 31 | "} c #03514B", 32 | "| c #025A56", 33 | "1 c #004E4D", 34 | "2 c #015C5B", 35 | "3 c #03504A", 36 | "4 c #04544E", 37 | "5 c #004B4B", 38 | "6 c #005252", 39 | "7 c #034C4C", 40 | "8 c #307369", 41 | "9 c #538473", 42 | "0 c #578A77", 43 | "a c #3A786C", 44 | "b c #054E4D", 45 | "c c #005050", 46 | "d c #025C58", 47 | "e c #04423B", 48 | "f c #035753", 49 | "g c #065D5A", 50 | "h c #699074", 51 | "i c #C1A753", 52 | "j c #D29E28", 53 | "k c #DC980D", 54 | "l c #DC970B", 55 | "m c #CB901D", 56 | "n c #B09147", 57 | "o c #2C6B61", 58 | "p c #004F4F", 59 | "q c #03514D", 60 | "r c #05443C", 61 | "s c #05504A", 62 | "t c #04544F", 63 | "u c #06554D", 64 | "v c #03544F", 65 | "w c #03504C", 66 | "x c #095F5B", 67 | "y c #9D9C67", 68 | "z c #D19211", 69 | "A c #CE9520", 70 | "B c #A26B67", 71 | "C c #83336F", 72 | "D c #AD985A", 73 | "E c #CB901E", 74 | "F c #EEA600", 75 | "G c #AA924F", 76 | "H c #004E4E", 77 | "I c #025D5B", 78 | "J c #04453E", 79 | "K c #768B68", 80 | "L c #C9870C", 81 | "M c #BC8421", 82 | "N c #9EA999", 83 | "O c #822182", 84 | "P c #820182", 85 | "Q c #814283", 86 | "R c #A88C4F", 87 | "S c #E9A100", 88 | "T c #B08C40", 89 | "U c #005656", 90 | "V c #035550", 91 | "W c #9D8447", 92 | "X c #D38F00", 93 | "Y c #AD823C", 94 | "Z c #772C78", 95 | "` c #7A1B7A", 96 | " . c #863886", 97 | ".. c #894480", 98 | "+. c #9C573A", 99 | "@. c #CC8A0E", 100 | "#. c #828D65", 101 | "$. c #005353", 102 | "%. c #035553", 103 | "&. c #035A57", 104 | "*. c #7C8C66", 105 | "=. c #BA7A0B", 106 | "-. c #BB7A0C", 107 | ";. c #A26E46", 108 | ">. c #BAA25C", 109 | ",. c #BE9E49", 110 | "'. c #C38713", 111 | "). c #BE871D", 112 | "!. c #919668", 113 | "~. c #005555", 114 | "{. c #005D5D", 115 | "]. c #03443D", 116 | "^. c #025D5A", 117 | "/. c #08504F", 118 | "(. c #848D65", 119 | "_. c #AA843D", 120 | ":. c #B08028", 121 | "<. c #B5862B", 122 | "[. c #B99644", 123 | "}. c #A39B5F", 124 | "|. c #488071", 125 | "1. c #014B4B", 126 | "2. c #004B4A", 127 | "3. c #005B5B", 128 | "4. c #045650", 129 | "5. c #034C45", 130 | "6. c #005958", 131 | "7. c #08514F", 132 | "8. c #1D635D", 133 | "9. c #286C64", 134 | "0. c #095250", 135 | "a. c #025351", 136 | "b. c #05453E", 137 | "c. c #063F37", 138 | "d. c #015A58", 139 | "e. c #035650", 140 | "f. c #006161", 141 | "g. c #045953", 142 | "h. c #024B47", 143 | "i. c #006463", 144 | "j. c #005F5F", 145 | "k. c #005C5C", 146 | "l. c #044B44", 147 | "m. c #035854", 148 | "n. c #035E5A", 149 | "o. c #044540", 150 | "p. c #005A59", 151 | "q. c #025E5A", 152 | "r. c #015B59", 153 | "s. c #04564F", 154 | "t. c #04453F", 155 | "u. c #005857", 156 | "v. c #034F4A", 157 | "w. c #054E49", 158 | "x. c #044B45", 159 | "y. c #044440", 160 | "z. c #043A38", 161 | "A. c #06413A", 162 | "B. c #035853", 163 | "C. c #025A57", 164 | "D. c #045852", 165 | "E. c #025A58", 166 | "F. c #015958", 167 | "G. c #03524C", 168 | "H. c #043F38", 169 | "I. c #043838", 170 | " ", 171 | " ", 172 | " ", 173 | " ", 174 | " ", 175 | " ", 176 | " . + @ ", 177 | " # $ % & * = - - ; > , ' ", 178 | " ) ! ~ { ] ^ ^ / ^ ^ ^ ^ ^ ( _ : < [ } ", 179 | " | ^ ^ ^ ^ ^ ^ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ { 2 3 ", 180 | " 4 5 ^ ^ ^ ^ ^ 6 ^ 7 8 9 0 a b ^ ^ ^ ^ ^ ^ c d e ", 181 | " f 5 ^ ^ ^ ^ ^ g h i j k l m n o ^ ^ ^ ^ ^ ^ p : q ", 182 | " r s t u v w x y z A B C D E F G ^ ^ ^ ^ ^ H ^ ^ H I J ", 183 | " q K L M N O P Q R S T ^ ^ ^ ^ H ^ ^ ^ ^ ^ U V ", 184 | " V { W X Y Z ` ...+.@.#.^ ^ ^ p ^ ^ ^ ^ ^ ^ ] $.%.", 185 | " &.H ^ *.=.-.;.>.,.'.).!.b ^ ^ p ^ ^ ^ ^ ^ ^ ~.{.{ < ", 186 | " ].^.( ^ ^ /.(._.:.<.[.}.|.1.^ ^ _ 2.^ ^ ^ ^ ^ ~.3.^ ( 4.", 187 | " 5.6.^ ^ ^ ^ ^ ^ 7.8.9.0.^ ^ ^ ^ ( a.f p ^ ^ ^ 6 {.^ ^ - b.", 188 | " c.f 6 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ d. e.{ ^ ( f.5 ^ H g. ", 189 | "h.i.j.k.- ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ { l. m.] {.p ^ p n. ", 190 | "o.p.^ ] $.k.j.~.5 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ q.{ { r.s. ", 191 | " t.u.^ ^ ^ 5 ~.j.k.{ ^ ^ ^ ^ ^ ^ ] v. b.w.x. ", 192 | " y.r.5 ^ ^ ^ ^ H ; j.{.~.] ^ ^ - z. ", 193 | " A.B.~.5 ^ ^ ^ ^ ^ ( _ k.{ ^ C. ", 194 | " J D.[ - - - ; d.E.! ! F.G. ", 195 | " H.I. ", 196 | " ", 197 | " ", 198 | " ", 199 | " ", 200 | " ", 201 | " "}; 202 | -------------------------------------------------------------------------------- /modules/clThreadedDownload.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | import urllib 21 | import hashlib 22 | import os 23 | 24 | import threading 25 | import gtk 26 | 27 | import clSettings 28 | import functions 29 | from clWidgets import ProcessDialog 30 | 31 | from time import sleep, time 32 | 33 | # Gettext - Übersetzung 34 | functions.translation_gettext() 35 | #def _(string): 36 | # return string 37 | 38 | settings = clSettings.settings() 39 | 40 | class Download_Images(): 41 | def __init__(self, pyjama, imglist): 42 | self.__pyjama = pyjama 43 | self.__imglist = imglist 44 | 45 | self.threads = [] 46 | 47 | 48 | def start(self): 49 | max_time_for_downloading = 10 + len(self.__imglist) * 0.1 50 | start_time = time() 51 | 52 | self.dia = ProcessDialog(self.__pyjama, _("Downloading %i images" % len(self.__imglist))) 53 | self.dia.set_description(_("Need to download %i images in order to display this page" % len(self.__imglist))) 54 | self.dia.show() 55 | 56 | self.__pyjama.window.do_events() 57 | 58 | counter = 0 59 | for image in self.__imglist: 60 | self.threads.append(Download(self.__pyjama, image, counter)) 61 | self.threads[counter].start() 62 | counter += 1 63 | print "Downloading %i images" % counter 64 | 65 | threads_alive = self.count_threads() 66 | while threads_alive > 0: 67 | if start_time + max_time_for_downloading <= time(): 68 | print "Aborting image download" 69 | self.dia.destroy() 70 | return threads_alive 71 | percentage = 100.0 / len(self.__imglist) * (len(self.__imglist) - threads_alive) 72 | self.dia.set_status(percentage, _("%i images remaining" % threads_alive)) 73 | self.__pyjama.window.do_events() 74 | print "%i threads pending, will abort in %i seconds" % (threads_alive, max_time_for_downloading + start_time - time()) 75 | sleep(self.__pyjama.settings.get_value("PERFORMANCE", "THREAD_WAIT")) 76 | threads_alive = self.count_threads() 77 | 78 | self.dia.destroy() 79 | 80 | def count_threads(self): 81 | counter = 0 82 | for thread in self.threads: 83 | if thread.isAlive(): 84 | counter += 1 85 | return counter 86 | 87 | def threads_alive(self): 88 | alive = [] 89 | for thread in self.threads: 90 | if thread.isAlive(): 91 | alive.append(thread) 92 | return alive 93 | 94 | class Download( threading.Thread ): 95 | def __init__( self, parent, url, num): 96 | if type(url) == type(()): 97 | if url[0] == "album": 98 | self.saveas = "http://api.jamendo.com/get2/image/album/redirect/?id=%s&imagesize=100" % url[1] 99 | self.url = "http://imgjam.com/albums/s%s/%s/covers/1.100.jpg" % (str(url[1])[0:2], url[1]) 100 | else: 101 | self.saveas = url 102 | self.url = url 103 | self.parent = parent 104 | self.num = num 105 | threading.Thread.__init__(self) 106 | 107 | ################################################################### 108 | # 109 | # get a album's cover 110 | # RETURNS: None = error 111 | # 112 | def run( self ): 113 | md5hash = hashlib.md5(self.saveas).hexdigest() 114 | imagepath = os.path.join(self.parent.home, "images", md5hash) 115 | if not os.path.exists(imagepath) and self.url != "": 116 | if self.parent.debug_extreme: 117 | print ("[%i] Trying to burst-download cover for '%s'[...]") % (self.num, self.url) 118 | try: 119 | urllib.urlretrieve(self.url, imagepath) 120 | if self.parent.debug_extreme: 121 | print ("[%i] Burst-downloaded Cover from Jamendo") % self.num 122 | return "0" 123 | except IOError: 124 | print ("[%i] Could not get album cover from jamendo:") % self.num 125 | print "'%s'" % self.url 126 | return "1" 127 | elif self.url == "": 128 | return "2" 129 | else: 130 | return "0" 131 | if self.parent.debug_extreme: 132 | print ("[%i] Not Burst-Downloading: Cover on HD") % self.num 133 | 134 | ################################################################### 135 | # 136 | # test if to much threads a running at the same time 137 | # RETURNS: True = to much threads, False = less than MAX_THREADS 138 | # 139 | def threadLimiter(threads): 140 | counter = 0 141 | for thread in threads: 142 | if threads[thread].isAlive(): 143 | counter += 1 144 | if counter > settings.get_value("PERFORMANCE", "MAX_THREADS"): 145 | return True 146 | return False 147 | 148 | def threadCounter(threads): 149 | counter = 0 150 | for thread in threads: 151 | if threads[thread].isAlive(): 152 | counter += 1 153 | return counter 154 | -------------------------------------------------------------------------------- /modules/notification.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------------- 5 | # pyjama - python jamendo audioplayer 6 | # Copyright (c) 2008 Daniel Nögel 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, version 3 of the License. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # 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 . 18 | # ---------------------------------------------------------------------------- 19 | 20 | # An example for this script was taken from: 21 | # John Dong 22 | # 23 | # He states: 24 | # "Feel free to use/tweak/modify to your free will." 25 | # 26 | 27 | import gtk 28 | import gobject 29 | try: 30 | import pynotify 31 | NOTIFICATIONS = True 32 | except ImportError: 33 | print "Module 'pynotify' not found" 34 | print "Not using notifications" 35 | NOTIFICATIONS = False 36 | 37 | import os 38 | import functions 39 | 40 | class TrayMenu(gtk.Menu): 41 | def __init__(self, parent): 42 | self.main = parent 43 | gtk.Menu.__init__(self) 44 | 45 | self.play_button_status = "play" 46 | self.draw_menu_items() 47 | 48 | def draw_menu_items(self, play=None): 49 | self.mnuShow = gtk.ImageMenuItem(_("Show Pyjama")) 50 | w, h = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) 51 | image = "hspbp-burnstation.png" 52 | img = gtk.Image() 53 | if not os.path.exists(image): 54 | image = os.path.join(functions.install_dir(), "images", image) 55 | if not os.path.exists(image): 56 | print ("Image not found") 57 | else: 58 | pix = gtk.gdk.pixbuf_new_from_file_at_size(image, w, h) 59 | img.set_from_pixbuf(pix) 60 | self.mnuShow.set_image(img) 61 | self.mnuShow.connect('activate', self.main.window.show_window) 62 | 63 | 64 | self.mnuPlay = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PLAY) 65 | self.mnuPlay.connect('activate', self.main.window.on_bPlay_clicked) 66 | 67 | 68 | self.mnuNext = gtk.ImageMenuItem(gtk.STOCK_MEDIA_NEXT) 69 | self.mnuNext.connect('activate', self.main.window.on_bNext_clicked) 70 | 71 | self.mnuPrev = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PREVIOUS) 72 | self.mnuPrev.connect('activate', self.main.window.on_bPrev_clicked) 73 | 74 | self.mnuQuit = gtk.ImageMenuItem(gtk.STOCK_QUIT) 75 | self.mnuQuit.connect('activate', self.main.window.really_quit) 76 | 77 | 78 | self.append(self.mnuShow) 79 | self.append(self.mnuPlay) 80 | self.append(self.mnuNext) 81 | self.append(self.mnuPrev) 82 | self.append(self.mnuQuit) 83 | 84 | def switch_play_button(self, play): 85 | self.play_button_status = play 86 | self.mnuPlay.destroy() 87 | if play=="play": 88 | self.mnuPlay = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PLAY) 89 | self.mnuPlay.connect('activate', self.main.window.on_bPlay_clicked) 90 | else: 91 | self.mnuPlay = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PAUSE) 92 | self.mnuPlay.connect('activate', self.main.window.on_bPlay_clicked) 93 | 94 | self.insert(self.mnuPlay, 1) 95 | 96 | 97 | class TrayIcon(): 98 | def __init__(self, parent, title = "Pyjama", text = "Python Jamendo Audiocenter"): 99 | self.parent = parent 100 | self.menu = TrayMenu(parent) 101 | if NOTIFICATIONS: 102 | pynotify.init("pynotify") 103 | self.notify = None 104 | # self.icon=gtk.status_icon_new_from_icon_name("warning") 105 | self.icon = gtk.status_icon_new_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png")) 106 | self.icon.set_visible(False) 107 | # self.icon.connect('activate', self.parent.switch_window_state) 108 | self.icon.connect('activate', self.parent.window.show_window) 109 | self.icon.connect('popup-menu', self.cb_popup_menu, self.menu) 110 | self.icon.connect('scroll-event', self.cb_scroll) 111 | self.icon.set_tooltip("%s\n%s" % (title, text)) 112 | self.icon.set_visible(True) 113 | 114 | 115 | def cb_popup_menu(self, widget, button, time, event): 116 | event.show_all() 117 | event.popup(None, None, None, 3, time) 118 | 119 | def cb_scroll(self, widget, event): 120 | new_volume = self.parent.window.hsVolume.get_value() 121 | if event.direction == gtk.gdk.SCROLL_UP: 122 | new_volume += 5 123 | elif event.direction == gtk.gdk.SCROLL_DOWN: 124 | new_volume -= 5 125 | self.parent.window.hsVolume.set_value(new_volume) 126 | 127 | def show_notification(self, caption, text, img = "pyjama", size = None): 128 | if not NOTIFICATIONS: return 129 | if size == None: size = self.parent.settings.get_value("PYJAMA", "notification_cover_size") 130 | pixbuf = None 131 | if img != "pyjama": 132 | pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(img, size, size) 133 | if not self.notify: 134 | self.notify = pynotify.Notification(caption, text) 135 | else: 136 | self.notify.update(caption, text) 137 | self.notify.set_icon_from_pixbuf(pixbuf) 138 | else: 139 | if not self.notify: 140 | self.notify = pynotify.Notification(caption, text, img) 141 | else: 142 | self.notify.update(caption, text, img) 143 | self.notify.set_urgency(pynotify.URGENCY_NORMAL) 144 | self.notify.attach_to_status_icon(self.icon) 145 | self.notify.set_timeout(self.parent.settings.get_value("PYJAMA", "NOTIFICATION_DELAY")) 146 | self.notify.show() 147 | -------------------------------------------------------------------------------- /plugins/PVC/PVC.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 5 7 | True 8 | 320 9 | 260 10 | normal 11 | False 12 | 13 | 14 | True 15 | vertical 16 | 2 17 | 18 | 19 | True 20 | 21 | 22 | True 23 | True 24 | never 25 | automatic 26 | in 27 | 28 | 29 | True 30 | True 31 | False 32 | word 33 | fill 34 | 10 35 | 10 36 | False 37 | 38 | 39 | 40 | 41 | 0 42 | 43 | 44 | 45 | 46 | True 47 | 10 48 | 10 49 | start 50 | 51 | 52 | gtk-ok 53 | True 54 | True 55 | True 56 | True 57 | top 58 | 59 | 60 | False 61 | False 62 | 0 63 | 64 | 65 | 66 | 67 | gtk-refresh 68 | True 69 | True 70 | True 71 | top 72 | 73 | 74 | False 75 | False 76 | 1 77 | 78 | 79 | 80 | 81 | gtk-preferences 82 | True 83 | True 84 | True 85 | True 86 | top 87 | 88 | 89 | False 90 | False 91 | 20 92 | 2 93 | 94 | 95 | 96 | 97 | False 98 | False 99 | 1 100 | 101 | 102 | 103 | 104 | 1 105 | 106 | 107 | 108 | 109 | True 110 | end 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | False 120 | end 121 | 0 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /plugins/lastfm/__init__.py.THIS: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | 32 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 33 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 34 | 35 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 36 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 37 | 38 | 39 | # login to last.fm 40 | try: 41 | # pyjama has own last.fm clien id 'pyj' 42 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 43 | self.scrobbler.login(self.login, self.password) 44 | except Exception, e: 45 | logging.error(e) 46 | 47 | self.scrobbler = None 48 | raise 49 | 50 | logging.debug('last.fm plugin loaded') 51 | 52 | 53 | def ev_nowplaying(self,track): 54 | """ for sending now playing notification to last.fm """ 55 | logging.debug('nowplaying: %s' % track) 56 | 57 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 58 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 59 | logging.warn('cat\' send nowplaying info to last.fm') 60 | else: 61 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 62 | else: 63 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 64 | 65 | def ev_scrobble(self,track): 66 | """ for scrobbling to last.fm """ 67 | logging.debug('track: %s' % track) 68 | 69 | 70 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 71 | try: 72 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 73 | except Exception, e: 74 | logging.error(e) 75 | raise 76 | 77 | if not self.scrobbler.flush(): 78 | logging.warn('last.fm plugin: can\'t scrobble song') 79 | else: 80 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 81 | 82 | 83 | 84 | else: 85 | logging.debug('song doesn\' scrobbled - scrobbling is off') 86 | 87 | 88 | 89 | 90 | class Preferences(): 91 | ## Preferences Constructor 92 | # @param self Object Pointer 93 | # @param pyjama Again we have a pyjama object reference passed to our class 94 | def __init__(self, pyjama): 95 | # get settings 96 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 97 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 98 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 99 | 100 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 101 | 102 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 103 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 104 | dialog.set_title(_("last.fm Plugin Preferences")) 105 | dialog.set_default_size(100,100) 106 | 107 | hbox = gtk.HBox() 108 | dialog.vbox.pack_start(hbox, False, True) 109 | hbox.show() 110 | 111 | hbox2 = gtk.HBox() 112 | dialog.vbox.pack_start(hbox2, False, True) 113 | hbox2.show() 114 | 115 | 116 | # scrobble check button 117 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 118 | check.set_active(scrobble_value) 119 | dialog.vbox.pack_start(check, False, True) 120 | 121 | # login field 122 | llabel=gtk.Label(_('Login:')) 123 | hbox.pack_start(llabel, False, True) 124 | 125 | login = gtk.Entry(max=0) 126 | login.set_text(login_value) 127 | hbox.pack_end(login, False, True) 128 | 129 | # password field 130 | plabel=gtk.Label(_('Password:')) 131 | hbox2.pack_start(plabel, False, True) 132 | 133 | password = gtk.Entry(max=0) 134 | password.set_visibility(False) 135 | password.set_text(pass_value) 136 | 137 | password.set_visibility(False) 138 | 139 | hbox2.pack_end(password, False, True) 140 | 141 | dialog.show_all() 142 | result = dialog.run() 143 | dialog.destroy() 144 | # set new settings 145 | if result == -3:#gtk.RESPONSE_OK: 146 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 147 | logging.debug('new login: %s' % login.get_text()) 148 | 149 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 150 | logging.debug('new pass: %s' % password.get_text()) 151 | 152 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 153 | logging.debug('new scrobble vaule: %s' % check.get_active()) 154 | 155 | if check.get_active(): 156 | try: 157 | # pyjama has own last.fm clien id 'pyj' 158 | scrobbler.login(str(login.get_text()), str(password.get_text()), client=('pyj','0.3')) 159 | except Exception, e: 160 | logging.error(e) 161 | #raise 162 | 163 | 164 | -------------------------------------------------------------------------------- /plugins/librefm/__init__.py.THIS: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging, os, urllib2, urllib 3 | from time import time 4 | logging.basicConfig(level=logging.DEBUG) 5 | 6 | try: 7 | from scrobbler import Scrobbler 8 | except: 9 | logging.error('scrobbler not found') 10 | raise 11 | 12 | try: 13 | import gtk 14 | except: 15 | logging.error('gtk not found') 16 | raise 17 | 18 | try: 19 | # for python 2.6 20 | from hashlib import md5 21 | except ImportError: 22 | from md5 import md5 23 | 24 | class main(): 25 | ## The Constructor 26 | # @param self Object pointer 27 | # @param pyjama Reference to the pyjama object 28 | def __init__(self, pyjama): 29 | self.pyjama = pyjama 30 | self.Events = self.pyjama.Events 31 | 32 | self.login=self.pyjama.settings.get_value('LASTFM','LOGIN') 33 | self.password=self.pyjama.settings.get_value('LASTFM','PASS') 34 | 35 | self.Events.connect_event("nowplaying", self.ev_nowplaying) 36 | self.Events.connect_event('scrobble_to_lastfm', self.ev_scrobble) 37 | 38 | 39 | # login to last.fm 40 | try: 41 | # pyjama has own last.fm clien id 'pyj' 42 | self.scrobbler=Scrobbler(client=('pyj','0.3')) 43 | self.scrobbler.login(self.login, self.password) 44 | except Exception, e: 45 | logging.error(e) 46 | 47 | self.scrobbler = None 48 | raise 49 | 50 | logging.debug('last.fm plugin loaded') 51 | 52 | 53 | def ev_nowplaying(self,track): 54 | """ for sending now playing notification to last.fm """ 55 | logging.debug('nowplaying: %s' % track) 56 | 57 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 58 | if not self.scrobbler.now_playing(track['artist_name'], track['name'], album=track['album_name'], length=track['duration']): 59 | logging.warn('cat\' send nowplaying info to last.fm') 60 | else: 61 | logging.info('nowplaying %s - %s send to last.fm' % (track['artist_name'], track['name'])) 62 | else: 63 | logging.debug('nowplaying info doesn\'t send - scrobbling is off') 64 | 65 | def ev_scrobble(self,track): 66 | """ for scrobbling to last.fm """ 67 | logging.debug('track: %s' % track) 68 | 69 | 70 | if self.pyjama.settings.get_value('LASTFM','SCROBBLING'): 71 | try: 72 | self.scrobbler.submit(track['artist_name'],track['name'],int(time()),length=track['duration']) 73 | except Exception, e: 74 | logging.error(e) 75 | raise 76 | 77 | if not self.scrobbler.flush(): 78 | logging.warn('last.fm plugin: can\'t scrobble song') 79 | else: 80 | logging.info('song %s - %s send to last.fm' % (track['artist_name'], track['name'])) 81 | 82 | 83 | 84 | else: 85 | logging.debug('song doesn\' scrobbled - scrobbling is off') 86 | 87 | 88 | 89 | 90 | class Preferences(): 91 | ## Preferences Constructor 92 | # @param self Object Pointer 93 | # @param pyjama Again we have a pyjama object reference passed to our class 94 | def __init__(self, pyjama): 95 | # get settings 96 | login_value=pyjama.settings.get_value('LASTFM','LOGIN','login') 97 | pass_value=pyjama.settings.get_value('LASTFM','PASS', 'password') 98 | scrobble_value=pyjama.settings.get_value('LASTFM','SCROBBLING',False) 99 | 100 | logging.debug('settings on start: %s:%s %s' % (login_value,pass_value,str(scrobble_value))) 101 | 102 | dialog = gtk.Dialog(buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 103 | gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 104 | dialog.set_title(_("last.fm Plugin Preferences")) 105 | dialog.set_default_size(100,100) 106 | 107 | hbox = gtk.HBox() 108 | dialog.vbox.pack_start(hbox, False, True) 109 | hbox.show() 110 | 111 | hbox2 = gtk.HBox() 112 | dialog.vbox.pack_start(hbox2, False, True) 113 | hbox2.show() 114 | 115 | 116 | # scrobble check button 117 | check = gtk.CheckButton(_("Scrobble to last.fm?")) 118 | check.set_active(scrobble_value) 119 | dialog.vbox.pack_start(check, False, True) 120 | 121 | # login field 122 | llabel=gtk.Label(_('Login:')) 123 | hbox.pack_start(llabel, False, True) 124 | 125 | login = gtk.Entry(max=0) 126 | login.set_text(login_value) 127 | hbox.pack_end(login, False, True) 128 | 129 | # password field 130 | plabel=gtk.Label(_('Password:')) 131 | hbox2.pack_start(plabel, False, True) 132 | 133 | password = gtk.Entry(max=0) 134 | password.set_visibility(False) 135 | password.set_text(pass_value) 136 | 137 | password.set_visibility(False) 138 | 139 | hbox2.pack_end(password, False, True) 140 | 141 | dialog.show_all() 142 | result = dialog.run() 143 | dialog.destroy() 144 | # set new settings 145 | if result == -3:#gtk.RESPONSE_OK: 146 | pyjama.settings.set_value('LASTFM','LOGIN', str(login.get_text())) 147 | logging.debug('new login: %s' % login.get_text()) 148 | 149 | pyjama.settings.set_value('LASTFM','PASS',str(password.get_text())) 150 | logging.debug('new pass: %s' % password.get_text()) 151 | 152 | pyjama.settings.set_value('LASTFM','SCROBBLING',str(check.get_active())) 153 | logging.debug('new scrobble vaule: %s' % check.get_active()) 154 | 155 | if check.get_active(): 156 | try: 157 | # pyjama has own last.fm clien id 'pyj' 158 | scrobbler.login(str(login.get_text()), str(password.get_text()), client=('pyj','0.3')) 159 | except Exception, e: 160 | logging.error(e) 161 | #raise 162 | 163 | 164 | --------------------------------------------------------------------------------