This file is indexed.

/usr/share/bluemindo/src/common/webservices.py is in bluemindo 0.3-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# -*- coding: utf-8 -*-

# Bluemindo: A really simple but powerful audio player in Python/PyGTK.
# Copyright (C) 2007-2009  Erwan Briand

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation version 3 of the License.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from StringIO import StringIO
from ConfigParser import ConfigParser
from os.path import join, exists
from os import makedirs, remove
from re import compile as re_compile
from base64 import b64decode
from urllib2 import urlopen, Request, quote as urllib_quote, HTTPError
from urllib import urlretrieve
from httplib import BadStatusLine
from threading import Lock
from time import time, sleep

try:
    # Python >= 2.5
    import xml.etree.cElementTree as ElementTree
except ImportError:
    try:
        # Python < 2.5
        from elementtree import ElementTree
    except ImportError:
        raise SystemExit('You need python-elementtree (see the INSTALL file).')

from common.config import ConfigLoader
from common.functions import Functions

class WebServices(object):
    """A class to handles many WebServices."""

    config = ConfigLoader()
    functions = Functions()
    lock = Lock()

    def get_xml(self, url):
        """This function downloads a file and returns an ElementTree object."""
        req = Request(url)
        req_file = urlopen(req)
        content = req_file.read()

        return ElementTree.fromstring(content)

    def get_html(self, url):
        """This function downloads a file and returns its content."""
        req = Request(url)
        req_file = urlopen(req)
        content = req_file.read()

        return content


class LastFm(WebServices):
    """A class for Last.fm."""

    def __init__(self):
        self.api_key = b64decode(self.config.lastfm_key)
        self.api_url = 'http://ws.audioscrobbler.com/2.0/'

    def get_pictures(self, artists):
        """Get a picture for all albums."""
        for artist in artists:
            self.get_artist_picture(artist)
            sleep(2)

    def get_artist_picture(self, artist_name):
        """Get a picture for an artist."""
        url = (self.api_url + '?method=artist.getinfo&artist=%s&api_key=%s' %
              (urllib_quote(str(artist_name)), self.api_key))

        datadir = self.config.datadir
        hash_a = self.functions.get_hash(artist_name, 'picture')
        pictures_dir = join(datadir, 'modules', 'explorer', 'artists')
        artist_file = join(pictures_dir, hash_a)

        self.lock.acquire()
        try:
            if not exists(pictures_dir):
                makedirs(pictures_dir)
        finally:
            self.lock.release()

        if not exists(artist_file):
            try:
                tree = self.get_xml(url)

                artist = tree.find('artist')
                images = artist.getiterator('image')
                for img in images:
                    if img.attrib['size'] == 'large':
                        artist_image = img.text
                        if artist_image is not None:
                            urlretrieve(artist_image, artist_file)
                            return artist_file
            except (BadStatusLine, HTTPError):
                # Service is currently unavailable
                pass


class Amazon(WebServices):
    """A class for Amazon."""

    def __init__(self):
        self.api_key = b64decode(self.config.amazon_key)
        self.api_url = ('http://ecs.amazonaws.com/onca/xml'
                        '?Service=AWSECommerceService'
                        '&SearchIndex=Music&AWSAccessKeyId=')
        self.api_ns = ('{http://webservices.amazon.com/AWSECommerceService/'
                       '2005-10-05}')
        self.api_reg = re_compile('<noscript><div id="imageViewerDiv"><img '
                                 'src="(.*?)" id="prodImage" /></div>'
                                 '</noscript>')

    def get_pictures(self, albums):
        """Get a picture for all albums."""
        for album in albums:
            self.get_album_picture(album[0], album[1])
            sleep(2)

    def get_album_picture(self, artist_name, album_name):
        """Get a picture for an album."""
        datadir = self.config.datadir
        hash_a = self.functions.get_hash(album_name, artist_name)
        pictures_dir = join(datadir, 'modules', 'player', 'covers')
        album_file = join(pictures_dir, hash_a)

        self.lock.acquire()
        try:
            if not exists(pictures_dir):
                makedirs(pictures_dir)
        finally:
            self.lock.release()

        search_keywords = ('%s %s' % (album_name, artist_name))
        url = (self.api_url + '%s&Operation=ItemSearch&Keywords=%s' % (
               self.api_key, urllib_quote(str(search_keywords))))

        if not exists(album_file):
            try:
                tree = self.get_xml(url)

                results = tree.find('%sItems' % self.api_ns)
                items = results.getiterator('%sItem' % self.api_ns)

                for item in items:
                    album_id = item.find('%sASIN' % self.api_ns).text
                    url = ('http://www.amazon.com/gp/product/images'
                           '/%s' % album_id)

                    html = self.get_html(url)

                    for img in self.api_reg.findall(html):
                        urlretrieve(img, album_file)
                        return img
            except HTTPError:
                # Service is currently unavailable
                pass


class Shoutcast(WebServices):
    """A class for Shoutcast Radio."""

    def __init__(self):
        self.api_url = 'http://www.shoutcast.com/sbin/'

    def get_categories(self):
        """Get the list of all categories."""
        tree = self.get_xml(self.api_url + 'newxml.phtml')
        cat = []

        categories = tree.getiterator('genre')
        for category in categories:
            cat.append(category.attrib['name'])

        return cat

    def get_radios_by_category(self, category):
        """Get the list of radios for one category."""
        url = '%snewxml.phtml?genre=%s' % (self.api_url, category)
        tree = self.get_xml(url)
        rad = []

        radios = tree.getiterator('station')
        for radio in radios:
            rad.append((radio.attrib['name'], radio.attrib['id'],
                        radio.attrib['lc']))

        return rad

    def get_radio_url(self, radio_id):
        """Construct the URL of a webradio with its identifier."""
        url = ('%sshoutcast-playlist.pls?rn=%d&file=filename.pls' % (
               self.api_url, int(radio_id)))

        return url

    def get_file_in_pls(self, pls):
        """Get the first file to load in the shoutcast playlist."""
        content = self.get_html(pls)
        output = StringIO(content)

        # Parse the content
        configparser = ConfigParser()
        configparser.readfp(output, None)
        file_url = configparser.get('playlist', 'File1')

        output.close()
        return file_url