Skip to content

Commit 612046c

Browse files
author
Michael Barr
committed
Made api_key_required decorator public and updated docstring. Also added util/vdf.py for convenience, although unused in our code base.
1 parent 91f1425 commit 612046c

File tree

2 files changed

+176
-1
lines changed

2 files changed

+176
-1
lines changed

steamwebapi/util/decorators.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ def public(f):
2929
public(public) # Emulate decorating ourself (make public)
3030

3131

32+
@public
3233
class api_key_required(object):
33-
"""
34+
"""Decorator which checks to make sure the instance method has a Steam Web
35+
API Key declared.
36+
3437
"""
3538

3639
def __init__(self, method):

steamwebapi/util/vdf.py

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
"""
2+
.. module:: core
3+
:platform: Unix, Windows
4+
:synopsis: VDF (de)serialization.
5+
:synopsis: Distributed under the ISC License (see LICENSE)
6+
:synopsis: https://github.com/Lagg/steamodd
7+
8+
.. moduleauthor:: Copyright (c) 2010-2013, Anthony Garcia <[email protected]>
9+
"""
10+
# =============================================================================
11+
# >> CONSTANTS
12+
# =============================================================================
13+
STRING = '"'
14+
NODE_OPEN = '{'
15+
NODE_CLOSE = '}'
16+
BR_OPEN = '['
17+
BR_CLOSE = ']'
18+
COMMENT = '/'
19+
CR = '\r'
20+
LF = '\n'
21+
SPACE = ' '
22+
TAB = '\t'
23+
WHITESPACE = set(' \t\r\n')
24+
25+
26+
# =============================================================================
27+
# >> FUNCTIONS
28+
# =============================================================================
29+
def _symtostr(line, i, token=STRING):
30+
opening = i + 1
31+
closing = 0
32+
33+
ci = line.find(token, opening)
34+
while ci != -1:
35+
if line[ci - 1] != '\\':
36+
closing = ci
37+
break
38+
ci = line.find(token, ci + 1)
39+
40+
finalstr = line[opening:closing]
41+
return finalstr, i + len(finalstr) + 1
42+
43+
44+
def _unquotedtostr(line, i):
45+
ci = i
46+
_len = len(line)
47+
while ci < _len:
48+
if line[ci] in WHITESPACE:
49+
break
50+
ci += 1
51+
return line[i:ci], ci
52+
53+
54+
def _parse(stream, ptr=0):
55+
i = ptr
56+
laststr = None
57+
lasttok = None
58+
lastbrk = None
59+
deserialized = {}
60+
61+
while i < len(stream):
62+
c = stream[i]
63+
64+
if c == NODE_OPEN:
65+
deserialized[laststr], i = _parse(stream, i + 1)
66+
elif c == NODE_CLOSE:
67+
return deserialized, i
68+
elif c == BR_OPEN:
69+
lastbrk, i = _symtostr(stream, i, BR_CLOSE)
70+
elif c == COMMENT:
71+
if (i + 1) < len(stream) and stream[i + 1] == '/':
72+
i = stream.find('\n', i)
73+
elif c == CR or c == LF:
74+
ni = i + 1
75+
if ni < len(stream) and stream[ni] == LF:
76+
i = ni
77+
if lasttok != LF:
78+
c = LF
79+
elif c != SPACE and c != TAB:
80+
string, i = (
81+
_symtostr if c == STRING else
82+
_unquotedtostr)(stream, i)
83+
if lasttok == STRING:
84+
if laststr in deserialized and lastbrk is not None:
85+
# ignore this entry if it's the second bracketed expression
86+
lastbrk = None
87+
else:
88+
deserialized[laststr] = string
89+
# force c = STRING so that lasttok will be set properly
90+
c = STRING
91+
laststr = string
92+
else:
93+
c = lasttok
94+
95+
lasttok = c
96+
i += 1
97+
98+
return deserialized, i
99+
100+
101+
def _run_parse_encoded(string):
102+
encoded = string
103+
104+
try:
105+
encoded = string.decode("ascii")
106+
except UnicodeDecodeError:
107+
try:
108+
encoded = string.decode("utf-8")
109+
except:
110+
encoded = string.decode("utf-16")
111+
except UnicodeEncodeError:
112+
# Likely already decoded
113+
pass
114+
115+
res, ptr = _parse(encoded)
116+
return res
117+
118+
119+
def load(stream):
120+
return _run_parse_encoded(stream.read())
121+
122+
123+
def loads(string):
124+
return _run_parse_encoded(string)
125+
126+
indent = 0
127+
mult = 2
128+
129+
130+
def _i():
131+
return u' ' * (indent * mult)
132+
133+
134+
def _dump(obj):
135+
nodefmt = u'\n' + _i() + '"{0}"\n' + _i() + '{{\n{1}' + _i() + '}}\n\n'
136+
podfmt = _i() + '"{0}" "{1}"\n'
137+
lstfmt = _i() + (' ' * mult) + '"{0}" "1"'
138+
global indent
139+
140+
indent += 1
141+
142+
nodes = []
143+
for k, v in obj.items():
144+
if isinstance(v, dict):
145+
nodes.append(nodefmt.format(k, _dump(v)))
146+
else:
147+
try:
148+
try:
149+
v.isdigit
150+
nodes.append(podfmt.format(k, v))
151+
except AttributeError:
152+
lst = map(lstfmt.format, v)
153+
nodes.append(nodefmt.format(k, u'\n'.join(lst) + '\n'))
154+
except TypeError:
155+
nodes.append(podfmt.format(k, v))
156+
157+
indent -= 1
158+
159+
return u''.join(nodes)
160+
161+
162+
def _run_dump(obj):
163+
res = _dump(obj)
164+
return res.encode("utf-16")
165+
166+
167+
def dump(obj, stream):
168+
stream.write(_run_dump(obj))
169+
170+
171+
def dumps(obj):
172+
return _run_dump(obj)

0 commit comments

Comments
 (0)