root/trunk/radiomate/mysqldao.py @ 42

Revision 42, 41.7 KB (checked in by clauz, 4 years ago)

adding playlist randomization plus small changes

  • Property svn:keywords set to Id
Line 
1# vim:fileencoding=utf-8:nomodified
2# $Id$
3#
4#  Copyright 2010 Claudio Pisa (clauz at ninux dot org)
5#
6#  This file is part of RadioMate
7#
8#  RadioMate 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#  RadioMate 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#
18#  You should have received a copy of the GNU General Public License
19#  along with RadioMate.  If not, see <http://www.gnu.org/licenses/>.
20#
21
22import MySQLdb
23import json
24import logging
25import config
26from mate import *
27from daobase import *
28
29# The MySQL Data Access Objects
30
31class MysqlConnectionManager(RadioMateConnectionManager):
32        "given the right parameters connect to the database"
33        def __init__(self, dbhost, dbuser, dbpassword, database):
34                self.conn = None
35                RadioMateConnectionManager.__init__(self, dbhost, dbuser, dbpassword, database)
36                conn = MySQLdb.connect(
37                                host = self.dbhost, 
38                                user = self.dbuser, 
39                                passwd = self.dbpassword, 
40                                db = self.database
41                                )
42                assert isinstance(conn, MySQLdb.connections.Connection)
43                self.conn = conn
44
45        def __del__(self):
46                if self.conn:
47                        self.conn.close()
48
49        def getMysqlConnection(self):
50                return self.conn
51
52
53class RadioMateParentMysqlDAO(object):
54        "The parent class from which the other classess representing MySQL Database Access Objects (DAOs) inherit"
55        def __init__(self, conn):
56                if isinstance(conn, MysqlConnectionManager):
57                        self.connectionmanager = conn
58                        self.conn = self.connectionmanager.getMysqlConnection()
59                elif isinstance(conn, MySQLdb.connections.Connection):
60                        self.conn = conn
61                else:
62                        raise RadioMateDAOException("Invalid object for MySQL connection: %s", self.conn)
63                self.logger = logging.getLogger("radiomate.mysqldao")
64                logging.basicConfig(filename=config.LOGFILENAME, level=config.LOGGINGLEVEL)
65
66
67class RoleMysqlDAO(RadioMateParentMysqlDAO):
68        "The MySQL Database Access Object for Roles"
69        def __insert(self, roleobject, cursor):
70                insertionstring = """
71                INSERT INTO roles (
72                        rolename,
73                        canManageRoles,
74                        canManageUsers,
75                        canManageAllPlaylists,
76                        canRegisterFiles,
77                        canManageRegisteredFiles,
78                        canManageTimetable,
79                        fixedSlotTimes,
80                        changeTimeBeforeTransmission,
81                        canCreateTestSlot,
82                        fixedSlotTimesList
83                ) VALUES (
84                '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')""" % (
85                        roleobject.rolename,
86                        int(roleobject.canManageRoles),
87                        int(roleobject.canManageUsers),
88                        int(roleobject.canManageAllPlaylists),
89                        int(roleobject.canRegisterFiles),
90                        int(roleobject.canManageRegisteredFiles),
91                        int(roleobject.canManageTimetable),
92                        int(roleobject.fixedSlotTimes),
93                        roleobject.changeTimeBeforeTransmission,
94                        int(roleobject.canCreateTestSlot),
95                        roleobject.fixedSlotTimesList.strip("[]")
96                )
97
98                self.logger.debug(insertionstring)
99                cursor.execute(insertionstring)
100
101        def __getByName(self, rolename, cursor):
102                selectionstring = """
103                SELECT 
104                        rolename,
105                        canManageRoles,
106                        canManageUsers,
107                        canManageAllPlaylists,
108                        canRegisterFiles,
109                        canManageRegisteredFiles,
110                        canManageTimetable,
111                        fixedSlotTimes,
112                        changeTimeBeforeTransmission,
113                        canCreateTestSlot,
114                        fixedSlotTimesList
115                FROM roles
116                WHERE rolename = '%s'""" % rolename
117
118                self.logger.debug(selectionstring)
119                cursor.execute(selectionstring)
120                return cursor.fetchall()
121
122        def __removeByName(self, rolename, cursor):
123                deletionstring = """
124                DELETE FROM roles
125                WHERE rolename = '%s'""" % rolename
126
127                self.logger.debug(deletionstring)
128                cursor.execute(deletionstring)
129       
130        def __getAll(self, cursor):
131                selectionstring = """
132                SELECT 
133                        rolename,
134                        canManageRoles,
135                        canManageUsers,
136                        canManageAllPlaylists,
137                        canRegisterFiles,
138                        canManageRegisteredFiles,
139                        canManageTimetable,
140                        fixedSlotTimes,
141                        changeTimeBeforeTransmission,
142                        canCreateTestSlot,
143                        fixedSlotTimesList
144                FROM roles"""
145
146                self.logger.debug(selectionstring)
147                cursor.execute(selectionstring)
148                return cursor.fetchall()
149
150        def __update(self, roleobject, cursor):
151                updatestring = """
152                UPDATE roles
153                SET
154                        canManageRoles = %d,
155                        canManageUsers = %d,
156                        canManageAllPlaylists = %d,
157                        canRegisterFiles = %d,
158                        canManageRegisteredFiles = %d,
159                        canManageTimetable = %d,
160                        fixedSlotTimes = %d,
161                        changeTimeBeforeTransmission = %d,
162                        canCreateTestSlot= %d,
163                        fixedSlotTimesList = '%s'
164                WHERE rolename = '%s' """ % (
165                        int(roleobject.canManageRoles),
166                        int(roleobject.canManageUsers),
167                        int(roleobject.canManageAllPlaylists),
168                        int(roleobject.canRegisterFiles),
169                        int(roleobject.canManageRegisteredFiles),
170                        int(roleobject.canManageTimetable),
171                        int(roleobject.fixedSlotTimes),
172                        roleobject.changeTimeBeforeTransmission,
173                        int(roleobject.canCreateTestSlot),
174                        roleobject.fixedSlotTimesList.strip("[]"),
175                        roleobject.rolename
176                )
177
178                self.logger.debug(updatestring)
179                cursor.execute(updatestring)
180
181        def insert(self, roleobject):
182                "Create a new Role"
183                try:
184                        cursor = self.conn.cursor()
185                        self.__insert(roleobject, cursor)
186                        self.conn.commit()
187                        cursor.close()
188                        self.logger.debug("Number of role rows inserted: %d" % cursor.rowcount)
189                        return cursor.rowcount
190                except MySQLdb.Error, e:
191                        raise RadioMateDAOException(e.args)
192       
193        def getByName(self, rolename):
194                "Get a Role from its name"
195                try:
196                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
197                        resultdicts = self.__getByName(rolename, cursor)
198                        cursor.close()
199
200                        self.logger.debug("Number of role rows fetched: %d" % len(resultdicts))
201                        assert len(resultdicts) <= 1
202
203                        if len(resultdicts) == 1:
204                                return Role(resultdicts[0])
205                        else:
206                                return None
207                except MySQLdb.Error, e:
208                        raise RadioMateDAOException(e.args)
209
210        def removeByName(self, rolename):
211                "Remove a Role from its name"
212                try:
213                        cursor = self.conn.cursor()
214                        self.__removeByName(rolename, cursor)
215                        self.conn.commit()
216                        cursor.close()
217                        self.logger.debug("Number of role rows deleted: %d" % cursor.rowcount)
218                        return cursor.rowcount
219                except MySQLdb.Error, e:
220                        raise RadioMateDAOException(e.args)
221
222        def getAll(self):
223                "Get the list of all Roles"
224                try:
225                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
226                        resultdicts = self.__getAll(cursor)
227                        cursor.close()
228
229                        self.logger.debug("Number of role rows fetched: %d" % len(resultdicts))
230
231                        res = []
232                        for rd in resultdicts:
233                                res.append(Role(rd))
234
235                        return res
236                except MySQLdb.Error, e:
237                        raise RadioMateDAOException(e.args)
238       
239        def update(self, roleobject):
240                "Update an existing Role"
241                try:
242                        cursor = self.conn.cursor()
243                        self.__update(roleobject, cursor)
244                        self.conn.commit()
245                        cursor.close()
246                        self.logger.debug("Number of role rows updated: %d" % cursor.rowcount)
247                        return cursor.rowcount
248                except MySQLdb.Error, e:
249                        raise RadioMateDAOException(e.args)
250
251
252class UserMysqlDAO(RadioMateParentMysqlDAO):
253        "The MySQL Database Access Object for Users"
254        def __insert(self, userobject, cursor):
255                # rolename existance check is provided by foreign key in MySQL
256                insertionstring = """
257                INSERT INTO users (
258                        name,
259                        password,
260                        displayname,
261                        role
262                ) VALUES (
263                '%s', SHA1('%s'), '%s', '%s')""" % (
264                        userobject.name,
265                        userobject.password,
266                        userobject.displayname,
267                        userobject.rolename
268                )
269                self.logger.debug(insertionstring)
270                cursor.execute(insertionstring)
271
272        def __getByName(self, username, cursor):
273                selectionstring = """
274                SELECT 
275                        name,
276                        displayname,
277                        role
278                FROM users
279                WHERE name = '%s'""" % username
280                self.logger.debug(selectionstring)
281                cursor.execute(selectionstring)
282                return cursor.fetchall()
283
284        def __removeByName(self, username, cursor):
285                deletionstring = """
286                DELETE FROM users
287                WHERE name = '%s'""" % username
288                self.logger.debug(deletionstring)
289                cursor.execute(deletionstring)
290       
291        def __getAll(self, cursor):
292                selectionstring = """
293                SELECT 
294                        name,
295                        displayname,
296                        role
297                FROM users"""
298                self.logger.debug(selectionstring)
299                cursor.execute(selectionstring)
300                return cursor.fetchall()
301
302        def __update(self, userobject, cursor):
303                updatestring = """
304                UPDATE users
305                SET
306                        password = SHA1('%s'),
307                        displayname = '%s',
308                        role = '%s'
309                WHERE name = '%s'""" % (
310                        userobject.password,
311                        userobject.displayname,
312                        userobject.rolename,
313                        userobject.name
314                )
315                self.logger.debug(updatestring)
316                cursor.execute(updatestring)
317       
318        def __logincheck(self, username, password, cursor):
319                selectionstring = """
320                SELECT 
321                        name,
322                        displayname,
323                        role
324                FROM users
325                WHERE name = '%s' and password = SHA1('%s')""" % (username, password)
326                self.logger.debug(selectionstring)
327                cursor.execute(selectionstring)
328                return cursor.fetchall()
329
330        def insert(self, userobject):
331                "Insert a new user"
332                try:
333                        cursor = self.conn.cursor()
334                        self.__insert(userobject, cursor)
335                        self.conn.commit()
336                        cursor.close()
337                        self.logger.debug("Number of user rows inserted: %d" % cursor.rowcount)
338                        return cursor.rowcount
339                except MySQLdb.Error, e:
340                        raise RadioMateDAOException(e.args)
341       
342        def getByName(self, username):
343                "Get an user from its username"
344                try:
345                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
346                        resultdicts = self.__getByName(username, cursor)
347                        cursor.close()
348
349                        self.logger.debug("Number of user rows fetched: %d" % len(resultdicts))
350                        assert len(resultdicts) <= 1
351
352                        if len(resultdicts) == 1:
353                                u = User(resultdicts[0])
354                                roledao = RoleMysqlDAO(self.conn)
355                                u.role = roledao.getByName(u.rolename)
356                                return u
357                        else:
358                                return None
359                except MySQLdb.Error, e:
360                        raise RadioMateDAOException(e.args)
361
362        def removeByName(self, username):
363                "Remove an user from its username"
364                try:
365                        cursor = self.conn.cursor()
366                        self.__removeByName(username, cursor)
367                        self.conn.commit()
368                        cursor.close()
369                        self.logger.debug("Number of user rows deleted: %d" % cursor.rowcount)
370                        return cursor.rowcount
371                except MySQLdb.Error, e:
372                        raise RadioMateDAOException(e.args)
373
374        def getAll(self):
375                "Get the list of all users"
376                try:
377                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
378                        resultdicts = self.__getAll(cursor)
379                        cursor.close()
380
381                        self.logger.debug("Number of user rows fetched: %d" % len(resultdicts))
382
383                        roledao = RoleMysqlDAO(self.conn)
384                        res = []
385                        for rd in resultdicts:
386                                u = User(rd)
387                                u.role = roledao.getByName(u.rolename)
388                                res.append(u)
389
390                        return res
391                except MySQLdb.Error, e:
392                        raise RadioMateDAOException(e.args)
393
394        def update(self, userobject):
395                "Update an existing user"
396                try:
397                        cursor = self.conn.cursor()
398                        self.__update(userobject, cursor)
399                        self.conn.commit()
400                        cursor.close()
401                        self.logger.debug("Number of user rows updated: %d" % cursor.rowcount)
402                        return cursor.rowcount
403                except MySQLdb.Error, e:
404                        raise RadioMateDAOException(e.args)
405
406        def logincheck(self, username, password):
407                try:
408                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
409                        resultdicts = self.__logincheck(username, password, cursor)
410                        cursor.close()
411
412                        self.logger.debug("Login for user %s: %d" % (username, len(resultdicts)))
413                        assert len(resultdicts) <= 1
414
415                        if len(resultdicts) == 1:
416                                u = User(resultdicts[0])
417                                roledao = RoleMysqlDAO(self.conn)
418                                u.role = roledao.getByName(u.rolename)
419                                return u
420                        else:
421                                return None
422                except MySQLdb.Error, e:
423                        raise RadioMateDAOException(e.args)
424       
425
426class MediaFileMysqlDAO(RadioMateParentMysqlDAO):
427        "The MySQL Database Access Object for media files"
428        def __insert(self, mediafileobject, cursor):
429                insertionstring = """
430                INSERT INTO mediafiles (
431                        user,
432                        path,
433                        type,
434                        title,
435                        author,
436                        album,
437                        genre,
438                        year,
439                        comment,
440                        license,
441                        tags
442                ) VALUES (
443                '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s')""" % (
444                        mediafileobject.user,
445                        mediafileobject.path, 
446                        mediafileobject.type,
447                        mediafileobject.title,
448                        mediafileobject.author,
449                        mediafileobject.album,
450                        mediafileobject.genre,
451                        mediafileobject.year,
452                        mediafileobject.comment,
453                        mediafileobject.license,
454                        mediafileobject.tags
455                )
456                self.logger.debug(insertionstring)
457                cursor.execute(insertionstring)
458
459        def __getLastId(self, cursor):
460                selectionstring = """
461                SELECT LAST_INSERT_ID() AS lastid
462                """
463                self.logger.debug(selectionstring)
464                cursor.execute(selectionstring)
465                return cursor.fetchall()[0]['lastid']
466
467        def __getById(self, mediafileid, cursor):
468                selectionstring = """
469                SELECT 
470                        id,
471                        user,
472                        path,
473                        type,
474                        title,
475                        author,
476                        album,
477                        genre,
478                        year,
479                        comment,
480                        license,
481                        tags
482                FROM mediafiles
483                WHERE id = %d""" % mediafileid
484
485                self.logger.debug(selectionstring)
486                cursor.execute(selectionstring)
487                return cursor.fetchall()
488
489        def __removeById(self, mediafileid, cursor):
490                deletionstring = """
491                DELETE FROM mediafiles
492                WHERE id = %d""" % mediafileid
493
494                self.logger.debug(deletionstring)
495                cursor.execute(deletionstring)
496
497        def __search(self, partialmediafile, cursor):
498                searchstring = """
499                SELECT 
500                        id,
501                        user,
502                        path,
503                        type,
504                        title,
505                        author,
506                        album,
507                        genre,
508                        year,
509                        comment,
510                        license,
511                        tags
512                FROM mediafiles
513                """
514                def whereand(n):
515                        if n == 0:
516                                return " WHERE "
517                        else:
518                                return " AND "
519                i = 0
520                if partialmediafile.user:
521                        searchstring += whereand(i) + " user = '%s' " % partialmediafile.user
522                        i+=1
523                if partialmediafile.path:
524                        searchstring += whereand(i) + " path LIKE '%%%s%%' " % partialmediafile.path
525                        i+=1
526                if partialmediafile.title:
527                        searchstring += whereand(i) + " title LIKE '%%%s%%' " % partialmediafile.title
528                        i+=1
529                if partialmediafile.author:
530                        searchstring += whereand(i) + " author LIKE '%%%s%%' " % partialmediafile.author
531                        i+=1
532                if partialmediafile.album:
533                        searchstring += whereand(i) + " album LIKE '%%%s%%' " % partialmediafile.album
534                        i+=1
535                if partialmediafile.genre:
536                        searchstring += whereand(i) + " genre LIKE '%%%s%%' " % partialmediafile.genre
537                        i+=1
538                if partialmediafile.year:
539                        searchstring += whereand(i) + " year = %d " % partialmediafile.year
540                        i+=1
541                if partialmediafile.comment:
542                        searchstring += whereand(i) + " comment LIKE '%%%s%%' " % partialmediafile.comment
543                        i+=1
544                if partialmediafile.license:
545                        searchstring += whereand(i) + " license LIKE '%%%s%%' " % partialmediafile.license
546                        i+=1
547                #TODO: tags
548                self.logger.debug(searchstring)
549                cursor.execute(searchstring)
550                return cursor.fetchall()
551
552        def __update(self, mediafileobject, cursor):
553                updatestring = """
554                UPDATE mediafiles
555                SET
556                        user = '%s',
557                        path = '%s',
558                        type = '%s',
559                        title = '%s',
560                        author = '%s',
561                        album = '%s',
562                        genre = '%s',
563                        year = %d,
564                        comment = '%s',
565                        license = '%s',
566                        tags = '%s'
567                WHERE
568                        id = '%d'
569                """ % (
570                        mediafileobject.user,
571                        mediafileobject.path, 
572                        mediafileobject.type,
573                        mediafileobject.title,
574                        mediafileobject.author,
575                        mediafileobject.album,
576                        mediafileobject.genre,
577                        mediafileobject.year,
578                        mediafileobject.comment,
579                        mediafileobject.license,
580                        mediafileobject.tags,
581                        mediafileobject.id
582                )
583
584                self.logger.debug(updatestring) 
585                cursor.execute(updatestring)
586       
587        def __getByPath(self, mediafilepath, cursor):
588                selectionstring = """
589                SELECT 
590                        id,
591                        user,
592                        path,
593                        type,
594                        title,
595                        author,
596                        album,
597                        genre,
598                        year,
599                        comment,
600                        license,
601                        tags
602                FROM mediafiles
603                WHERE path = '%s'""" % mediafilepath
604
605                self.logger.debug(selectionstring)
606                cursor.execute(selectionstring)
607                return cursor.fetchall()
608
609        def insert(self, mediafileobject):
610                "Insert a new media file"
611                try:
612                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
613                        self.__insert(mediafileobject, cursor)
614                        self.conn.commit()
615                        lastid = self.__getLastId(cursor)
616                        cursor.close()
617
618                        self.logger.debug("Number of mediafile rows inserted: %d. Last id = %d" % (cursor.rowcount, lastid))
619                        return lastid
620                except MySQLdb.Error, e:
621                        raise RadioMateDAOException(e.args)
622       
623        def getById(self, mediafileid):
624                "Get a media file from its id"
625                try:
626                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
627                        resultdicts = self.__getById(mediafileid, cursor)
628                        cursor.close()
629
630                        self.logger.debug("Number of mediafile rows fetched: %d" % len(resultdicts))
631                        assert len(resultdicts) == 1
632
633                        return MediaFile(resultdicts[0])
634                except MySQLdb.Error, e:
635                        raise RadioMateDAOException(e.args)
636
637        def removeById(self, mediafileid):
638                "Remove a media file from its id"
639                try:
640                        cursor = self.conn.cursor()
641                        self.__removeById(mediafileid, cursor)
642                        self.conn.commit()
643                        cursor.close()
644                        self.logger.debug("Number of mediafile rows deleted: %d" % cursor.rowcount)
645                        return cursor.rowcount
646                except MySQLdb.Error, e:
647                        raise RadioMateDAOException(e.args)
648
649        def search(self, partialmediafile):
650                "Search for a media file"
651                try:
652                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
653                        resultdicts = self.__search(partialmediafile, cursor)
654                        cursor.close()
655
656                        self.logger.debug("Number of mediafile rows fetched while searching: %d" % len(resultdicts))
657
658                        res = []
659                        for mf in resultdicts:
660                                res.append(MediaFile(mf))
661                        return res
662                except MySQLdb.Error, e:
663                        raise RadioMateDAOException(e.args)
664       
665        def update(self, mediafileobject):
666                "Update an existing media file"
667                try:
668                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
669                        self.__update(mediafileobject, cursor)
670                        self.conn.commit()
671                        lastid = mediafileobject.id
672                        cursor.close()
673                        self.logger.debug("Number of mediafile rows updated: %d. id = %d" % (cursor.rowcount, lastid))
674                        return lastid
675                except MySQLdb.Error, e:
676                        raise RadioMateDAOException(e.args)
677
678        def getByPath(self, mediafilepath):
679                "Get a media file from its path"
680                try:
681                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
682                        resultdicts = self.__getByPath(mediafilepath, cursor)
683                        cursor.close()
684
685                        self.logger.debug("Number of mediafile rows fetched by path: %d" % len(resultdicts))
686
687                        res = []
688                        for mf in resultdicts:
689                                res.append(MediaFile(mf))
690                        return res
691                except MySQLdb.Error, e:
692                        raise RadioMateDAOException(e.args)
693
694
695class PlayListMysqlDAO(RadioMateParentMysqlDAO):
696        "The MySQL Database Access Object for playlists"
697        def __insert(self, playlistobject, cursor):
698                insertionstring = """
699                INSERT INTO playlists (
700                        creator,
701                        private,
702                        random,
703                        title,
704                        description,
705                        comment,
706                        tags
707                ) VALUES (
708                '%s', %d, '%s', '%s', '%s', '%s')""" % (
709                        playlistobject.creator,
710                        int(playlistobject.private),
711                        int(playlistobject.random),
712                        playlistobject.title,
713                        playlistobject.description,
714                        playlistobject.comment,
715                        playlistobject.tags
716                )
717
718                self.logger.debug(insertionstring)
719                cursor.execute(insertionstring)
720       
721        def __getLastId(self, cursor):
722                selectionstring = """
723                SELECT LAST_INSERT_ID() AS lastid
724                """
725                self.logger.debug(selectionstring)
726                cursor.execute(selectionstring)
727                return cursor.fetchall()[0]['lastid']
728
729        def __insertmediafile(self, playlistid, mediafileid, position, cursor):
730                insertionstring = """
731                INSERT INTO compilation (
732                        playlist,
733                        mediafile,
734                        position
735                ) VALUES (
736                %d, %d, %d)""" % (
737                        playlistid,
738                        mediafileid,
739                        position
740                )
741
742                self.logger.debug(insertionstring)
743                cursor.execute(insertionstring)
744
745        def __insertowner(self, playlistid, ownername, cursor):
746                insertionstring = """
747                INSERT INTO playlistowners (
748                        playlist,
749                        user
750                ) VALUES (
751                %d, '%s')""" % (
752                        playlistid,
753                        ownername
754                )
755
756                self.logger.debug(insertionstring)
757                cursor.execute(insertionstring)
758       
759        def __insertviewer(self, playlistid, viewername, cursor):
760                insertionstring = """
761                INSERT INTO playlistviewers(
762                        playlist,
763                        user
764                ) VALUES (
765                %d, '%s')""" % (
766                        playlistid,
767                        viewername
768                )
769
770                self.logger.debug(insertionstring)
771                cursor.execute(insertionstring)
772       
773        def __getById(self, playlistid, cursor):
774                selectionstring = """
775                SELECT 
776                        id,
777                        creator,
778                        private,
779                        random,
780                        title,
781                        description,
782                        comment,
783                        tags
784                FROM playlists
785                WHERE id = %d""" % playlistid
786
787                self.logger.debug(selectionstring)
788                cursor.execute(selectionstring)
789                return cursor.fetchall()
790       
791        def __getMediaFiles(self, playlistid, cursor):
792                selectionstring = """
793                SELECT 
794                        playlist,
795                        mediafile,
796                        position
797                FROM compilation
798                WHERE playlist = %d
799                ORDER BY position""" % playlistid   
800
801                self.logger.debug(selectionstring)
802                cursor.execute(selectionstring)
803                return cursor.fetchall()
804       
805        def __getOwners(self, playlistid, cursor):
806                selectionstring = """
807                SELECT 
808                        playlist,
809                        user
810                FROM playlistowners
811                WHERE playlist = %d""" % playlistid
812
813                self.logger.debug(selectionstring)
814                cursor.execute(selectionstring)
815                return cursor.fetchall()
816       
817        def __getViewers(self, playlistid, cursor):
818                selectionstring = """
819                SELECT 
820                        playlist,
821                        user
822                FROM playlistviewers
823                WHERE playlist = %d""" % playlistid
824
825                self.logger.debug(selectionstring)
826                cursor.execute(selectionstring)
827                return cursor.fetchall()
828       
829        def __removeById(self, playlistid, cursor):
830                deletionstring = """
831                DELETE FROM playlists
832                WHERE id = %d""" % playlistid
833
834                self.logger.debug(deletionstring)
835                cursor.execute(deletionstring)
836
837        def __update(self, playlistobject, cursor):
838                updatestring = """
839                UPDATE playlists
840                SET
841                        creator = '%s',
842                        private = %d,
843                        random = %d,
844                        title = '%s',
845                        description = '%s',
846                        comment = '%s',
847                        tags = '%s'
848                WHERE id = %d """ % (
849                        playlistobject.creator,
850                        int(playlistobject.private),
851                        int(playlistobject.random),
852                        playlistobject.title,
853                        playlistobject.description,
854                        playlistobject.comment,
855                        playlistobject.tags,
856                        playlistobject.id
857                )
858
859                self.logger.debug(updatestring)
860                cursor.execute(updatestring)
861
862        def __deleteCompilationOwnersAndViewers(self, playlistid, cursor):
863                "delete stuff related to this playlist in all tables"
864                mediafiledeletionstring = """
865                DELETE FROM compilation
866                WHERE playlist = %d """ % playlistid
867
868                ownerdeletionstring = """
869                DELETE FROM playlistowners
870                WHERE playlist = %d """ % playlistid
871
872                viewerdeletionstring = """
873                DELETE FROM playlistviewers
874                WHERE playlist = %d """ % playlistid
875       
876                self.logger.debug(mediafiledeletionstring)
877                cursor.execute(mediafiledeletionstring)
878                self.logger.debug(ownerdeletionstring)
879                cursor.execute(ownerdeletionstring)
880                self.logger.debug(viewerdeletionstring)
881                cursor.execute(viewerdeletionstring)
882       
883        def __getByCreator(self, creatorname, cursor):
884                selectionstring = """
885                SELECT 
886                        id,
887                        creator,
888                        private,
889                        random,
890                        title,
891                        description,
892                        comment,
893                        tags
894                FROM playlists
895                WHERE creator = '%s'""" % creatorname
896
897                self.logger.debug(selectionstring)
898                cursor.execute(selectionstring)
899                return cursor.fetchall()
900       
901        def __getByUser(self, username, getprivate, cursor):
902                "Returns public (i.e. not private) playlist ids in which the user is creator, owner or viewer"
903                selectionstring = """
904                SELECT 
905                        playlists.id
906                FROM playlists JOIN (playlistowners, playlistviewers)
907                ON (playlistowners.playlist = playlists.id AND playlistviewers.playlist = playlists.id)
908                WHERE
909                ( playlists.creator = '%s' OR
910                playlistowners.user = '%s' OR
911                playlistviewers.user = '%s' )
912                """ % (username, username, username)
913                if not getprivate:
914                        selectionstring+="AND playlists.private = 0" 
915
916                self.logger.debug(selectionstring)
917                cursor.execute(selectionstring)
918                return cursor.fetchall()
919
920        def insert(self, playlistobject):
921                "Insert a new Playlist in the database"
922                try:
923                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
924                        self.__insert(playlistobject, cursor)
925                        self.conn.commit()
926                        lastid = self.__getLastId(cursor)
927                        for i, mf in enumerate(playlistobject.mediafilelist):
928                                self.__insertmediafile(lastid, mf.id, i, cursor)
929                        for uname in playlistobject.owners:
930                                self.__insertowner(lastid, uname, cursor)
931                        for uname in playlistobject.viewers:
932                                self.__insertviewer(lastid, uname, cursor)
933                        self.conn.commit()
934                        cursor.close()
935                        return lastid
936                except MySQLdb.Error, e:
937                        raise RadioMateDAOException(e.args)
938       
939        def getById(self, playlistid):
940                "Get a Playlist from its id"
941                try:
942                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
943                        resultdicts = self.__getById(playlistid, cursor)
944
945                        self.logger.debug("Number of playlist rows fetched: %d" % len(resultdicts))
946                        assert len(resultdicts) <= 1
947
948                        if len(resultdicts) == 0:
949                                return None
950
951                        pl = PlayList(resultdicts[0])
952                        mediafiledao = MediaFileMysqlDAO(self.conn)
953
954                        resultdicts = self.__getMediaFiles(playlistid, cursor)
955                        for mfrow in resultdicts:
956                                mf = mediafiledao.getById(mfrow['mediafile'])
957                                pl.addMediaFile(mf)
958
959                        resultdicts = self.__getOwners(playlistid, cursor)
960                        for urow in resultdicts:
961                                pl.addOwner(urow['user'])
962
963                        resultdicts = self.__getViewers(playlistid, cursor)
964                        for urow in resultdicts:
965                                pl.addViewer(urow['user'])
966
967                        cursor.close()
968                        return pl
969                except MySQLdb.Error, e:
970                        raise RadioMateDAOException(e.args)
971
972        def removeById(self, playlistid):
973                "Remove a playlist from its id"
974                try:
975                        cursor = self.conn.cursor()
976                        self.__removeById(playlistid, cursor)
977                        self.conn.commit()
978                        cursor.close()
979                        self.logger.debug("Number of playlist rows deleted: %d" % cursor.rowcount)
980                        return cursor.rowcount
981                except MySQLdb.Error, e:
982                        raise RadioMateDAOException(e.args)
983
984        def update(self, playlistobject):
985                "Update an existing playlist"
986                try:
987                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
988                        self.__deleteCompilationOwnersAndViewers(playlistobject.id, cursor)
989                        self.conn.commit() #needed?
990                        self.__update(playlistobject, cursor)
991                        lastid = playlistobject.id
992                        for i, mf in enumerate(playlistobject.mediafilelist):
993                                self.__insertmediafile(lastid, mf.id, i, cursor)
994                        for uname in playlistobject.owners:
995                                self.__insertowner(lastid, uname, cursor)
996                        for uname in playlistobject.viewers:
997                                self.__insertviewer(lastid, uname, cursor)
998                        self.conn.commit()
999                        cursor.close()
1000                        return lastid
1001                except MySQLdb.Error, e:
1002                        raise RadioMateDAOException(e.args)
1003       
1004        def getByCreator(self, creatorname):
1005                "Get the playlists of a given creator"
1006                try:
1007                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1008                        plresultdicts = self.__getByCreator(creatorname, cursor)
1009
1010                        self.logger.debug("Number of playlist rows fetched: %d" % len(plresultdicts))
1011
1012                        mediafiledao = MediaFileMysqlDAO(self.conn)
1013                        res = []
1014                        for plist in plresultdicts:
1015                                pl = PlayList(plist)
1016
1017                                resultdicts = self.__getMediaFiles(pl.id, cursor)
1018                                for mfrow in resultdicts:
1019                                        mf = mediafiledao.getById(mfrow['mediafile'])
1020                                        pl.addMediaFile(mf)
1021
1022                                resultdicts = self.__getOwners(pl.id, cursor)
1023                                for urow in resultdicts:
1024                                        pl.addOwner(urow['user'])
1025
1026                                resultdicts = self.__getViewers(pl.id, cursor)
1027                                for urow in resultdicts:
1028                                        pl.addViewer(urow['user'])
1029
1030                                res.append(pl)
1031                        cursor.close()
1032                        return res
1033                except MySQLdb.Error, e:
1034                        raise RadioMateDAOException(e.args)
1035
1036        def getByUser(self, username, getprivate=False):
1037                "Returns playlists in which the user is creator, owner or viewer"
1038                try:
1039                        #TODO: type checking in all methods, not only in this one
1040                        if not isinstance(username, basestring):
1041                                raise RadioMateDAOException("String needed")
1042
1043                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1044                        plresultdicts = self.__getByUser(username, getprivate, cursor)
1045                        cursor.close()
1046
1047                        self.logger.debug("Number of playlist rows fetched: %d" % len(plresultdicts))
1048
1049                        res = []
1050                        for plres in plresultdicts:
1051                                assert len(plres) == 1
1052                                plid = plres['id']
1053                                pl = self.getById(plid)
1054                                res.append(pl)
1055                        return res
1056                except MySQLdb.Error, e:
1057                        raise RadioMateDAOException(e.args)
1058
1059
1060class TimeSlotMysqlDAO(RadioMateParentMysqlDAO):
1061        "The MySQL Database Access Object for radio show time slots"
1062        def __isGoodTimeSlot(self, timeslotobject, cursor):
1063                "check if the timeslotobject can be inserted in the radio's timetable"
1064                # time conflict conditions
1065                # +---+ = existing timeslot = (b+, e+)
1066                # *---* = new timeslot = (b*, e*)
1067                #
1068                #  b+         e+
1069                #  +----------+
1070                #       b*          e*
1071                #       *-----------*   b+ < b* < e+  but also  b* < e+ < e*
1072                #
1073                #
1074                #       b+          e+
1075                #       +-----------+
1076                #  b*        e*
1077                #  *---------*          b+ < e* < e+  but also  b* < b+ < e*
1078                #
1079                #
1080                #    b+        e+
1081                #    +---------+
1082                #  b*            e*
1083                #  *-------------*      b* < b+ < e*,  b* < e+ < e*  ---> first two cases together
1084                #
1085               
1086                #   b+         e+
1087                #  +-------------+
1088                #    b*        e*
1089                #    *---------*        b+ < b* < e+,  b+ < e* < e+  ---> first two cases together
1090                #
1091                #
1092                selectionstring = """
1093                SELECT 
1094                        id,
1095                        creator,
1096                        beginningtime,
1097                        endingtime,
1098                        title
1099                FROM timeslots
1100                WHERE """
1101                # b+ < b* < e+
1102                selectionstring += "(beginningtime <= '%s' AND '%s' <= endingtime) OR \n" %\
1103                                (timeslotobject.getBeginningDatetime(), timeslotobject.getBeginningDatetime())
1104                # b+ < e* < e+
1105                selectionstring += "(beginningtime <= '%s' AND '%s' <= endingtime) OR \n" %\
1106                                (timeslotobject.getEndingDatetime(), timeslotobject.getEndingDatetime())
1107                # b* < b+ < e*
1108                selectionstring += "('%s' <= beginningtime AND beginningtime <= '%s') OR \n" %\
1109                                (timeslotobject.getBeginningDatetime(), timeslotobject.getEndingDatetime())
1110                # b* < e+ < e*
1111                selectionstring += "('%s' <= endingtime AND endingtime <= '%s')" %\
1112                                (timeslotobject.getBeginningDatetime(), timeslotobject.getEndingDatetime())
1113
1114                self.logger.debug(selectionstring)
1115                cursor.execute(selectionstring)
1116                return cursor.fetchall()
1117
1118        def __insert(self, timeslotobject, cursor):
1119                insertionstring = """
1120                INSERT INTO timeslots (
1121                        creator,
1122                        slottype,
1123                        beginningtime,
1124                        endingtime,
1125                        title,
1126                        description,
1127                        comment,
1128                        tags,
1129                        slotparameters,
1130                        fallbackplaylist
1131                ) VALUES (
1132                '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)""" % (
1133                        timeslotobject.creator,
1134                        timeslotobject.slottype,
1135                        timeslotobject.getBeginningDatetime(),
1136                        timeslotobject.getEndingDatetime(),
1137                        timeslotobject.title,
1138                        timeslotobject.description,
1139                        timeslotobject.comment,
1140                        timeslotobject.tags,
1141                        json.dumps(timeslotobject.slotparams),
1142                        timeslotobject.fallbackplaylist
1143                )
1144
1145                self.logger.debug(insertionstring)
1146                cursor.execute(insertionstring)
1147
1148        def __getLastId(self, cursor):
1149                selectionstring = """
1150                SELECT LAST_INSERT_ID() AS lastid
1151                """
1152
1153                self.logger.debug(selectionstring)
1154                cursor.execute(selectionstring)
1155                return cursor.fetchall()[0]['lastid']
1156
1157        def __getById(self, timeslotid, cursor):
1158                selectionstring = """
1159                SELECT 
1160                        id,
1161                        creator,
1162                        slottype,
1163                        beginningtime,
1164                        endingtime,
1165                        title,
1166                        description,
1167                        comment,
1168                        slotparameters,
1169                        fallbackplaylist,
1170                        tags
1171                FROM timeslots
1172                WHERE id = %d""" % timeslotid
1173
1174                self.logger.debug(selectionstring)
1175                cursor.execute(selectionstring)
1176                return cursor.fetchall()
1177
1178        def __removeById(self, timeslotid, cursor):
1179                deletionstring = """
1180                DELETE FROM timeslots
1181                WHERE id = %d""" % timeslotid
1182
1183                self.logger.debug(deletionstring)
1184                cursor.execute(deletionstring)
1185       
1186        def __update(self, timeslotobject, cursor):
1187                updatestring = """
1188                UPDATE timeslots
1189                SET
1190                        creator = '%s',
1191                        slottype = '%s',
1192                        beginningtime = '%s',
1193                        endingtime = '%s',
1194                        title = '%s',
1195                        description = '%s',
1196                        comment = '%s',
1197                        tags = '%s',
1198                        slotparameters = '%s',
1199                        fallbackplaylist = %d
1200                WHERE id = %d
1201                """ % (
1202                        timeslotobject.creator,
1203                        timeslotobject.slottype,
1204                        timeslotobject.getBeginningDatetime(),
1205                        timeslotobject.getEndingDatetime(),
1206                        timeslotobject.title,
1207                        timeslotobject.description,
1208                        timeslotobject.comment,
1209                        timeslotobject.tags,
1210                        json.dumps(timeslotobject.slotparams),
1211                        timeslotobject.fallbackplaylist,
1212                        timeslotobject.id
1213                )
1214
1215                self.logger.debug(updatestring)
1216                cursor.execute(updatestring)
1217       
1218        def __getFromTo(self, fromdate, todate, cursor):
1219                "fromdate and todate are date+time strings"
1220                selectionstring = """
1221                SELECT 
1222                        id,
1223                        creator,
1224                        slottype,
1225                        beginningtime,
1226                        endingtime,
1227                        title,
1228                        description,
1229                        comment,
1230                        slotparameters,
1231                        fallbackplaylist,
1232                        tags
1233                FROM timeslots
1234                WHERE beginningtime >= '%s' AND beginningtime <= '%s'""" % (fromdate, todate)
1235
1236                self.logger.debug(selectionstring)
1237                cursor.execute(selectionstring)
1238                return cursor.fetchall()
1239       
1240        def __search(self, timeslotobject, cursor):
1241                "Search for timeslots"
1242                selectionstring = """
1243                SELECT 
1244                        id,
1245                        creator,
1246                        slottype,
1247                        beginningtime,
1248                        endingtime,
1249                        title,
1250                        description,
1251                        comment,
1252                        slotparameters,
1253                        fallbackplaylist,
1254                        tags
1255                FROM timeslots
1256                """
1257
1258                def whereand(n):
1259                        if n == 0:
1260                                return " WHERE "
1261                        else:
1262                                return " AND "
1263                i = 0
1264                if timeslotobject.title:
1265                        selectionstring += whereand(i) + " title LIKE '%%%s%%' " % timeslotobject.title
1266                        i+=1
1267                if timeslotobject.description:
1268                        selectionstring += whereand(i) + " description LIKE '%%%s%%' " % timeslotobject.description
1269                        i+=1
1270                if timeslotobject.comment:
1271                        selectionstring += whereand(i) + " comment LIKE '%%%s%%' " % timeslotobject.comment
1272                        i+=1
1273                if timeslotobject.tags:
1274                        selectionstring += whereand(i) + " tags LIKE '%%%s%%' " % timeslotobject.tags
1275                        i+=1
1276                if timeslotobject.creator:
1277                        selectionstring += whereand(i) + " creator = '%s'" % timeslotobject.creator
1278
1279                self.logger.debug(selectionstring)
1280                cursor.execute(selectionstring)
1281                return cursor.fetchall()
1282       
1283        def __getNext(self, fromdate, n, cursor):
1284                "fromdate is a date+time string"
1285                selectionstring = """
1286                SELECT 
1287                        id,
1288                        creator,
1289                        slottype,
1290                        beginningtime,
1291                        endingtime,
1292                        title,
1293                        description,
1294                        comment,
1295                        slotparameters,
1296                        fallbackplaylist,
1297                        tags
1298                FROM timeslots
1299                WHERE beginningtime >= '%s'
1300                LIMIT %d
1301                """ % (fromdate, n)
1302
1303                self.logger.debug(selectionstring)
1304                cursor.execute(selectionstring)
1305                return cursor.fetchall()
1306       
1307        def isGoodTimeSlot(self, timeslotobject):
1308                "Returns true iff the timeslot does not conflict with existing timeslots"
1309                try:
1310                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1311                        resultdicts = self.__isGoodTimeSlot(timeslotobject, cursor)
1312                        cursor.close()
1313                       
1314                        self.logger.debug("Number of timeslot rows fetched: %d" % len(resultdicts))
1315
1316                        if len(resultdicts) == 0:
1317                                return True
1318                        elif len(resultdicts) == 1:
1319                                if int(resultdicts[0]['id']) == timeslotobject.id:
1320                                        return True
1321                        else:
1322                                return False
1323                except MySQLdb.Error, e:
1324                        raise RadioMateDAOException(e.args)
1325
1326        def insert(self, timeslotobject):
1327                "Insert a new timeslot in the database"
1328                try:
1329                        if not self.isGoodTimeSlot(timeslotobject):
1330                                raise RadioMateBadTimeSlotException()
1331                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1332                        self.__insert(timeslotobject, cursor)
1333                        self.conn.commit()
1334                        lastid = self.__getLastId(cursor)
1335                        cursor.close()
1336                        self.logger.debug("Number of timeslot rows inserted: %d. Last id = %d" % (cursor.rowcount, lastid))
1337                        return lastid
1338                except MySQLdb.Error, e:
1339                        raise RadioMateDAOException(e.args)
1340       
1341        def getById(self, timeslotid):
1342                "Get a timeslot from its id"
1343                try:
1344                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1345                        resultdicts = self.__getById(timeslotid, cursor)
1346                        cursor.close()
1347
1348                        self.logger.debug("Number of timeslot rows fetched: %d" % len(resultdicts))
1349                        assert len(resultdicts) == 1
1350                        self.logger.debug("getById: %s" % resultdicts[0])
1351
1352                        rs = resultdicts[0]
1353                        ts = TimeSlot()
1354                        ts.id = rs['id']
1355                        #debug
1356                        assert ts.id == rs['id']
1357                        ts.creator = rs['creator']
1358                        ts.slottype = rs['slottype']
1359                        ts.title = rs['title']
1360                        ts.description = rs['description']
1361                        ts.comment = rs['comment']
1362                        ts.tags = rs['tags']
1363                        ts.setBeginningDateTime(rs['beginningtime'])
1364                        ts.setEndingDateTime(rs['endingtime'])
1365                        ts.slotparams = json.loads(rs['slotparameters'])
1366                        ts.fallbackplaylist = rs['fallbackplaylist']
1367                        self.logger.debug("getById: %s" % str(ts))
1368                        return ts
1369                except MySQLdb.Error, e:
1370                        raise RadioMateDAOException(e.args)
1371
1372        def removeById(self, timeslotid):
1373                "Remove a timeslot from its id"
1374                try:
1375                        cursor = self.conn.cursor()
1376                        self.__removeById(timeslotid, cursor)
1377                        self.conn.commit()
1378                        cursor.close()
1379                        self.logger.debug("Number of timeslot rows deleted: %d" % cursor.rowcount)
1380                        return cursor.rowcount
1381                except MySQLdb.Error, e:
1382                        raise RadioMateDAOException(e.args)
1383
1384        def update(self, timeslotobject):
1385                "Update an existing timeslot"
1386                try:
1387                        if not self.isGoodTimeSlot(timeslotobject):
1388                                raise RadioMateBadTimeSlotException()
1389                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1390                        self.__update(timeslotobject, cursor)
1391                        self.conn.commit()
1392                        lastid = timeslotobject.id
1393                        cursor.close()
1394                        self.logger.debug("Number of timeslot rows inserted: %d. Last id = %d" % (cursor.rowcount, lastid))
1395                        return lastid
1396                except MySQLdb.Error, e:
1397                        raise RadioMateDAOException(e.args)
1398
1399        def getFromTo(self, fromdate, todate):
1400                "Get timeslots between fromdate and todate date+time strings"
1401                try:
1402                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1403                        resultdicts = self.__getFromTo(fromdate, todate, cursor)
1404                        cursor.close()
1405
1406                        self.logger.debug("Number of timeslot rows fetched: %d" % len(resultdicts))
1407
1408                        res = []
1409                        for rs in resultdicts:
1410                                ts = TimeSlot()
1411                                ts.id = rs['id']
1412                                ts.creator = rs['creator']
1413                                ts.slottype = rs['slottype']
1414                                ts.title = rs['title']
1415                                ts.description = rs['description']
1416                                ts.comment = rs['comment']
1417                                ts.tags = rs['tags']
1418                                ts.setBeginningDateTime(rs['beginningtime'])
1419                                ts.setEndingDateTime(rs['endingtime'])
1420                                ts.slotparams = json.loads(rs['slotparameters'])
1421                                ts.fallbackplaylist = rs['fallbackplaylist']
1422                                res.append(ts)
1423                        return res
1424                except MySQLdb.Error, e:
1425                        raise RadioMateDAOException(e.args)
1426       
1427        def search(self, timeslotobject):
1428                "Search for timeslots using the title, comment, description, tags and creator properties of timeslotobject"
1429                try:
1430                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1431                        resultdicts = self.__search(timeslotobject, cursor)
1432                        cursor.close()
1433
1434                        self.logger.debug("Number of timeslot rows fetched: %d" % len(resultdicts))
1435
1436                        res = []
1437                        for rs in resultdicts:
1438                                ts = TimeSlot()
1439                                ts.id = rs['id']
1440                                ts.creator = rs['creator']
1441                                ts.slottype = rs['slottype']
1442                                ts.title = rs['title']
1443                                ts.description = rs['description']
1444                                ts.comment = rs['comment']
1445                                ts.tags = rs['tags']
1446                                ts.setBeginningDateTime(rs['beginningtime'])
1447                                ts.setEndingDateTime(rs['endingtime'])
1448                                ts.slotparams = json.loads(rs['slotparameters'])
1449                                ts.fallbackplaylist = rs['fallbackplaylist']
1450                                res.append(ts)
1451                        return res
1452                except MySQLdb.Error, e:
1453                        raise RadioMateDAOException(e.args)
1454
1455        def getNext(self, fromdate, n=1):
1456                "Get the next scheduled n timeslots since fromdate"
1457                try:
1458                        cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
1459                        resultdicts = self.__getNext(fromdate, n, cursor)
1460                        cursor.close()
1461
1462                        self.logger.debug("Number of timeslot rows fetched: %d" % len(resultdicts))
1463
1464                        if len(resultdicts) == 0:
1465                                return None 
1466
1467                        res = []
1468                        for rs in resultdicts:
1469                                ts = TimeSlot()
1470                                ts.id = rs['id']
1471                                ts.creator = rs['creator']
1472                                ts.slottype = rs['slottype']
1473                                ts.title = rs['title']
1474                                ts.description = rs['description']
1475                                ts.comment = rs['comment']
1476                                ts.tags = rs['tags']
1477                                ts.setBeginningDateTime(rs['beginningtime'])
1478                                ts.setEndingDateTime(rs['endingtime'])
1479                                ts.slotparams = json.loads(rs['slotparameters'])
1480                                ts.fallbackplaylist = rs['fallbackplaylist']
1481                                res.append(ts)
1482
1483                        if len(res) == 1:
1484                                return res[0]
1485                        return res
1486                except MySQLdb.Error, e:
1487                        raise RadioMateDAOException(e.args)
1488
1489
Note: See TracBrowser for help on using the browser.