]> jfr.im git - irc/rizon/acid.git/commitdiff
User can bind SteamID and request status
authorMichiel <Sovereign>
Tue, 23 Sep 2014 12:47:23 +0000 (14:47 +0200)
committerAdam <redacted>
Thu, 4 Dec 2014 04:31:29 +0000 (23:31 -0500)
pyva/pyva/src/main/python/internets/api/steam.py [new file with mode: 0644]
pyva/pyva/src/main/python/internets/cmd_user.py
pyva/pyva/src/main/python/internets/internets.py
pyva/pyva/src/main/python/internets/internets_users.py

diff --git a/pyva/pyva/src/main/python/internets/api/steam.py b/pyva/pyva/src/main/python/internets/api/steam.py
new file mode 100644 (file)
index 0000000..c4e258a
--- /dev/null
@@ -0,0 +1,59 @@
+# Steam API for Internets bot
+from feed import get_json
+import requests
+from BeautifulSoup import BeautifulSoup
+from BeautifulSoup import BeautifulStoneSoup as XMLParser
+
+class Steam(object):   
+       def __init__(self, key):
+               """Initialises Steam object, sets API key."""
+               self.api_key = key
+
+       def find_user(self, steamid):
+               steam_data = {}
+               urlCommunity = 'http://steamcommunity.com/id/%s?xml=1' % steamid                
+               responseXML = XMLParser(requests.get(urlCommunity).text)
+               
+               if responseXML.response != None:                        
+                       return self.get_status(steamid)
+               else:
+                       steam_data['steamid'] = responseXML.steamid64.text
+                       steam_data['personaname'] = responseXML.steamid.text
+                       return steam_data
+
+       def get_status(self, steamid):
+               """Gets data from the steam website, returns JSON object with data."""
+               url = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s&format=json' % (self.api_key, steamid)
+               response = get_json(url)['response']['players']
+               if len(response) == 0:
+                       raise SteamException('No user found')
+               return response[0]
+
+       def get_games(self, userid):
+               """Gets list of games owned from the server, assumes userid is correct."""
+               url = 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=%s&steamid=%s&include_player_free_games=1&format=json' % (self.api_key, userid)
+               response = get_json(url)['response']
+               return response
+
+       def get_game_name(self, gameid):
+               """Gets game info from the server, assumes gameid is correct."""
+               url = 'http://steamcommunity.com/app/%s' % gameid
+               response = requests.get(url)            
+               soup = BeautifulSoup(response.text)
+               title = soup.title.string.replace("Steam Community :: ", "")            
+               return title
+
+class SteamException(Exception):
+       """Steam Exception, raised when something goes wrong when interacting with the API."""
+       def __init__(self, msg):
+               self.msg = msg
+
+       def __str__(self):
+               return str(self.msg)
+
+class SteamUser(object):
+       """Steam User, contains a mapping of nick and steamid."""
+       __slots__ = ['nick', 'steamid']
+       def __init__(self, nick, steamid):
+               self.nick = nick
+               self.steamid = steamid
\ No newline at end of file
index b4b1a008db0b5a1920e1e70829246041f82d1804..e21c3a13cca0ffbda905f616eac4077b096db77e 100644 (file)
@@ -10,7 +10,7 @@ from api.feed import FeedError
 from api.idlerpg import IrpgPlayer
 from api.quotes import FmlException
 from api.weather import WeatherException
-
+from api.steam import SteamException
 
 def get_citystate_from_zipcode(self, zipcode):
        """Return [city,state] for the given U.S. zip code (if database has been imported)"""
@@ -21,6 +21,34 @@ def get_citystate_from_zipcode(self, zipcode):
        except:
                return None
 
+##
+# Returns colour coded test of persona state in Steam.
+##
+def get_personastate_text(self, state):
+       if state == 0:
+               # user is offline.
+               return '@c14OFFLINE@c'
+       elif state == 1:
+               # user is online
+               return '@c3ONLINE@c'
+       elif state == 2:
+               # user is busy
+               return '@c4BUSY@c'
+       elif state == 3:
+               # user is away
+               return '@c7AWAY@c'
+       elif state == 4:
+               # user is snooze
+               return '@c7SNOOZE@c'
+       elif state == 5:
+               # user is looking to trade
+               return '@c5LOOKING TO TRADE@c'
+       elif state == 6:
+               # user is looking to play
+               return '@c10LOOKING TO PLAY@c'
+       else:
+               # unknown status
+               return '@c14UNKNOWN@c'
 
 def command_weather(self, manager, opts, arg, channel, sender, userinfo):
        arg = self.get_location(opts, arg, channel, sender)
@@ -345,6 +373,107 @@ def command_imdb(self, manager, opts, arg, channel, sender, userinfo):
 @bGenre@b {r[Genre]} @sep @bDirector@b {r[Director]} @sep @bActors@b {r[Actors]} @sep @bRuntime@b {r[Runtime]} @sep""".format(r=reply))
        self.msg(channel, u'@sep @bPlot@b {r[Plot]} @sep @uhttp://www.imdb.com/title/{r[imdbID]}/@u @sep'.format(r=reply))
 
+#
+# Registers the user's steam ID and links it to his/her nickname.
+#
+def command_register_steam(self, manager, opts, arg, channel, sender, userinfo):
+       arg = arg.strip()
+       try:            
+               steam_data = self.steam.find_user(arg)
+               self.notice(sender, u'Steam ID registered, current personaname: {name}'.format(name = steam_data['personaname']))
+               self.users.set(sender, 'steamid', steam_data['steamid'])
+       except SteamException as exc:
+               self.notice(sender, 'No user found')            
+
+##
+# Shows user's online status and what game he/sh is playing.
+# Game does not show when user's profile is set to private.
+##
+def command_steam(self, manager, opts, arg, channel, sender, userinfo):
+       steamuser = self.get_steamid(opts, arg, channel, sender)
+       if not steamuser:
+               return
+       steam_data = self.steam.get_status(steamuser.steamid)
+
+       if steam_data['communityvisibilitystate'] == 1:
+               # Profile is hidden
+               self.notice(sender, 'Profile is hidden. If you want to use this functionality, set your profile to Public.')
+               return
+
+       if 'games' in opts:
+               steam_games = self.steam.get_games(steamuser.steamid)           
+               playtime_forever = 0
+               playtime_2weeks = 0
+               playtime_forever_top = 0
+               game_forever = ""
+               playtime_2weeks_top = 0
+               game_2weeks = ""
+               message = u"""@sep @b{player}@b @sep""".format(player = steam_data['personaname'])
+
+               if steam_games['game_count'] == 0:
+                       # You know, because it's possible
+                       message += u""" Does not own any games. @sep"""
+                       self.msg(channel, message)
+                       return
+
+               for item in steam_games['games']:                       
+                       ptf = item['playtime_forever']                  
+                       if ptf > playtime_forever_top:
+                               game_forever = item['appid']
+                               playtime_forever_top = ptf
+                       playtime_forever += ptf
+
+                       try:
+                               ptw = item['playtime_2weeks']
+                               if ptw > playtime_2weeks_top:
+                                       game_2weeks = item['appid']
+                                       playtime_2weeks_top = ptw
+                               playtime_2weeks += ptw
+                       except Exception:
+                               #just skip it
+                               continue
+
+               message += u""" @bTotal games:@b {total} @sep @bTotal playtime:@b {ftime} hours @sep @bPlaytime last 2 weeks:@b {wtime} hours @sep""".format(
+                       total = steam_games['game_count'],
+                       ftime = round(playtime_forever / 60, 0),
+                       wtime = round(playtime_2weeks / 60, 0))
+               if game_forever != "":
+                       fgame = self.steam.get_game_name(game_forever)
+                       message += u""" @bMost played game:@b {fgame}, {ftime} hours @sep""".format(
+                               fgame = fgame,
+                               ftime = round(playtime_forever_top / 60, 0))
+               if game_2weeks != "":
+                       wgame = self.steam.get_game_name(game_2weeks)
+                       message += u""" @bMost played last 2 weeks:@b {wgame}, {wtime} hours @sep""".format(
+                               wgame = wgame,
+                               wtime = round(playtime_2weeks / 60, 0))
+               self.msg(channel, message)
+       else:
+               # Prepare message
+               message = u"""@sep @b{player}@b [{status}] @sep""".format(
+                       player = steam_data['personaname'],
+                       status = get_personastate_text(self, steam_data['personastate']))
+               if steam_data['personastate'] == 0 or steam_data['personastate'] > 7:
+                       # User is offline or unknown state
+                       # NOTE: lastlogoff is actual logoff timestamp, not "appear offline" timestamp
+                       latestdate = get_timespan(datetime.fromtimestamp(steam_data['lastlogoff']))
+                       message += u""" @bLast seen@b {latestdate} ago @sep""".format(
+                               latestdate = latestdate)
+                       self.msg(channel, message)
+               else:
+                       # user is online, busy, away, snooze, looking to trade or looking to play
+                       if 'gameextrainfo' in steam_data:
+                               message += u""" @bPlaying:@b {gamename} @sep""".format(
+                                       gamename = steam_data['gameextrainfo'])
+                               if 'gameserverip' in steam_data:
+                                       message += u""" @bPlaying on server:@b {gameserver} @sep""".format(
+                                       gameserver = steam_data['gameserverip'])
+                       else:
+                               # User is not playing a game.
+                               message += u""" Not playing anything right now @sep"""
+
+                       self.msg(channel, message)
+
 def command_lastfm(self, manager, opts, arg, channel, sender, userinfo):
        try:
                user = self.lastfm.get_user(arg)
@@ -458,6 +587,7 @@ def command_ipinfo(self, manager, opts, arg, channel, sender, userinfo):
                                map = ' http://maps.google.com/maps?q=%s,%s @sep' % (reply['latitude'], reply['longitude']) if reply['latitude'] and reply['longitude'] else ''))
        
 dice_regex = re.compile('^(?:(\d+)d)?(\d+)(?:([\+\-])(\d+))?$')
+
 def command_dice(self, manager, opts, arg, channel, sender, userinfo):
        r = dice_regex.search(arg)
        if not r:
@@ -624,6 +754,13 @@ class UserCommandManager(CommandManager):
                        
                        'fml': (command_fml, ARG_OPT, 'Displays a quote from http://www.fmylife.com', []),
                        
+                       'steam': (command_steam, ARG_OPT, 'Shows your steam information', [
+                               ('nick', '-n', 'use the steamid linked to a nick.', {'action': 'store_true'}, ARG_YES),
+                               ('games', '-g', 'shows the total games owned by nick and shows most played game.', {'action': 'store_true'}, ARG_NO)]),
+                       
+                       'regsteam': 'register_steam',
+                       'register_steam': (command_register_steam, ARG_YES, 'Registers your Steam user ID', [], 'steamid'),
+                       
                        'info': (command_internets_info, ARG_NO|ARG_OFFLINE, 'Displays version and author information', []),
                        'help': (command_internets_help, ARG_OPT|ARG_OFFLINE, 'Displays available commands and their usage', []),
                }
index 87a758d419385d5128bac9a6f165dce37d3e3d25..7d4226e2f6f9335962c68160c61a0746e1625b01 100644 (file)
@@ -20,8 +20,9 @@ import mythreading as threading
 from pseudoclient import sys_antiflood, sys_auth, sys_channels, sys_log, sys_options, cmd_manager, inviteable
 
 import cmd_admin, cmd_user, erepparser, internets_users
-from api import bing, calc, google, imdb, ipinfo, lastfm, quotes, urbandictionary, urls, weather, wolfram, words
+from api import bing, calc, google, imdb, ipinfo, lastfm, quotes, urbandictionary, urls, weather, wolfram, words, steam
 from internets_utils import *
+from api.steam import SteamUser
 
 import pyva_net_rizon_acid_core_Acidictive as Acidictive
 import pyva_net_rizon_acid_core_AcidCore as AcidCore
@@ -122,6 +123,7 @@ class internets(
                        self.weather = weather.Weather(self.config.get('internets', 'key_openweathermap'))
                        self.wolfram = wolfram.Wolfram(self.config.get('internets', 'key_wolframalpha'))
                        self.wordnik = words.Words(self.config.get('internets', 'key_wordnik'))
+                       self.steam = steam.Steam(self.config.get('internets', 'key_steam'))
                except Exception, err:
                        self.log.exception('Error initializing internets module (%s)' % err)
                        raise
@@ -339,6 +341,28 @@ class internets(
                        if 'nick' in opts:
                                self.msg(channel, 'No location found linked to nick %s.' % arg)
                        else:
-                               self.msg(channel, 'No location found linked to your nick. To link one type: @b.register_location <location>@b')
+                               self.msg(channel, 'No location found linked to your nick. To link one, type: @b%sregister_location <location>@b' % self.commands_user.get_prefix())
 
                return location
+
+       def get_steamid(self, opts, arg, channel, sender):
+               """Gets the steamid from the database."""
+               nick = None
+               steamid = None
+
+               if 'nick' in opts:
+                       nick = arg
+               else:
+                       nick = sender
+
+               steamid = self.users.get(nick, 'steamid')
+
+               if not steamid:
+                       if 'nick' in opts:
+                               self.msg(channel, 'No steamid found linked to nick %s.' % arg)
+                               return
+                       else:
+                               self.msg(channel, 'No steamid found linked to your nick. To link one, type: @b%sregister_steam <steamid>@b' % self.commands_user.get_prefix())
+                               return
+               else:
+                       return SteamUser(nick, steamid)
index 3e85d3be392fc9656c511de1cd5a9f8c18240d13..099596e3126cfddb2b0e941d45db59a34833e8d7 100644 (file)
@@ -3,6 +3,7 @@ from pseudoclient.sys_users import *
 
 class InternetsUser(CollectionEntity):
        location = None
+       steamid = None
 
        def __init__(self, id, name):
                CollectionEntity.__init__(self, id)