dbthreaded.py

00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 
00004 # ----------------------------------------------------------------------------
00005 # pyjama - python jamendo audioplayer
00006 # Copyright (c) 2008 Daniel Nögel
00007 #
00008 # This program is free software: you can redistribute it and/or modify
00009 # it under the terms of the GNU General Public License as published by
00010 # the Free Software Foundation, either version 3 of the License, or
00011 # (at your option) any later version.
00012 #
00013 # This program is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 # You should have received a copy of the GNU General Public License
00018 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 # ----------------------------------------------------------------------------
00020 
00021 ## @package clDB
00022 # clDB holds database related functions
00023 
00024 
00025 import os, sys
00026 import time
00027 try:
00028     from pysqlite2 import dbapi2 as sqlite3
00029 except ImportError:
00030     import sqlite3
00031 
00032 import Queue, thread
00033 from threading import Thread
00034 
00035 ####
00036 from modules import functions
00037 from modules.clGstreamer010 import Track
00038 from modules.errors import DatabaseQueryException
00039 
00040 ConnectCmd = "connect"
00041 SqlCmd = "SQL"
00042 StopCmd = "stop"
00043 
00044 class Query:
00045     def __init__(self, cmd=None, params=[]):
00046         if cmd is None: cmd = SqlCmd
00047         self.cmd = cmd
00048         self.params = params
00049 
00050 _threadex_settings = thread.allocate_lock()
00051 qthreads_settings = 0
00052 sqlqueue_settings = Queue.Queue()
00053 class SettingsThread(Thread):
00054     def __init__(self, path, nr):
00055         Thread.__init__(self)
00056         self.path = path
00057         self.nr = nr
00058     def run(self):
00059         global qthreads_settings
00060         con = sqlite3.connect(self.path)
00061         cur = con.cursor()
00062         while True:
00063             s = sqlqueue_settings.get()
00064             if "print-queries" in sys.argv:
00065                 print "Conn %d -> %s -> %s" % (self.nr, s.cmd, s.params)
00066             if s.cmd == SqlCmd:
00067                 commitneeded = False
00068                 res = []
00069 #               s.params is a list to bundle statements into a "transaction"
00070                 for sql in s.params:
00071                     error = False
00072                     inst = None
00073                     try:
00074                         if type(sql) == type(()):
00075                             cur.execute(sql[0],sql[1])
00076                         else:
00077                             cur.execute(sql)# [0],sql[1]
00078                     except Exception, inst:
00079                         error = True
00080                     if not sql.upper().startswith("SELECT"): 
00081                         commitneeded = True
00082                     if not error:
00083                         try:
00084                             for row in cur.fetchall(): res.append(row)
00085                         except Exception, inst:
00086                             error = True
00087                 if not error:
00088                     try:
00089                         if commitneeded: con.commit()
00090                     except Exception, inst:
00091                         error = True
00092                 if not error:
00093                     s.resultqueue.put(res)
00094                 else:
00095                     error = DatabaseQueryException()
00096                     error.inst = inst
00097                     s.resultqueue.put(error)
00098             else:
00099                 _threadex_settings.acquire()
00100                 qthreads_settings -= 1
00101                 _threadex_settings.release()
00102 #               allow other threads to stop
00103                 sqlqueue_settings.put(s)
00104                 s.resultqueue.put(None)
00105                 break
00106 
00107 _threadex_db = thread.allocate_lock()
00108 qthreads_db = 0
00109 sqlqueue_db = Queue.Queue()
00110 class DBThread(Thread):
00111     def __init__(self, path, nr):
00112         Thread.__init__(self)
00113         self.path = path
00114         self.nr = nr
00115     def run(self):
00116         global qthreads_db
00117         con = sqlite3.connect(self.path)
00118         cur = con.cursor()
00119         while True:
00120             s = sqlqueue_db.get()
00121             if "print-queries" in sys.argv:
00122                 print "Conn %d -> %s -> %s" % (self.nr, s.cmd, s.params)
00123             if s.cmd == SqlCmd:
00124                 commitneeded = False
00125                 res = []
00126 #               s.params is a list to bundle statements into a "transaction"
00127                 for sql in s.params:
00128                     cur.execute(sql)# [0],sql[1]
00129                     if not sql.upper().startswith("SELECT"): 
00130                         commitneeded = True
00131                     for row in cur.fetchall(): res.append(row)
00132                 if commitneeded: con.commit()
00133                 s.resultqueue.put(res)
00134             else:
00135                 _threadex_db.acquire()
00136                 qthreads_db -= 1
00137                 _threadex_db.release()
00138 #               allow other threads to stop
00139                 sqlqueue_db.put(s)
00140                 s.resultqueue.put(None)
00141                 break
00142 
00143 ## Settings Database Class
00144 # This settings-class is going to become
00145 # a more powerfull settings interface than
00146 # the current ConfigParser is.
00147 # Of course you can still use the ConfigParser
00148 # but have in mind, that this class also allows
00149 # you to have own tables and real db queries.
00150 ## \todo 
00151 # - Implementation
00152 class DB_Settings():
00153     ## The Constructor
00154     # @param self The Object pointer
00155     # @param pyjama Reference to pyjama
00156     def __init__(self, pyjama):
00157         ## Reference to pyjama
00158         self.pyjama = pyjama
00159         ## Database file
00160         self.db = os.path.join(functions.preparedirs(), "settings.db")
00161         ## Holds the databse connection
00162         self.connection = None
00163 
00164         self.query_counter = 0
00165 
00166         if not os.path.exists(self.db):
00167             self.open() 
00168             self.create_database()
00169         else:
00170             self.open() 
00171 
00172     ## Set a option's value
00173     # @param self The Object pointer
00174     # @param section The table to write to
00175     # @param option The option as string
00176     # @param value The value to set as string
00177     # @return bool
00178     def set_value(self, section, option, value, table="settings"):
00179         option = str(option).replace("'", "''")
00180 
00181         sql = "SELECT COUNT(*) FROM '%s' WHERE section='%s' and option='%s'" % (table, section, option)
00182         ret = self.query(sql)
00183 
00184         if ret[0][0] == 0:
00185             sql = "INSERT INTO '%s' (section, option, value) values('%s', '%s', '%s')"% (table, section, option, value)
00186         else:
00187             sql = "UPDATE '%s' SET value='%s' WHERE section='%s' and option='%s'"% (table, value, section, option)
00188 
00189         ret = self.query(sql)
00190 
00191         return ret
00192 
00193     def increase_value(self, section, option, table="settings"):
00194         option = str(option).replace("'", "''")
00195         sql = "SELECT value FROM %s WHERE section='%s' and option='%s'" % (table, section, option)
00196         ret = self.query(sql)
00197 
00198         if ret == []:
00199             sql = "INSERT INTO %s (section, option, value) values('%s', '%s', '1')" % (table, section, option)
00200         else:
00201             sql = "UPDATE %s SET value=value+1 WHERE section='%s' and option='%s'" % (table, section, option)
00202 
00203         ret = self.query(sql)
00204 
00205         return ret
00206 
00207     ## Reads a value from an option
00208     # @param self The Object pointer
00209     # @param section The table to read from
00210     # @param option An option as string
00211     # @param default A default value
00212     # @return The option's value or default if section or option do not exist
00213     def get_value(self, section, option, default=None, table="settings"):
00214         option = str(option).replace("'", "''")
00215         
00216         sql = "SELECT value FROM %s WHERE section='%s' and option='%s'" % (table, section, option)
00217         ret = self.query(sql)
00218 
00219         if ret == [] or ret == -1: 
00220             return default
00221         else:
00222             if len(ret[0]) == 1: 
00223                 return ret[0][0]
00224             else:
00225                 return ret[0]
00226 
00227 #    def create_table(self, option):
00228 #        sql = """
00229 #        CREATE TABLE %s (
00230 #          uid INTEGER PRIMARY KEY,
00231 #          option INTEGER,
00232 #          value INTEGER
00233 #        )
00234 #        """ % option
00235 #        self.connection.execute(sql)
00236 #        self.connection.commit()
00237 
00238     def create_table(self, table_name):
00239         sql = "select count(name) from sqlite_master where name = '%s'" % table_name
00240         ret = self.query(sql)
00241 
00242         if ret[0][0] == 0:
00243             sql = """
00244             CREATE TABLE %s (
00245               uid INTEGER PRIMARY KEY,
00246               section STRING,
00247               option STRING,
00248               value string
00249             )
00250             """ % table_name
00251             ret = self.query(sql)
00252             return "created"
00253         else:
00254             return "existant"
00255 
00256     ## Create Database if not existant
00257     # @param self The Object Pointer
00258     def create_database(self):
00259         print("Creating settings database 'settings.db'")
00260 
00261 #        sql = """
00262 #        CREATE TABLE tracks (
00263 #          uid INTEGER PRIMARY KEY,
00264 #          id INTEGER,
00265 #          listencounter INTEGER
00266 #        )
00267 #        """
00268 #        self.connection.execute(sql)
00269 #        self.connection.commit()
00270 
00271         sql = """
00272         CREATE TABLE settings (
00273           uid INTEGER PRIMARY KEY,
00274           section STRING,
00275           option STRING,
00276           value string
00277         )
00278         """
00279         ret = self.query(sql)
00280 
00281     ## Open Database connection
00282     # @param self The Object pointer
00283     def open(self):
00284         global qthreads_settings
00285         _threadex_settings.acquire()
00286         qthreads_settings += 1
00287         _threadex_settings.release()
00288         wrap = SettingsThread(self.db, qthreads_settings)
00289         wrap.start()
00290 
00291     def quit(self):
00292         s = Query(StopCmd)
00293         s.resultqueue = Queue.Queue()
00294         sqlqueue_settings.put(s)
00295 #       sleep until all threads are stopped
00296         while qthreads_settings > 0: time.sleep(0.1)
00297 
00298 
00299 
00300     ## Close Database connection
00301     # @param self The Object poi
00302     def close(self):
00303         self.connection.close()
00304 
00305     ## Queries the SQLite database
00306     # @param self The Object pointer
00307     # @param query A SQL Query
00308     def query(self, query):
00309         s = Query(None, [query])
00310         s.resultqueue = Queue.Queue()
00311         sqlqueue_settings.put(s)
00312         self.query_counter += 1
00313         ret = s.resultqueue.get()
00314 
00315         if isinstance(ret, DatabaseQueryException):
00316             desc = "There was an error while querying the settings database:\n"
00317             desc += str(ret.inst)
00318             self.pyjama.Events.raise_event("error", None, desc)
00319             return -1
00320         else:
00321             return ret
00322 
00323         try:
00324             cur = self.connection.cursor()
00325             cur.execute(query)
00326             rows = cur.fetchall()
00327             return rows
00328         except Exception, inst:
00329             desc = "There was an error while querying the settings database"
00330             self.pyjama.Events.raise_event("error", inst, desc)
00331             return -1
00332 
00333 
00334 ## Main Database Class
00335 #
00336 # Holds methods to search the databse
00337 # for albums, artists, tracks and
00338 # related informations
00339 class DB():
00340     ## The constructor
00341     # @param self The object pointer
00342     # @param par Pyjama reference
00343     def __init__(self, par):
00344         ## reference to pyjama
00345         self.parent = par
00346         ## pyjama's home directory
00347         self.home=functions.preparedirs()
00348         ## pyjama's database file
00349         self.db = os.path.join(self.home, "pyjama.db")
00350 
00351         self.tracks, self.albums, self.artists = 0, 0, 0
00352         self.query_counter = 0
00353 
00354         ## stores results for threaded queries
00355         self.results = {}
00356 
00357         # not implemented, yet
00358         self.queue = []
00359 
00360         ## holds the connection to our database
00361         self.connection = None
00362 
00363         self.open()
00364 
00365         self.database_ok = True
00366         if not os.path.exists(os.path.join(functions.preparedirs(),"pyjama.db")):
00367             self.database_ok = False
00368         else:
00369             sql = "select count(name) from sqlite_master where name = 'albums' or name = 'artists' or name = 'tracks'" 
00370             try:
00371                 tablecount =  self.__query(sql)
00372                 if tablecount[0][0] < 3:
00373                     print("Some tables in the database seems to be missing")
00374                     print ("Marking the database as corrupt")
00375                     self.database_ok = False
00376             except Exception:
00377                 self.database_ok = False
00378 
00379         if self.database_ok:
00380             try:
00381                 ## number of tracks in the database
00382                 self.tracks = self.__query("SELECT COUNT (*) FROM tracks WHERE 1")[0][0]
00383                 ## number of albums in the database
00384                 self.albums = self.__query("SELECT COUNT (*) FROM albums WHERE 1")[0][0]
00385                 ## number of artists in the database
00386                 self.artists = self.__query("SELECT COUNT (*) FROM artists WHERE 1")[0][0]
00387             except TypeError, inst:
00388                 self.database_ok = False
00389                 desc =  "\n\n+-------------------------------------------------------+\n"
00390                 desc += "|          A neccessary table wasn't found.             |\n"
00391                 desc += "| Pyjama will now download and convert the needed files |\n"
00392                 desc += "|         If any problems occur, run 'pyjama -u'        |\n"
00393                 desc += "+-------------------------------------------------------+"
00394                 #self.parent.Events.raise_event("error", inst, desc)
00395                 print desc
00396     #            sys.exit(1)
00397 
00398             if self.tracks < 135000 or self.albums < 19000 or self.artists < 10000:
00399                 print ("There seem to be a lot of entries missing in the database")
00400                 print ("Marking the database as corrupt")
00401                 self.database_ok = False
00402 
00403         # run this in its own thread
00404 #        self.watch_queue()
00405 
00406 
00407     ## Opens a database connection
00408     # @return None
00409     # @param self The Object pointer
00410     def open(self):
00411         global qthreads_db
00412         _threadex_db.acquire()
00413         qthreads_db += 1
00414         _threadex_db.release()
00415         wrap = DBThread(self.db, qthreads_db)
00416         wrap.start()
00417 
00418     ## Closes the database connection
00419     # @return None
00420     # @param self The Object pointer
00421     def close(self):
00422         self.connection.close()
00423 
00424     def quit(self):
00425         s = Query(StopCmd)
00426         s.resultqueue = Queue.Queue()
00427         sqlqueue_db.put(s)
00428 #       sleep until all threads are stopped
00429         while qthreads_db > 0: time.sleep(0.1)
00430 
00431     ## queries the database
00432     # @return list
00433     # @param self The Object pointer
00434     # @param query a string with a sql command
00435     def query(self, query):
00436         if not self.parent.window.check_alldone():
00437             self.parent.Events.raise_event("error", None, "You are not allowed to query the database before the main-module was loaded succesfully. If you are writing a plugin, please connect to the 'alldone' event.")
00438             return -2
00439 
00440         s = Query(None, [query])
00441         s.resultqueue = Queue.Queue()
00442         sqlqueue_db.put(s)
00443         self.query_counter += 1
00444         return s.resultqueue.get()
00445 
00446 
00447 #        try:
00448 #            self.open()
00449 #            cur = self.connection.cursor()
00450 #            cur.execute(query)
00451 #            rows = cur.fetchall()
00452 #       
00453 #            self.close()
00454 #        
00455 #            return rows
00456 #        except Exception, inst:
00457 #            desc = "There was an error while querying the database"
00458 #            self.parent.Events.raise_event("error", inst, desc)
00459 #            return -1
00460 
00461     ## Private methode
00462     # Use query() for your plugins
00463     def __query(self, query):
00464         s = Query(None, [query])
00465         s.resultqueue = Queue.Queue()
00466         sqlqueue_db.put(s)
00467         self.query_counter += 1
00468         return s.resultqueue.get()
00469 
00470 #        try:
00471 #            self.open()
00472 #            cur = self.connection.cursor()
00473 #            cur.execute(query)
00474 #            rows = cur.fetchall()
00475 #       
00476 #            self.close()
00477 #        
00478 #            return rows
00479 #        except Exception, inst:
00480 #            desc = "There was an error while querying the database"
00481 #            self.parent.Events.raise_event("error", inst, desc)
00482 #            return -1
00483 
00484 #    ## add a query to the queue
00485 #    # /todo Rename this fkt to query()
00486 #    def query_to_come(self, query):
00487 #        self.query.insert(0, query)
00488 
00489 #    def watch_queue(self):
00490 #        # run this in a thread
00491 #        while 1:
00492 #            while len(self.queue) > 0:
00493 #                query = queue.pop()
00494 #                self.__do_query()
00495 
00496 #    ## queries the database - never call this function directly
00497 #    # use query() instead
00498 #    # @return list
00499 #    # @param self The Object pointer
00500 #    # @param query a string with a sql command
00501 #    def __do_query(self, query):
00502 #        self.query_counter += 1
00503 
00504 #        try:
00505 #            self.open()
00506 #            cur = self.connection.cursor()
00507 #            cur.execute(query)
00508 #            rows = cur.fetchall()
00509 #       
00510 #            self.close()
00511 #        
00512 #            return rows
00513 #        except Exception, inst:
00514 #            desc = "There was an error while querying the database"
00515 #            self.parent.Events.raise_event("error", inst, desc)
00516 #            return -1
00517 
00518     ## get several informations for a spicific artist-id
00519     # @return dictionary
00520     # @param self The Object pointer
00521     # @param id An artist id as int or string
00522     # @param thread_id If this function is called by a thread,
00523     # this is the thread's id
00524     def artistinfos(self, id, thread_id = 0):
00525         sql = """
00526             SELECT
00527                 artists.name, artists.country, artists.image, artists.url, artists.id, albums.name, albums.id, artists.albumcount
00528             FROM
00529                 artists, albums
00530             WHERE
00531                 artists.id=%s and albums.artist_id=artists.id
00532             """ % str(id)
00533         ret = self.query(sql)
00534         counter = 0
00535         artist = {}
00536         for info in ret:
00537             artist[counter] = {}
00538             artist[counter]['artist_name'] = info[0]
00539             artist[counter]['artist_country'] = info[1]
00540             artist[counter]['artist_image'] = info[2]
00541             artist[counter]['artist_url'] = info[3]
00542             artist[counter]['artist_id'] = info[4]
00543             artist[counter]['album_name'] = info[5]
00544             artist[counter]['album_id'] = info[6]
00545             artist[counter]['artist_albumcount'] = info[7]
00546             counter += 1
00547         self.results[thread_id]=artist
00548         return artist
00549 
00550     def multiple_albuminfos(self, ids):
00551         album_string = "("
00552         for album in ids:
00553             album_string += " albums.id=%s or" % album
00554         album_string = album_string[:-3] + ") and albums.artist_id=artists.id"
00555 
00556         sql = """
00557             SELECT
00558                 albums.id, albums.name, artists.id, artists.name
00559             FROM
00560                 albums, artists
00561             WHERE
00562                 %s
00563             """ % album_string
00564 
00565         ret = self.query(sql)
00566         return ret
00567 
00568 #    ## get track-informations for several track-ids
00569 #    # @return dictionary
00570 #    # @param self The Object pointer
00571 #    # @param ids A list of ids as strings
00572 #    def multiple_albumtracks(self, ids):
00573 #        where_clause = ") OR ("
00574 #        strings = []
00575 #        for id in ids:
00576 #            strings.append( "tracks.albumID='%s'" % id)
00577 #        where_clause = "(" + where_clause.join(strings) + ")"
00578 #        sql = """
00579 #            SELECT
00580 #                tracks.dispname, tracks.lengths, tracks.trackno, tracks.id, albums.id, albums.dispname, artists.id, artists.dispname, artists.name
00581 #            FROM
00582 #                albums, artists
00583 #            INNER JOIN tracks ON albums.artistID=tracks.albumID
00584 #            """# % where_clause #order by tracks.albumID
00585 #        ret = self.query(sql)
00586 #        counter = 0
00587 #        tracks={}
00588 #        for track in ret:
00589 #            tracks[counter] = {}
00590 #            #tracks[counter]['uid'] = time()
00591 #            tracks[counter]['dispname'] = track[0]
00592 #            tracks[counter]['lengths'] = track[1]
00593 #            tracks[counter]['trackno'] = track[2]
00594 #            tracks[counter]['id'] = track[3]
00595 #            tracks[counter]['album_id'] = track[4]
00596 #            tracks[counter]['album_dispname'] = track[5]
00597 #            tracks[counter]['artist_id'] = track[6]
00598 #            tracks[counter]['artist_dispname'] = track[7]
00599 #            tracks[counter]['artist_name'] = track[8]
00600 ##            tracks[counter]['stream'] = "query" 
00601 #            tracks[counter]['stream'] = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (track[3], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00602 #            counter += 1
00603 #        return tracks
00604 
00605     ## Get trackinfos for a list of tracks
00606     # @return dictionary
00607     # @param self The Object pointer
00608     # @param tracks a list of strings 
00609     def get_multiple_trackinfos(self, tracks):
00610         track_string = "("
00611         for track in tracks:
00612             track_string += " tracks.id=%s or" % track
00613         track_string = track_string[:-3] + ") and tracks.artist_id=artists.id and albums.id=tracks.album_id"
00614         sql = """
00615             SELECT
00616                 tracks.name, tracks.duration, tracks.numalbum, tracks.license, tracks.album_id, tracks.artist_id, artists.name, albums.name, tracks.uid, tracks.id3genre, tracks.id
00617             FROM
00618                 tracks, artists, albums
00619             WHERE 
00620                 %s
00621             """ % track_string
00622 
00623         ret = self.query(sql)
00624 
00625         tracks=[]
00626         for track in ret:
00627             tr = Track()
00628             tr.name = track[0]
00629             tr.duration = track[1]
00630             tr.numalbum = track[2]
00631             tr.license = track[3]
00632             tr.album_id = track[4]
00633             tr.artist_id = track[5]
00634             tr.artist_name = track[6]
00635             tr.album_name = track[7]
00636             tr.uid = track[8]
00637             tr.id3genre = track[9]
00638             tr.id = track[10]
00639             tr.stream = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (track[10], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00640             tracks.append(tr)
00641         return tracks
00642 
00643     ## Get trackinfos for a single track
00644     # @return dictionary
00645     # @param self The Object pointer
00646     # @param trackid a track-id as string or int
00647     def get_trackinfos2(self, trackid):
00648         sql = """
00649             SELECT
00650                 tracks.name, tracks.duration, tracks.numalbum, tracks.license, tracks.album_id, tracks.artist_id, artists.name, albums.name, tracks.uid, tracks.id3genre, tracks.id
00651             FROM
00652                 tracks, albums, artists
00653             WHERE
00654                 tracks.id=%s and albums.id=tracks.album_id and artists.id=tracks.artist_id
00655             """ % str(trackid)
00656         ret = self.query(sql)
00657         if ret == []:
00658             return []
00659         ret = ret[0]
00660         tr = Track()
00661         tr.name = ret[0]
00662         tr.duration = ret[1]
00663         tr.numalbum = ret[2]
00664         tr.license = ret[3]
00665         tr.album_id = ret[4]
00666         tr.artist_id = ret[5]
00667         tr.artist_name = ret[6]
00668         tr.album_name = ret[7]
00669         tr.uid = ret[8]
00670         tr.id3genre = ret[9]
00671         tr.id = ret[10]
00672         tr.stream = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (ret[10], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00673 #        tracks.append(tr)
00674         return tr
00675 
00676   
00677         
00678 #http://api.jamendo.com/get2/track_name+track_duration+track_url+license_url+album_id+album_name+artist_id+artist_idstr+artist_name/track/jsonpretty/album_artist/
00679 
00680     ## Get all artist's tracks
00681     # @return dictionary
00682     # @param self The Object pointer
00683     # @param id an artist's id as string or int
00684     def artisttracks(self, id):
00685         sql = """
00686             SELECT
00687                 tracks.name, tracks.duration, tracks.numalbum, tracks.license, tracks.album_id, tracks.artist_id, artists.name, albums.name, tracks.uid, tracks.id3genre, tracks.id
00688             FROM
00689                 tracks, albums, artists
00690             WHERE
00691                 tracks.album_id=albums.id and tracks.artist_id=%s and albums.artist_id=%s and artists.id=tracks.artist_id
00692             """ % (str(id), str(id))
00693         ret = self.query(sql)                
00694         tracks=[]
00695         for track in ret:
00696             tr = Track()
00697             tr.name = track[0]
00698             tr.duration = track[1]
00699             tr.numalbum = track[2]
00700             tr.license = track[3]
00701             tr.album_id = track[4]
00702             tr.artist_id = track[5]
00703             tr.artist_name = track[6]
00704             tr.album_name = track[7]
00705             tr.uid = track[8]
00706             tr.id3genre = track[9]
00707             tr.id = track[10]
00708             tr.stream = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (track[10], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00709             tracks.append(tr)
00710         return tracks
00711 
00712     ## get all tracks of an album
00713     # @return dictionary
00714     # @param self The Object pointer
00715     # @param id an album's id
00716     def albumtracks(self, id):
00717         sql = """
00718             SELECT
00719                 tracks.name, tracks.duration, tracks.numalbum, tracks.license, tracks.album_id, tracks.artist_id, artists.name, albums.name, tracks.uid, tracks.id3genre, tracks.id
00720             FROM
00721                 tracks, albums, artists
00722             WHERE
00723                 tracks.album_id=%s and albums.id=%s and artists.id=albums.artist_id
00724             """ % (str(id), str(id))
00725         ret = self.query(sql)
00726         tracks=[]
00727         for track in ret:
00728             tr = Track()
00729             tr.name = track[0]
00730             tr.duration = track[1]
00731             tr.numalbum = track[2]
00732             tr.license = track[3]
00733             tr.album_id = track[4]
00734             tr.artist_id = track[5]
00735             tr.artist_name = track[6]
00736             tr.album_name = track[7]
00737             tr.uid = track[8]
00738             tr.id3genre = track[9]
00739             tr.id = track[10]
00740             tr.stream = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (track[10], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00741             tracks.append(tr)
00742         return tracks
00743 
00744     ## search tags
00745     # @return dictionary
00746     # @param self The Object pointer
00747     # @param string a string to search for
00748     def Search_tag(self, string):
00749     
00750         sql = """
00751             SELECT
00752                 albums.name, albums.id, artists.name, artists.id
00753             FROM
00754                 albums, artists, tags
00755             WHERE
00756                 tags.idstr='""" + string + """' and albums.id=tags.album_id LIMIT """ + str(self.parent.settings.get_value("PERFORMANCE", "db_search_limit"))
00757         ret = self.query(sql)
00758         tags = {}
00759         counter = 0
00760         for tag in ret:
00761             tags[counter] = {}
00762             tags[counter]['album_name'] = tag[0]
00763             tags[counter]['album_id'] = tag[1]
00764             tags[counter]['artist_name'] = tag[2]
00765             tags[counter]['artist_id'] = tag[3]
00766             counter += 1
00767         print tags
00768         return tags
00769 
00770 
00771     ## Search tracks
00772     # @return dictionary
00773     # @param self The Object pointer
00774     # @param string a string to search for
00775     def search_track(self, string):
00776     
00777         sql = """
00778             SELECT
00779                 tracks.name, tracks.duration, tracks.numalbum, tracks.id, tracks.license, tracks.id3genre, albums.id, albums.name, artists.id, artists.name, tracks.uid
00780             FROM
00781                 tracks, albums, artists
00782             WHERE
00783                 tracks.name LIKE '%""" + string + """%' and tracks.album_id=albums.id and albums.artist_id=artists.id LIMIT """ + str(self.parent.settings.get_value("PERFORMANCE", "db_search_limit"))
00784         ret = self.query(sql)
00785         tracks=[]
00786         for track in ret:
00787             tr = Track()
00788             tr.name = track[0]
00789             tr.duration = track[1]
00790             tr.numalbum = track[2]
00791             tr.id = track[3]
00792             tr.license = track[4]
00793             tr.id3genre = track[5]
00794             tr.album_id = track[6]
00795             tr.album_name = track[7]
00796             tr.artist_id = track[8]
00797             tr.artist_name = track[9]
00798             tr.uid = track[10]
00799             tr.stream = "http://api.jamendo.com/get2/stream/track/redirect/?id=%i&streamencoding=%s" % (track[3], self.parent.settings.get_value("JAMENDO", "format_stream", "mp31"))
00800             tracks.append(tr)
00801         return tracks
00802 
00803     ## Search artists
00804     # @return dictionary
00805     # @param self The Object pointer
00806     # @param string a string to search for
00807     def search_artist(self, string):
00808         sql = """
00809             SELECT
00810                 artists.name, artists.id
00811             FROM
00812                 artists
00813             WHERE
00814                 artists.name LIKE '%""" + string + """%' LIMIT """ + str(self.parent.settings.get_value("PERFORMANCE", "db_search_limit"))
00815         ret = self.query(sql)
00816         artists = {}
00817         counter = 0
00818         for artist in ret:
00819             artists[counter] = {}
00820             artists[counter]['artist_name'] = artist[0]
00821             artists[counter]['artist_id'] = artist[1]
00822 #            artists[counter]['album_dispname'] = artist[2]
00823 #            artists[counter]['album_id'] = artist[3]
00824             counter += 1
00825         return artists
00826 
00827     ## Search albums
00828     # @return dictionary
00829     # @param self The Object pointer
00830     # @param string a string to search for 
00831     def search_album(self, string):
00832     
00833         sql = """
00834             SELECT
00835                 albums.name, albums.id, artists.name, artists.id
00836             FROM
00837                 albums, artists
00838             WHERE
00839                 albums.name LIKE '%""" + string + """%' and albums.artist_id=artists.id LIMIT """ + str(self.parent.settings.get_value("PERFORMANCE", "db_search_limit"))
00840         ret = self.query(sql)
00841         albums = {}
00842         counter = 0
00843         for album in ret:
00844             albums[counter] = {}
00845             albums[counter]['album_name'] = album[0]
00846             albums[counter]['album_id'] = album[1]
00847             albums[counter]['artist_name'] = album[2]
00848             albums[counter]['artist_id'] = album[3]
00849             counter += 1
00850         return albums
00851 
00852     ## Get an album's tags
00853     # @return list
00854     # @param self The Object pointer
00855     # @param id an album to search for as string or int
00856     def gettags(self, id):
00857         
00858         sql = """
00859             SELECT
00860                 tags
00861             FROM
00862                 albums
00863             WHERE
00864                 id=%s
00865             """ % str(id)
00866         ret = self.query(sql)
00867         return ret
00868 
00869 #    def albuminfos(self, id):
00870 #        strQuery = "track/id/album/data/json/ID?ali=full&ari=full+object&tri=full&item_o=track_no_asc&showhidden=1&shownotmod=1"
00871 #        strQuery = strQuery.replace("ID", str(id))
00872 #        ret = self.__queryold__(strQuery)
00873 #        return ret
00874 
00875 
00876 
00877 
00878 
00879 
00880 
00881 #    def albumtracks(self, id):         
00882 #        ret = self.get("track_id+track_name+track_stream+track_duration+album_name", "track", "album_track/?album_id=" + str(id)+"&streamencoding=ogg2")       
00883 #        return ret
00884 #        
00885 
00886 #    def artistalbums(self, idstr):
00887 #        ret = self.get("album_id+album_name+album_playlist", "artist", "?idstr=" + idstr + "&ali=full")
00888 #        print ret
00889 #        return ret
00890 
00891 #    def artistlist(self):
00892 #        ret =  self.get("id+idstr+name", "artist", "?artist_hasalbums&n=50")
00893 #        return ret
00894 
00895 

Generated on Thu Jun 4 19:08:24 2009 for Pyjama by  doxygen 1.5.8