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
|
import re
import os
import time
import sys
import urllib, urllib2
from subprocess import Popen, PIPE
Request = urllib2.Request
urlencode = urllib.urlencode
urlopen = urllib2.urlopen
from Config import WORKING_DIR, MAX_SIZE, \
SPECIAL_DOWNLOADERS, SPECIAL_DOWNLOADERS_MAX_SIZE, \
BIN_IDENTIFY
class BadParamError(Exception):
pass
class Params(object):
def __init__(self, classname="", **kwargs):
self._working_dir = WORKING_DIR
self._now = kwargs.get("now", str(int(time.time())));
self._classname = classname
for key, value in kwargs.items():
setattr(self, key, value)
def __iter__(self):
for key, value in vars(self).iteritems():
yield key, value
def err_warn(self, s, error=None):
self._error_log(s, error=error);
raise BadParamError("%s - %s" % (self._classname, s))
def __getattr__(self, key):
try:
return self.__getattribute__(key);
except AttributeError:
return None
def err_fatal(self, s, error=None):
self._log(s, error, fatal=True);
sys.exit(1);
def set_val(self, key, value, value_type=None, enum_values=None):
try:
if value_type == "color":
value = self._color_sanitize(value)
elif value_type == "float":
value = float(value)
elif value_type == "int":
value = int(value)
elif value_type == "bool":
value = self._bool_correct(str(value))
elif value_type == "string":
value = self._sanitize(str(value))
elif value_type == "img_url":
_filename = self._filename_temporary(key)
_path = os.path.join(self._working_dir, _filename)
self._image_download(value, _path)
_mimetype = self._image_mimetype(_path)
value = {
'url': value,
'path': _path,
'mimetype' : _mimetype
}
elif value_type == "enum":
if value not in enum_values:
raise ValueError
self.__setattr__(key, value)
except Exception as e:
self.err_warn("key: %s value: %s" % (key, value), error=str(e))
def _sanitize (self, s):
return re.sub(r'\W+', '', s)
def _color_sanitize(self, s):
if s == "":
return "transparent"
if re.match('(rgba?\([0-9]+,[0-9]+,[0-9]+\))|([a-zA-Z]+)|(\#[A-Ha-h0-9]+)', s):
return s.replace(' ', '');
else:
sys.stderr.write("Not a color: {}\n".format(s))
raise ValueError
def _bool_correct(self, b):
if type(b) == str:
if re.match(r'true', b, re.IGNORECASE):
return True
elif re.match(r'false', b, re.IGNORECASE):
return False
elif type(b) == bool:
return b
raise ValueError
def _filename_temporary(self, s):
return "_tmp-{}-{}_{}".format(self._classname, self._now, s)
def _error_log(self, s, error=None, fatal=False):
message = "ERROR - BAD PARAM"
if fatal: message += "- [FATAL] -"
sys.stderr.write("{}:{} - {}\n".format(message, self._classname, s))
if error:
sys.stderr.write("PARAM ERROR: {}\n".format(str(error)))
def _image_download(self, url, path):
max_size = MAX_SIZE
if self.username in SPECIAL_DOWNLOADERS:
max_size = SPECIAL_DOWNLOADERS_MAX_SIZE
try:
self._download(url, path, max_size=max_size)
except Exception as e:
self.err_warn("Download failed");
def _browser_request (self, url, data=None):
headers = {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
'Accept': '*/*',
}
try:
req = Request(url, data, headers)
response = urlopen(req)
except IOError as e:
if hasattr(e, 'code'):
sys.stderr.write( 'browser request error: %s - ERROR %s' % (url, e.code) )
raise IOError
return response
def _download(self, url, destination, max_size=MAX_SIZE):
response = self._browser_request(url, None)
rawimg = response.read()
if len(rawimg) == 0:
self.err_warn("got zero-length file")
if len(rawimg) > max_size:
self.err_warn("file too big: max size {} KB / {} is {} KB".format(
str(MAX_SIZE/1024),
destination,
str(len(rawimg)/1024)
)
)
f = open(destination, "w")
f.write(rawimg)
f.close()
def _image_mimetype(self, f):
try:
mimetype = Popen(
[BIN_IDENTIFY, f], stdout=PIPE
).communicate()[0].split(" ")[1].lower()
return mimetype
except Exception as e:
sys.stderr.write("couldn't determine mimetype\n")
raise e;
|