forked from smiley/steamapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
191 lines (168 loc) · 7.38 KB
/
app.py
File metadata and controls
191 lines (168 loc) · 7.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
__author__ = 'SmileyBarry'
from .core import APIConnection, SteamObject, store
from .decorators import cached_property, INFINITE
class SteamApp(SteamObject):
def __init__(self, appid, name=None, owner=None):
self._id = appid
if name is not None:
import time
self._cache = dict()
self._cache['name'] = (name, time.time())
# Normally, the associated userid is also the owner.
# That would not be the case if the game is borrowed, though. In that case, the object creator
# usually defines attributes accordingly. However, at this time we can't ask the API "is this
# game borrowed?", unless it's the actively-played game, so this distinction isn't done in the
# object's context, but in the object creator's context.
self._owner = owner
self._userid = self._owner
# Factory methods
@staticmethod
def from_api_response(api_json, associated_userid=None):
"""
Create a new SteamApp instance from an APIResponse object.
:param api_json: The raw JSON returned by the API, in "APIResponse" form.
:type api_json: steamapi.core.APIResponse
:param associated_userid: A user ID associated to this game, if applicable. This can be the user who played the
app/game, or its owner if it is borrowed, depending on context.
:type associated_userid: long
:return: a new SteamApp instance
:rtype: SteamApp
"""
if 'appid' not in api_json:
# An app ID is a bare minimum.
raise ValueError(
"An app ID is required to create a SteamApp object.")
appid = api_json.appid
name = None
if 'name' in api_json:
name = api_json.name
return SteamApp(appid, name, associated_userid)
@cached_property(ttl=INFINITE)
def _schema(self):
return APIConnection().call("ISteamUserStats", "GetSchemaForGame", "v2", appid=self._id)
@property
def appid(self):
return self._id
@cached_property(ttl=INFINITE)
def achievements(self):
global_percentages = APIConnection().call("ISteamUserStats", "GetGlobalAchievementPercentagesForApp", "v0002",
gameid=self._id)
if self._userid is not None:
# Ah-ha, this game is associated to a user!
userid = self._userid
unlocks = APIConnection().call("ISteamUserStats",
"GetUserStatsForGame",
"v2",
appid=self._id,
steamid=userid)
if 'achievements' in unlocks.playerstats:
unlocks = [associated_achievement.name
for associated_achievement in unlocks.playerstats.achievements
if associated_achievement.achieved != 0]
else:
userid = None
unlocks = None
achievements_list = []
if 'availableGameStats' not in self._schema.game:
# No stat data -- at all. This is a hidden app.
return achievements_list
for achievement in self._schema.game.availableGameStats.achievements:
achievement_obj = SteamAchievement(
self._id, achievement.name, achievement.displayName, userid)
achievement_obj._cache = {}
if achievement.hidden == 0:
store(achievement_obj, "is_hidden", False)
else:
store(achievement_obj, "is_hidden", True)
for global_achievement in global_percentages.achievementpercentages.achievements:
if global_achievement.name == achievement.name:
achievement_obj.unlock_percentage = global_achievement.percent
achievements_list += [achievement_obj]
if unlocks is not None:
for achievement in achievements_list:
if achievement.apiname in unlocks:
store(achievement, "is_achieved", True)
else:
store(achievement, "is_achieved", False)
return achievements_list
@cached_property(ttl=INFINITE)
def name(self):
if 'gameName' in self._schema.game:
return self._schema.game.gameName
else:
return "<Unknown>"
@cached_property(ttl=INFINITE)
def owner(self):
if self._owner is None:
return self._userid
else:
return self._owner
def __str__(self):
return self.name
def __hash__(self):
# Don't just use the ID so ID collision between different types of
# objects wouldn't cause a match.
return hash(('app', self.id))
class SteamAchievement(SteamObject):
def __init__(self, linked_appid, apiname, displayname, linked_userid=None):
"""
Initialise a new instance of SteamAchievement. You shouldn't create one yourself, but from
"SteamApp.achievements" instead.
:param linked_appid: The AppID associated with this achievement.
:type linked_appid: int
:param apiname: The API-based name of this achievement. Usually a string.
:type apiname: str or unicode
:param displayname: The achievement's user-facing name.
:type displayname: str or unicode
:param linked_userid: The user ID this achievement is linked to.
:type linked_userid: int
:return: A new SteamAchievement instance.
"""
self._appid = linked_appid
self._id = apiname
self._displayname = displayname
self._userid = linked_userid
self.unlock_percentage = 0.0
def __hash__(self):
# Don't just use the ID so ID collision between different types of
# objects wouldn't cause a match.
return hash((self.id, self._appid))
@property
def appid(self):
return self._appid
@property
def name(self):
return self._displayname
@property
def apiname(self):
return self._id
@cached_property(ttl=INFINITE)
def is_hidden(self):
response = APIConnection().call("ISteamUserStats",
"GetSchemaForGame",
"v2",
appid=self._appid)
for achievement in response.game.availableGameStats.achievements:
if achievement.name == self._id:
if achievement.hidden == 0:
return False
else:
return True
@cached_property(ttl=INFINITE)
def is_unlocked(self):
if self._userid is None:
raise ValueError("No Steam ID linked to this achievement!")
response = APIConnection().call("ISteamUserStats",
"GetPlayerAchievements",
"v1",
steamid=self._userid,
appid=self._appid,
l="English")
for achievement in response.playerstats.achievements:
if achievement.apiname == self._id:
if achievement.achieved == 1:
return True
else:
return False
# Cannot be found.
return False