Achievements: new dumb feature, add irc achievements
stats on users are tracked, and achievements are defined by writing sql queries against those stats. silly fun
This commit is contained in:
		
							parent
							
								
									8c1ffc54ba
								
							
						
					
					
						commit
						ef66c855f3
					
				
							
								
								
									
										479
									
								
								modules/Achievements.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								modules/Achievements.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,479 @@ | |||||||
|  | """ | ||||||
|  | Achievements - gamifying IRC | ||||||
|  | Copyright (C) 2011  Brian S. Stephan | ||||||
|  | 
 | ||||||
|  | This program is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU General Public License | ||||||
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import re | ||||||
|  | import sqlite3 | ||||||
|  | import thread | ||||||
|  | import time | ||||||
|  | 
 | ||||||
|  | from Module import Module | ||||||
|  | 
 | ||||||
|  | from extlib import irclib | ||||||
|  | 
 | ||||||
|  | __author__ = "Brian S. Stephan" | ||||||
|  | __copyright__ = "Copyright 2011, Brian S. Stephan" | ||||||
|  | __credits__ = ["Brian S. Stephan", "#lh"] | ||||||
|  | __license__ = "GPL" | ||||||
|  | __version__ = "0.1" | ||||||
|  | __maintainer__ = "Brian S. Stephan" | ||||||
|  | __email__ = "bss@incorporeal.org" | ||||||
|  | __status__ = "Development" | ||||||
|  | 
 | ||||||
|  | class Achievements(Module): | ||||||
|  | 
 | ||||||
|  |     """Give out achievements for doing stuff on IRC, because why not.""" | ||||||
|  | 
 | ||||||
|  |     class AchievementsSettings(): | ||||||
|  | 
 | ||||||
|  |         """Track system settings.""" | ||||||
|  | 
 | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     def __init__(self, irc, config, server): | ||||||
|  |         """Set up trigger regexes.""" | ||||||
|  | 
 | ||||||
|  |         # TODO | ||||||
|  |         joinpattern = '^!achievements\s+join$' | ||||||
|  |         leavepattern = '^!achievements\s+leave$' | ||||||
|  |         infopattern = '^!achievements\s+info\s+(.*)$' | ||||||
|  |         rankpattern = '^!achievements\s+rank\s+(.*)$' | ||||||
|  | 
 | ||||||
|  |         self.joinre = re.compile(joinpattern) | ||||||
|  |         self.leavere = re.compile(leavepattern) | ||||||
|  |         self.infore = re.compile(infopattern) | ||||||
|  |         self.rankre = re.compile(rankpattern) | ||||||
|  | 
 | ||||||
|  |         Module.__init__(self, irc, config, server) | ||||||
|  | 
 | ||||||
|  |         self.connection = None | ||||||
|  |         self.next_achievements_scan = 0 | ||||||
|  |         thread.start_new_thread(self.thread_do, ()) | ||||||
|  | 
 | ||||||
|  |     def db_init(self): | ||||||
|  |         """Set up the database tables, if they don't exist.""" | ||||||
|  | 
 | ||||||
|  |         version = self.db_module_registered(self.__class__.__name__) | ||||||
|  |         if (version == None): | ||||||
|  |             # have to create the database tables | ||||||
|  |             db = self.get_db() | ||||||
|  |             try: | ||||||
|  |                 version = 1 | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_player ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         nick TEXT NOT NULL UNIQUE, | ||||||
|  |                         userhost TEXT NOT NULL DEFAULT '', | ||||||
|  |                         is_playing INTEGER NOT NULL DEFAULT 0, | ||||||
|  |                         last_seen_time TEXT DEFAULT CURRENT_TIMESTAMP | ||||||
|  |                     )''') | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_event ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         player_id INTEGER NOT NULL, | ||||||
|  |                         event TEXT NOT NULL, | ||||||
|  |                         target TEXT, | ||||||
|  |                         msg_len INTEGER, | ||||||
|  |                         event_time TEXT DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |                         FOREIGN KEY(player_id) REFERENCES achievements_player(id) | ||||||
|  |                     )''') | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_achievement ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         name TEXT NOT NULL, | ||||||
|  |                         desc TEXT NOT NULL, | ||||||
|  |                         query TEXT NOT NULL | ||||||
|  |                     )''') | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_log ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         player_id INTEGER NOT NULL, | ||||||
|  |                         achievement_id INTEGER NOT NULL, | ||||||
|  |                         event_time TEXT DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |                         FOREIGN KEY(player_id) REFERENCES achievements_player(id), | ||||||
|  |                         FOREIGN KEY(achievement_id) REFERENCES achievements_achievement(id) | ||||||
|  |                     )''') | ||||||
|  |                 db.commit() | ||||||
|  |                 db.close() | ||||||
|  |                 self.db_register_module_version(self.__class__.__name__, version) | ||||||
|  |             except sqlite3.Error as e: | ||||||
|  |                 db.rollback() | ||||||
|  |                 db.close() | ||||||
|  |                 print("sqlite error: " + str(e)) | ||||||
|  |                 raise | ||||||
|  |         if (version < 2): | ||||||
|  |             db = self.get_db() | ||||||
|  |             try: | ||||||
|  |                 version = 2 | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_config ( | ||||||
|  |                         channel TEXT NOT NULL | ||||||
|  |                     )''') | ||||||
|  |                 db.commit() | ||||||
|  |                 db.close() | ||||||
|  |                 self.db_register_module_version(self.__class__.__name__, version) | ||||||
|  |             except sqlite3.Error as e: | ||||||
|  |                 db.rollback() | ||||||
|  |                 db.close() | ||||||
|  |                 print("sqlite error: " + str(e)) | ||||||
|  |                 raise | ||||||
|  |         if (version < 3): | ||||||
|  |             db = self.get_db() | ||||||
|  |             try: | ||||||
|  |                 version = 3 | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_filter ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         filter TEXT NOT NULL | ||||||
|  |                     )''') | ||||||
|  |                 db.execute(''' | ||||||
|  |                     CREATE TABLE achievements_filter_log ( | ||||||
|  |                         id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||||
|  |                         filter_id INTEGER NOT NULL, | ||||||
|  |                         event_id INTEGER NOT NULL, | ||||||
|  |                         FOREIGN KEY(filter_id) REFERENCES achievements_filter(id), | ||||||
|  |                         FOREIGN KEY(event_id) REFERENCES achievements_event(id) | ||||||
|  |                     )''') | ||||||
|  |                 db.commit() | ||||||
|  |                 db.close() | ||||||
|  |                 self.db_register_module_version(self.__class__.__name__, version) | ||||||
|  |             except sqlite3.Error as e: | ||||||
|  |                 db.rollback() | ||||||
|  |                 db.close() | ||||||
|  |                 print("sqlite error: " + str(e)) | ||||||
|  |                 raise | ||||||
|  | 
 | ||||||
|  |     def register_handlers(self): | ||||||
|  |         """Handle all sorts of things to track.""" | ||||||
|  | 
 | ||||||
|  |         self.server.add_global_handler('pubmsg', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('pubnotice', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('privmsg', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('privnotice', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('join', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('kick', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('mode', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('part', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('quit', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('invite', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('action', self.track_irc_event) | ||||||
|  |         self.server.add_global_handler('topic', self.track_irc_event) | ||||||
|  | 
 | ||||||
|  |         self.server.add_global_handler('pubmsg', self.on_pub_or_privmsg) | ||||||
|  |         self.server.add_global_handler('privmsg', self.on_pub_or_privmsg) | ||||||
|  | 
 | ||||||
|  |     def unregister_handlers(self): | ||||||
|  |         self.server.remove_global_handler('pubmsg', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('pubnotice', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('privmsg', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('privnotice', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('join', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('kick', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('mode', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('part', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('quit', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('invite', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('action', self.track_irc_event) | ||||||
|  |         self.server.remove_global_handler('topic', self.track_irc_event) | ||||||
|  | 
 | ||||||
|  |         self.server.remove_global_handler('pubmsg', self.on_pub_or_privmsg) | ||||||
|  |         self.server.remove_global_handler('privmsg', self.on_pub_or_privmsg) | ||||||
|  | 
 | ||||||
|  |     def track_irc_event(self, connection, event): | ||||||
|  |         """Put events in the database.""" | ||||||
|  | 
 | ||||||
|  |         self.connection = connection | ||||||
|  | 
 | ||||||
|  |         if event.source(): | ||||||
|  |             if event.source().find('!') >= 0: | ||||||
|  |                 nick = irclib.nm_to_n(event.source()) | ||||||
|  |                 userhost = irclib.nm_to_uh(event.source()) | ||||||
|  |                 print('good: ' + nick + ' ' + userhost + ' ' + event.eventtype() + ' ' + str(event.target())) | ||||||
|  |                 if event.arguments(): | ||||||
|  |                     msg = event.arguments()[0] | ||||||
|  |                     msg_len = len(event.arguments()[0]) | ||||||
|  |                 else: | ||||||
|  |                     msg = '' | ||||||
|  |                     msg_len = 0 | ||||||
|  | 
 | ||||||
|  |                 player_id = self._get_or_add_player(nick, userhost) | ||||||
|  |                 self._add_event(player_id, event.eventtype(), event.target(), msg, msg_len) | ||||||
|  |             else: | ||||||
|  |                 print('bad: ' + event.source() + ' ' + event.eventtype()) | ||||||
|  |         else: | ||||||
|  |             print('really bad: ' + event.eventtype()) | ||||||
|  | 
 | ||||||
|  |     def do(self, connection, event, nick, userhost, what, admin_unlocked): | ||||||
|  |         """Do stuff when commanded.""" | ||||||
|  | 
 | ||||||
|  |         if self.joinre.search(what): | ||||||
|  |             return self.reply(connection, event, self._join_system(nick)) | ||||||
|  |         elif self.leavere.search(what): | ||||||
|  |             return self.reply(connection, event, self._leave_system(nick)) | ||||||
|  |         elif self.infore.search(what): | ||||||
|  |             match = self.infore.search(what) | ||||||
|  |             achievement = match.group(1) | ||||||
|  |             desc = self._get_achievement_info(achievement) | ||||||
|  |             if desc: | ||||||
|  |                 return self.reply(connection, event, achievement + ': ' + desc) | ||||||
|  |         elif self.rankre.search(what): | ||||||
|  |             match = self.rankre.search(what) | ||||||
|  |             player = match.group(1) | ||||||
|  |             achievements = self._get_player_achievements(player) | ||||||
|  |             if len(achievements): | ||||||
|  |                 return self.reply(connection, event, player + ' has obtained ' + ', '.join(achievements)) | ||||||
|  | 
 | ||||||
|  |     def thread_do(self): | ||||||
|  |         """Do the scan for achievements and other miscellaneous tasks.""" | ||||||
|  | 
 | ||||||
|  |         while not self.is_shutdown: | ||||||
|  |             self._do_achievement_scan() | ||||||
|  |             time.sleep(1) | ||||||
|  | 
 | ||||||
|  |     def _get_or_add_player(self, nick, userhost): | ||||||
|  |         """Add a player to the database, or update the existing one, and return the id.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             cur = db.cursor() | ||||||
|  |             statement = ''' | ||||||
|  |                 INSERT OR IGNORE INTO achievements_player (nick) VALUES (?)''' | ||||||
|  |             cur.execute(statement, (nick,)) | ||||||
|  |             statement = ''' | ||||||
|  |                 UPDATE achievements_player SET userhost = ?, last_seen_time = CURRENT_TIMESTAMP | ||||||
|  |                 WHERE nick = ?''' | ||||||
|  |             cur.execute(statement, (userhost, nick)) | ||||||
|  |             db.commit() | ||||||
|  |             statement = '''SELECT id FROM achievements_player WHERE nick = ?''' | ||||||
|  |             cur = db.execute(statement, (nick,)) | ||||||
|  |             result = cur.fetchone() | ||||||
|  |             db.close() | ||||||
|  |             return result['id'] | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _add_event(self, player_id, event, target, msg, msg_len): | ||||||
|  |         """Add an event to the log.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             cur = db.cursor() | ||||||
|  |             statement = ''' | ||||||
|  |                 INSERT INTO achievements_event ( | ||||||
|  |                     player_id, event, target, msg_len | ||||||
|  |                 ) VALUES (?, ?, ?, ?) | ||||||
|  |                 ''' | ||||||
|  |             cur.execute(statement, (player_id, event, target, msg_len)) | ||||||
|  |             db.commit() | ||||||
|  |             event_id = cur.lastrowid | ||||||
|  | 
 | ||||||
|  |             # now see if the event matched any filters | ||||||
|  |             query = ''' | ||||||
|  |                 SELECT id FROM achievements_filter WHERE ? REGEXP filter | ||||||
|  |                 ''' | ||||||
|  |             cursor = db.execute(query, (msg.decode('utf-8', 'replace'),)) | ||||||
|  |             results = cursor.fetchall() | ||||||
|  |             for result in results: | ||||||
|  |                 cur = db.cursor() | ||||||
|  |                 statement = ''' | ||||||
|  |                     INSERT INTO achievements_filter_log (filter_id, event_id) | ||||||
|  |                         VALUES (?, ?) | ||||||
|  |                     ''' | ||||||
|  |                 cur.execute(statement, (result['id'], event_id)) | ||||||
|  |                 db.commit() | ||||||
|  | 
 | ||||||
|  |             db.close() | ||||||
|  | 
 | ||||||
|  |             return event_id | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _get_achievements_settings(self): | ||||||
|  |         """Get the report settings.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             # get the settings | ||||||
|  |             db = self.get_db() | ||||||
|  |             query = 'SELECT channel FROM achievements_config' | ||||||
|  |             cursor = db.execute(query) | ||||||
|  |             result = cursor.fetchone() | ||||||
|  |             db.close() | ||||||
|  |             if result: | ||||||
|  |                 settings = self.AchievementsSettings() | ||||||
|  |                 settings.channel = result['channel'] | ||||||
|  | 
 | ||||||
|  |                 return settings | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _join_system(self, nick): | ||||||
|  |         """Add the appropriate nick to the game.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             cur = db.cursor() | ||||||
|  |             statement = 'UPDATE achievements_player SET is_playing = 1 WHERE nick = ?' | ||||||
|  |             cur.execute(statement, (nick,)) | ||||||
|  |             db.commit() | ||||||
|  |             db.close() | ||||||
|  |             return nick + ' joined.' | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _leave_system(self, nick): | ||||||
|  |         """Remove the appropriate nick from the game.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             cur = db.cursor() | ||||||
|  |             statement = 'UPDATE achievements_player SET is_playing = 0 WHERE nick = ?' | ||||||
|  |             cur.execute(statement, (nick,)) | ||||||
|  |             db.commit() | ||||||
|  |             db.close() | ||||||
|  |             return nick + ' left.' | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _add_player_to_achievement_log(self, player_id, achievement_id): | ||||||
|  |         """Log the success of a player.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             cur = db.cursor() | ||||||
|  |             statement = 'INSERT INTO achievements_log (player_id, achievement_id) VALUES (?, ?)' | ||||||
|  |             cur.execute(statement, (player_id, achievement_id)) | ||||||
|  |             db.commit() | ||||||
|  |             db.close() | ||||||
|  |             return | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _get_achievement_info(self, achievement): | ||||||
|  |         """Return the description of a given achievement.""" | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             query = 'SELECT desc FROM achievements_achievement WHERE name = ?' | ||||||
|  |             cursor = db.execute(query, (achievement,)) | ||||||
|  |             result = cursor.fetchone() | ||||||
|  |             db.close() | ||||||
|  |             if result: | ||||||
|  |                 return result['desc'] | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _get_player_achievements(self, nick): | ||||||
|  |         """Return the achievements the nick has.""" | ||||||
|  | 
 | ||||||
|  |         achievements = [] | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             query = ''' | ||||||
|  |                 SELECT a.name FROM achievements_achievement a | ||||||
|  |                     INNER JOIN achievements_log l ON l.achievement_id = a.id | ||||||
|  |                     INNER JOIN achievements_player p ON p.id = l.player_id | ||||||
|  |                     WHERE p.nick = ? | ||||||
|  |                 ''' | ||||||
|  |             cursor = db.execute(query, (nick,)) | ||||||
|  |             results = cursor.fetchall() | ||||||
|  |             db.close() | ||||||
|  |             for result in results: | ||||||
|  |                 achievements.append(result['name']) | ||||||
|  | 
 | ||||||
|  |             return achievements | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |     def _do_achievement_scan(self): | ||||||
|  |         """Run the queries in the database, seeing if anyone new has an achievement.""" | ||||||
|  | 
 | ||||||
|  |         # don't do anything the first time | ||||||
|  |         if self.next_achievements_scan == 0: | ||||||
|  |             self.next_achievements_scan = time.time() + 300 | ||||||
|  | 
 | ||||||
|  |         if self.next_achievements_scan < time.time(): | ||||||
|  |             self.next_achievements_scan = time.time() + 300 | ||||||
|  | 
 | ||||||
|  |             if self.connection is None: | ||||||
|  |                 return | ||||||
|  | 
 | ||||||
|  |             settings = self._get_achievements_settings() | ||||||
|  |             channel = settings.channel | ||||||
|  |             achievers = self._query_for_new_achievers() | ||||||
|  |             for achiever in achievers: | ||||||
|  |                 self.sendmsg(self.connection, channel, achiever[0] + ' achieved ' + achiever[1] + '!') | ||||||
|  | 
 | ||||||
|  |     def _query_for_new_achievers(self): | ||||||
|  |         """Get new achievement earners for each achievement.""" | ||||||
|  | 
 | ||||||
|  |         achievers = [] | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             db = self.get_db() | ||||||
|  |             query = 'SELECT id, name, query FROM achievements_achievement' | ||||||
|  |             cursor = db.execute(query) | ||||||
|  |             achievements = cursor.fetchall() | ||||||
|  | 
 | ||||||
|  |             for achievement in achievements: | ||||||
|  |                 print('checking achievement:[' + achievement['name'] + ']') | ||||||
|  |                 query = ''' | ||||||
|  |                     SELECT p.id, p.nick FROM achievements_player p WHERE | ||||||
|  |                         p.nick IN ( | ||||||
|  |                     ''' | ||||||
|  |                 query = query + achievement['query'] | ||||||
|  |                 query = query + ''' | ||||||
|  |                     ) AND p.is_playing = 1 | ||||||
|  |                         AND p.id NOT IN ( | ||||||
|  |                             SELECT player_id FROM achievements_log l | ||||||
|  |                                 INNER JOIN achievements_achievement a | ||||||
|  |                                     ON a.id = l.achievement_id | ||||||
|  |                                 WHERE a.name = ? | ||||||
|  |                         ) | ||||||
|  |                     ''' | ||||||
|  |                 cursor = db.execute(query, (achievement['name'],)) | ||||||
|  |                 ach_achievers = cursor.fetchall() | ||||||
|  | 
 | ||||||
|  |                 for ach_achiever in ach_achievers: | ||||||
|  |                     print('name:[' + ach_achiever['nick'] + '] achievement:[' + achievement['name'] + ']') | ||||||
|  |                     self._add_player_to_achievement_log(ach_achiever['id'], achievement['id']) | ||||||
|  |                     achievers.append((ach_achiever['nick'], achievement['name'])) | ||||||
|  | 
 | ||||||
|  |             db.close() | ||||||
|  |             return achievers | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             db.close() | ||||||
|  |             print('sqlite error: ' + str(e)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  | # vi:tabstop=4:expandtab:autoindent | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user