update
[archive.git] / Apkawa / godville.net / godvilleclient.py
blob772ffe1d2541a2adafa9d36cf529f2182f2a652e
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 ###
4 #Client app for zero player game godville.net
5 #Copyright (C) 2009 Apkawa
7 #This program is free software; you can redistribute it and/or
8 #modify it under the terms of the GNU General Public License
9 #as published by the Free Software Foundation; either version 2
10 #of the License, or (at your option) any later version.
12 #This program is distributed in the hope that it will be useful,
13 #but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 #GNU General Public License for more details.
17 #You should have received a copy of the GNU General Public License
18 #along with this program; if not, write to the Free Software
19 #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #You can contact author by email apkawa@gmail.com
22 ###
23 import httplib, urllib, urllib2
24 import json
25 import re
27 class MyRedirectHandler(urllib2.HTTPRedirectHandler):
28 def http_error_302(self, req, fp, code, msg, headers):
29 pass
30 urllib2_30x = urllib2.build_opener( MyRedirectHandler )
33 class ParsePage:
34 cookie = None
35 def __init__(self):
36 import html5lib
37 self.headers= {
38 'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1) Gecko/20090710 Firefox/3.5 (Swiftfox) GTB5',
39 'Cookie':'',
41 pass
42 def auth(self, username, password):
43 url = 'http://www.godville.net/login/login'
44 __headers = self.headers
45 __headers.update( {'Referer':'http://www.godville.net/login'} )
46 post_data ={
47 'username': username,
48 'password': password,
49 'commit':'Я уже бог!',
50 'save_login':'true',
52 post_data = urllib.urlencode( post_data )
53 req = urllib2.Request( url, post_data, __headers )
54 try:
55 u = urllib2_30x.open( req)
56 except urllib2.HTTPError, e:
57 if e.code == 302:
58 self.cookie = e.headers.get('Set-Cookie')
59 self.headers.update( {'Cookie': self.cookie } )
60 else:
61 raise Exception('Auth falled')
63 def get_main_page(self):
64 #url = 'http://www.godville.net/hero'
65 __headers = self.headers
66 __headers.update({
67 'Accept':'text/javascript, text/html, application/xml, text/xml, */*',
68 'X-Requested-With':'XMLHttpRequest',
69 'X-Prototype-Version':'1.6.0.3',
70 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
71 } )
72 url = 'http://www.godville.net/hero/update_details'
73 post = urllib.urlencode({'':''})
74 req = urllib2.Request(url, post, __headers)
75 u = urllib2.urlopen(req)
76 self.page = u.read()
77 print unicode(self.page)
79 def parse_block(self, parser, **attrs):
80 block = parser('div',attrs)[0]
81 for line in block('div',{'class':'new_line'}):
82 print line.findAllNext(attrs={'class':'l_capt'})[0].renderContents()
83 print line.findAllNext(attrs={'class':'field_content'})[0].renderContents()
86 def parse_page(self):
87 with open('hero.html','r') as f:
88 self.page = f.read()
89 init_parser = html5lib.HTMLParser(tree=html5lib.treebuilders.getTreeBuilder("beautifulsoup"))
90 parser = init_parser.parse( self.page, 'utf-8' )
91 #print parser.prettify()
92 self.parse_block(parser, id='hero_info')
93 self.parse_block(parser, id='hero_stats')
98 class API:
99 'http://wiki.godville.net/index.php/API'
100 api_url = 'http://www.godville.net/gods/api/%s.json'
101 names_keys = {
102 u'clan':u'Гильдия',
103 u'distance':u'Столбов от столицы',
104 u'gold_approx':u'Золотых',
105 u'inventory_max_num':'',
106 u'inventory_num':u'Инвентарь',
107 u'max_health':'',
108 u'health':u'Здоровье',
109 u'name':u'Имя',
110 u'quest_progress':u'Прогресс задания',
111 u'quest':u'Задание',
112 u'level':u'Уровень',
113 u'gender':u'Пол',
114 u'godpower':u'Прана',
115 u'arena_fight':u'Сражение на арене',
116 u'inventory':u'Инвентарь',
117 u'diary_last':u'Дневник героя',
118 u'godname':u'Бог',
119 u'motto':u'Девиз',
120 u'town_name':u'Город',
121 u'exp_progress':u'Прогресс опыта',
122 u'alignment':u'Характер'
125 def __init__(self):
126 pass
127 def load(self, godname='Godville'):
128 json_url = self.api_url%godname
129 _u = urllib.urlopen( json_url)
130 json_src = _u.read()
131 if not json_src == 'Not found':
132 self.json_loads = json.loads(json_src)
133 else:
134 raise Exception('Not found godname. Please enter correct name')
135 def get_info(self):
136 return self.json_loads
137 def get_names_keys(self):
138 return self.names_keys
139 def get_name_key(self, key):
140 name = self.names_keys.get(key)
141 if name:
142 return name
143 else:
144 return key
145 def print_info(self):
146 for k,v in self.json_loads.items():
147 if k == 'inventory':
148 print self.get_name_key( k )
149 for ik,iv in v.items():
150 print '* ',ik, ', '.join( [
151 ':'.join((str(i[0]),str(i[1])) ) for i in iv.items()
153 else:
154 print k, self.get_name_key(k), ': ',v
157 class CliApp(API):
158 #http://www.pixelbeat.org/docs/terminal_colours/
159 COLOR = {
160 'level':'\033[1;33m',
161 'health':'\033[31m',
162 'items':'\033[33m',
163 'quest':'\033[1;35m'
165 ENDC = '\033[0m'
166 def __init__(self, name):
167 self.name = name
168 pass
169 def corored_text(self, text, color):
170 return ''.join( (color, text, self.ENDC ) )
171 def progress(self, current, max, segments=30,full='=', none=' ' ):
173 current_segments = (current*segments)/max
174 return '['+''.join(
175 [full for i in xrange( current_segments-1) ]
176 )+'|'+''.join(
177 [ none for i in xrange( segments-current_segments)]
178 )+']'
180 def make_out(self):
181 __out = u'''Бог: %(godname)s
182 Имя: %(name)s
183 Пол: %(gender)s
184 Девиз: %(motto)s
185 Характер: %(alignment)s
186 Гильдия: %(clan)s
187 Уровень: %(level_progress)s %(level)i
188 Инвентарь: %(inventory_progress)s %(inventory_num)i / %(inventory_max_num)i
189 Здоровье: %(health_progress)s %(health)i / %(max_health)i
190 Задание: %(quest_progress_bar)s %(quest_progress)s
191 %(quest)s
192 Золотых: %(gold_approx)s
193 %(distance)s
194 Прана: %(godpower_progress)s %(godpower)i
195 Дневник героя: %(diary_last)s
197 %(inventory)s
199 __info = self.get_info()
200 __info.update(
202 'inventory':
203 u'В карманах у героя можно найти:\n%s'%'\n'.join(
204 [ '* '+i for i in __info.get('inventory').keys()]
205 ) if __info.get('inventory') else u'В карманах у героя пусто.',
206 'distance':
207 u'Город: %10s'% __info.get('town_name') if __info.get('town_name') else u'Столбов от столицы: %10i шт'%__info.get('distance'),
208 'level_progress':
209 self.progress(__info.get('exp_progress'),100),
210 'inventory_progress':
211 self.progress(__info.get('inventory_num'),
212 __info.get('inventory_max_num')),
213 'health_progress':
214 self.progress(__info.get( 'health'),
215 __info.get('max_health'),),
216 'godpower_progress':
217 self.progress(__info.get('godpower'),100),
218 'quest_progress_bar':
219 self.progress(__info.get('quest_progress'),100),
224 _o = __out%__info
225 self.lines = len(_o.split('\n'))
226 return _o
227 def clear(self):
228 return ''.join( [ '\r' for i in xrange( self.lines )] )
231 def main(self, delay=60):
232 import time, os
233 while True:
234 os.system('clear')
235 self.load(self.name)
236 print self.make_out()
237 time.sleep(delay)
239 pass
241 if __name__ == '__main__':
242 import os
243 name = os.sys.argv[1]
244 c = CliApp(name)
245 #c.load(name)
246 #c.print_info()
247 c.main()
249 #p =ParsePage()
250 #p.auth(name,pass)
251 #p.get_main_page()
252 #p.parse_page()