|
@@ -0,0 +1,78 @@
|
|
1
|
+#!/usr/bin/python
|
|
2
|
+
|
|
3
|
+import urllib2,json,sys
|
|
4
|
+from lxml.html import document_fromstring
|
|
5
|
+
|
|
6
|
+def monster_image(monster):
|
|
7
|
+ opener = urllib2.build_opener()
|
|
8
|
+ opener.addheaders = [('User-Agent', 'Mozilla/5.0')]
|
|
9
|
+ image_html = opener.open('https://www.dndbeyond.com/monsters/'+monster).read()
|
|
10
|
+# image_html = ' <a href="https://media-waterdeep.cursecdn.com/avatars/thumbnails/0/221/1000/1000/636252765234633232.jpeg" data-lightbox="Bugbear-aside" data-title="<a target='_blank' href='https://media-waterdeep.cursecdn.com/avatars/thumbnails/0/221/1000/1000/636252765234633232.jpeg' class='link link-full'>View Full Image</a>">'
|
|
11
|
+# pattern = re.compile(".*\<a href=\"([a-zA-Z0-9_\-\/\.:]+)\" data-lightbox=\"\w+-aside")
|
|
12
|
+# m = pattern.match(image_html)
|
|
13
|
+# return m.group(1) if m else "NotFound";
|
|
14
|
+ h = document_fromstring(image_html)
|
|
15
|
+ for div in h.cssselect('a'):
|
|
16
|
+ if div.get('data-lightbox') and div.get('data-lightbox').endswith('-aside'):
|
|
17
|
+ return div.get('href')
|
|
18
|
+
|
|
19
|
+def subtype(d):
|
|
20
|
+ return " (%s)"%(d) if d else ""
|
|
21
|
+
|
|
22
|
+def read_monster(monster):
|
|
23
|
+ opener = urllib2.build_opener()
|
|
24
|
+ opener.addheaders = [('User-Agent', 'Mozilla/5.0')]
|
|
25
|
+ data = json.loads(opener.open('https://api.open5e.com/monsters/'+monster).read())
|
|
26
|
+
|
|
27
|
+ monster_data = ''
|
|
28
|
+ monster_data += ' {\n'
|
|
29
|
+ monster_data += ' "count": 1,\n'
|
|
30
|
+ monster_data += ' "title": "%s",\n' % (data['name'])
|
|
31
|
+ monster_data += ' "contents": [\n'
|
|
32
|
+ monster_data += ' "subtitle | %s, %s%s, %s | %s",\n' % (data['size'][0], data['type'], subtype(data['subtype']), data['alignment'], data['challenge_rating'])
|
|
33
|
+ monster_data += ' "fill",\n'
|
|
34
|
+ monster_data += ' "rule",\n'
|
|
35
|
+ monster_data += ' "fill",\n'
|
|
36
|
+ monster_data += ' "dndstats | %s | %s | %s | %s | %s | %s",\n' % (data['strength'], data['dexterity'], data['constitution'], data['intelligence'], data['wisdom'], data['charisma'])
|
|
37
|
+ monster_data += ' "fill",\n'
|
|
38
|
+ monster_data += ' "rule",\n'
|
|
39
|
+ monster_data += ' "fill",\n'
|
|
40
|
+ def skill_func(s):
|
|
41
|
+ return "%s: %+d" % (s, int(data['skills'][s]))
|
|
42
|
+ monster_data += ' "property | Skills | %s",\n' % (', '.join(map(skill_func, data['skills'])))
|
|
43
|
+ monster_data += ' "property | Senses | %s",\n' % (data['senses'])
|
|
44
|
+ monster_data += ' "property | Languages | %s",\n' % (data['languages'])
|
|
45
|
+ monster_data += ' "fill",\n'
|
|
46
|
+ monster_data += ' "section | Abilities",\n'
|
|
47
|
+ for ability in data['special_abilities']:
|
|
48
|
+ monster_data += ' "description | %s | %s",\n' % (ability['name'], ability['desc'].replace('\n', '<br />'))
|
|
49
|
+ monster_data += ' "fill",\n'
|
|
50
|
+ monster_data += ' "section | Actions",\n'
|
|
51
|
+ for action in data['actions']:
|
|
52
|
+ monster_data += ' "description | %s | %s",\n' % (action['name'], action['desc'].replace('\n', '<br />'))
|
|
53
|
+ monster_data += ' ""\n'
|
|
54
|
+ monster_data += ' ],\n'
|
|
55
|
+ monster_data += ' "tags": [],\n'
|
|
56
|
+ monster_data += ' "color": "",\n'
|
|
57
|
+ monster_data += ' "title_size": "14",\n'
|
|
58
|
+ monster_data += ' "background_image": "%s",\n' % (monster_image(monster))
|
|
59
|
+ monster_data += ' "icon": "",\n'
|
|
60
|
+ monster_data += ' "stats": "%s|%s|%s"\n' % (data['speed']['walk'], data['hit_points'], data['armor_class'])
|
|
61
|
+ monster_data += ' }\n'
|
|
62
|
+
|
|
63
|
+ return monster_data
|
|
64
|
+
|
|
65
|
+def main():
|
|
66
|
+ if len(sys.argv) == 1:
|
|
67
|
+ print "usage: download.py monster1 [monster2...]"
|
|
68
|
+ return 1
|
|
69
|
+
|
|
70
|
+ monsters = []
|
|
71
|
+ for m in sys.argv[1:]:
|
|
72
|
+ sys.stderr.write("downloading " + m + "\n")
|
|
73
|
+ monsters.append(read_monster(m))
|
|
74
|
+
|
|
75
|
+ print("[%s]" % (",\n".join(monsters)))
|
|
76
|
+
|
|
77
|
+if __name__== "__main__":
|
|
78
|
+ main()
|