SHOW:
|
|
- or go back to the newest paste.
| 1 | #!/usr/bin/env python | |
| 2 | ||
| 3 | # Class handling MasterControl Data | |
| 4 | ||
| 5 | # Author: YoungJules with thanks to Matt and the guys at ENTS for the original MasterControl concept. | |
| 6 | ||
| 7 | # Class is a singleton and takes care of making a connection to the db and creating a cursor | |
| 8 | # This is part of a pluggable architecture which simplifies use of different databases and other data sources | |
| 9 | # To enable another database in MasterControl (e.g. postgreSQL) | |
| 10 | # Clone MasterControlMySQL.py to MasterControlPostgres.py | |
| 11 | # Adjust imports | |
| 12 | # Adjust database connection params in connect() | |
| 13 | # Adjust SQL statements where required (e.g. postgreSQL may have different syntax for joins...) | |
| 14 | # Remove MasterControlMySQL.py from application path and rerun RFIDServer | |
| 15 | # Using other data sources (flat files, excel...) | |
| 16 | # Follow pattern as above and adjust subroutines to get data from other datasource/update other datasource | |
| 17 | # Ensure routines returning a 'row' return an appropriate array of data | |
| 18 | # If you don't need to close anything at exit, just create a close() with pass, and similar for connect() | |
| 19 | ||
| 20 | # Example usage: | |
| 21 | # row = MCData().getMember( '117877', 'FobNumber' ) | |
| 22 | ||
| 23 | # Available functions: | |
| 24 | # getMember( fob number, fob field name ) | |
| 25 | # getLastUnlock( door number ) | |
| 26 | # createDoorLogFail( fob number, door number, command ) | |
| 27 | # createDoorLogAdmit( fob number, first name, last name, door number ) | |
| 28 | # getSeconds( last unlock ) | |
| 29 | # updateMember( fob number, fob field name, last unlock field name ) | |
| 30 | ||
| 31 | # Specific imports for MySQL, your mileage may vary... | |
| 32 | import MySQLdb | |
| 33 | import MySQLdb.cursors | |
| 34 | ||
| 35 | class MCData(object): | |
| 36 | conn = None | |
| 37 | cursor = None | |
| 38 | ||
| 39 | """Use to create a singleton""" | |
| 40 | def __new__(cls, *args, **kwds): | |
| 41 | """ | |
| 42 | >>> s = MCData() | |
| 43 | >>> p = MCData() | |
| 44 | >>> id(s) == id(p) | |
| 45 | True | |
| 46 | """ | |
| 47 | self = "__self__" | |
| 48 | if not hasattr(cls, self): | |
| 49 | instance = object.__new__(cls) | |
| 50 | instance.init(*args, **kwds) | |
| 51 | setattr(cls, self, instance) | |
| 52 | return getattr(cls, self) | |
| 53 | ||
| 54 | - | #return conn, cursor |
| 54 | + | |
| 55 | self.connect() | |
| 56 | - | def close( self, conn, cursor ): |
| 56 | + | |
| 57 | def connect( self ): | |
| 58 | # Information about the database | |
| 59 | database = "ENTS" | |
| 60 | table = "members" | |
| 61 | hostaddr = "localhost" | |
| 62 | username = "mastercontrol" | |
| 63 | - | print "getLastUnlock" |
| 63 | + | |
| 64 | password = "pass" | |
| 65 | self.conn = MySQLdb.connect ( host = hostaddr, user = username, passwd = password, db = database, cursorclass=MySQLdb.cursors.DictCursor ) | |
| 66 | self.cursor = self.conn.cursor() | |
| 67 | - | print "getLastUnlock returning row:" |
| 67 | + | |
| 68 | - | print row |
| 68 | + | def close( self ): |
| 69 | self.cursor.close() | |
| 70 | self.conn.close() | |
| 71 | ||
| 72 | - | print "getMember" |
| 72 | + | |
| 73 | # We match FobNumber on the members table with CardNum on the DoorLog table and search based on door number | |
| 74 | def getLastUnlock( self, doorNum ): | |
| 75 | # We use an inner join because we want to find at least one match on both tables | |
| 76 | self.cursor.execute ("SELECT * from DoorLog inner join members ON members.FobNumber=DoorLog.CardNum where DoorNum = '"+str(doorNum)+"' order by EventDateTime DESC")
| |
| 77 | - | #no match for that user cardNum, send |
| 77 | + | |
| 78 | - | #server.serve_forever()back fail message |
| 78 | + | #print "getLastUnlock returning row:" |
| 79 | #print row | |
| 80 | - | #print Exception |
| 80 | + | |
| 81 | ||
| 82 | def getMember( self, fobNumber, fobField ): | |
| 83 | self.cursor.execute ("SELECT * from members where "+fobField+" = '" + fobNumber+"'")
| |
| 84 | - | print "createDoorLogFail" |
| 84 | + | |
| 85 | row = self.cursor.fetchone() #get the record for the current cardnum | |
| 86 | except ValueError: #Exception: | |
| 87 | #TODO: Something better than just printing a message! | |
| 88 | print "Major Failure \n" | |
| 89 | return row | |
| 90 | - | print "createDoorLogAdmit" |
| 90 | + | |
| 91 | def createDoorLogFail( self, fobNumber, doorNumber, cmd ): | |
| 92 | self.cursor.execute("insert into DoorLog values ("+fobNumber+
| |
| 93 | ",'"+fobNumber+" Not in database: "+cmd+ | |
| 94 | "','"+doorNumber+"',now(),NULL)") | |
| 95 | ||
| 96 | - | print "getSeconds" |
| 96 | + | |
| 97 | self.cursor.execute("insert into DoorLog values ("+fobNumber+
| |
| 98 | ",'"+firstName+" "+lastName+" unlocked door "+doorNumber+ | |
| 99 | "','"+doorNumber+"',now(),NULL)") | |
| 100 | ||
| 101 | def getSeconds( self, lastUnlock ): | |
| 102 | self.cursor.execute("select timestampdiff(second,'"+lastUnlock+"',now()) as seconds")
| |
| 103 | seconds = self.cursor.fetchone()['seconds'] | |
| 104 | - | print "updateMember" |
| 104 | + | |
| 105 | seconds = 2000 | |
| 106 | return seconds | |
| 107 | ||
| 108 | def updateMember( self, fobNumber, fobField, lastUnlockField ): | |
| 109 | self.cursor.execute("update members set "+lastUnlockField+" = now() where "+fobField+" = '"+fobNumber+"'") |