1

add: initial AI support

This commit is contained in:
diSabler
2014-05-01 14:07:44 +04:00
parent 5ffac3efcf
commit e5295eb994
217 changed files with 78827 additions and 1 deletions

158
plugins/dist.py Normal file
View File

@@ -0,0 +1,158 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# --------------------------------------------------------------------------- #
# #
# Plugin for iSida Jabber Bot #
# Copyright (C) diSabler <dsy@dsy.name> #
# Copyright (C) Vit@liy <vitaliy@root.ua> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
# --------------------------------------------------------------------------- #
dist_max_search_limit = 100
dist_default_search_count = 10
def points2distance(start, end):
"""
Calculate distance (in kilometers) between two points given as (latt, long) pairs
based on Haversine formula (http://en.wikipedia.org/wiki/Haversine_formula).
"""
start_latt = math.radians(start[0])
start_long = math.radians(start[1])
end_latt = math.radians(end[0])
end_long = math.radians(end[1])
d_long = end_long - start_long
a = (math.cos(end_latt) * math.sin(d_long))**2 + (math.cos(start_latt)*math.sin(end_latt)-math.sin(start_latt)*math.cos(end_latt)*math.cos(d_long))**2
b = math.sin(start_latt)*math.sin(end_latt) + math.cos(start_latt)*math.cos(end_latt)*math.cos(d_long)
dist = math.atan2(math.sqrt(a), b) * 6372.795
dist = int(dist + 0.5)
return dist
def city_capitalize(s):
s = s.capitalize()
for k in re.findall('[ -].', s): s = s.replace(k,k.upper())
for tmp in [u'-На-', u' На ', u'-Де-', u' Де ']: s = s.replace(tmp, tmp.lower())
return s
def city(type, jid, nick, text):
parameters = text.strip().split(' ', 1)
if parameters[0] == 'add' and get_level(jid,nick)[0] == 9:
try:
tmp = parameters[1].split('\n', 1)
place = tmp[0].strip().lower().replace(' - ', '-')
if len(tmp) == 2:
coords = re.sub('[^-\.\d]+', ' ', tmp[1]).strip().split()
if abs(float(coords[0])) < 90 and abs(float(coords[1])) < 180:
if not cur_execute_fetchone('select * from dist_user where point ilike %s',(place,)):
cur_execute('insert into dist_user values (%s,%s,%s)',(place,coords[1],coords[0]))
if base_type not in ['sqlite3','mysql']:
conn.commit()
msg = L('Added!','%s/%s'%(jid,nick))
else: msg = L('This point is in database!','%s/%s'%(jid,nick))
elif len(GT('yandex_api_key')) > 60:
text = place.encode('utf-8')
url = 'http://geocode-maps.yandex.ru/1.x/?geocode=%s&key=%s&format=json&results=1' % (urllib.quote_plus(text), GT('yandex_api_key'))
j = json.loads(load_page(url))
place_ext = j['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['metaDataProperty']['GeocoderMetaData']['text']
coords = j['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos'].split()
if not cur_execute_fetchone('select * from dist_user where point ilike %s',(place,)):
cur_execute('insert into dist_user values (%s,%s,%s)',(place,coords[1],coords[0]))
if base_type not in ['sqlite3','mysql']:
conn.commit()
msg = L('Added: ','%s/%s'%(jid,nick)) + place_ext + L(' as ','%s/%s'%(jid,nick)) + '"%s"' % place
else: msg = L('This point is in database!','%s/%s'%(jid,nick))
else: msg = L('Not found Yandex.Map API. Get API-key on http://api.yandex.ru/maps/form.xml','%s/%s'%(jid,nick))
except: msg = L('What?','%s/%s'%(jid,nick))
elif parameters[0] == 'del' and get_level(jid,nick)[0] == 9:
if cur_execute_fetchone('select * from dist_user where point ilike %s',(parameters[1].lower(),)):
cur_execute('delete from dist_user where point=%s',(parameters[1].lower(),))
if base_type not in ['sqlite3','mysql']:
conn.commit()
msg = L('Deleted!','%s/%s'%(jid,nick))
else: msg = L('This point isn\'t in database!','%s/%s'%(jid,nick))
elif parameters[0] == 'map':
t = cur_execute_fetchone('select * from dist_user where point ilike %s',(parameters[1].lower(),))
if not t: t = cur_execute_fetchone('select * from dist where point ilike %s',(parameters[1].lower(),))
if t:
tmp = 'http://maps.google.com/maps?ll=%s,%s&spn=0.01,0.01&t=h&q=%s,%s' % (t[1], t[2], t[1], t[2])
try: msg = city_capitalize(parameters[1]) + L(' on the map: ','%s/%s'%(jid,nick)) + load_page(SHORT_TINYURL % enidna(tmp).decode('utf-8'))
except: msg = city_capitalize(parameters[1]) + L(' on the map: ','%s/%s'%(jid,nick)) + tmp
else: msg = L('What?','%s/%s'%(jid,nick))
elif parameters[0] == 'search':
if len(GT('yandex_api_key')) > 60:
text = parameters[1].encode('utf-8')
text_tmp = text.split(' ', 1)
if re.match('\d+$', text_tmp[0]):
results = text_tmp[0]
text = text_tmp[1]
skip = '0'
elif re.match('\d+[-: |]\d+$', text_tmp[0]):
tmp = re.sub('[-: |]', ' ', text_tmp[0]).split()
results = int(tmp[1]) - int(tmp[0]) + 1
skip = int(tmp[0]) - 1
text = text_tmp[1]
else: results, skip = '5', '0'
url = 'http://geocode-maps.yandex.ru/1.x/?geocode=%s&key=%s&format=json&results=%s&skip=%s' % (urllib.quote_plus(text), GT('yandex_api_key'), results, skip)
j = json.loads(load_page(url))
msg = ''
for object in j['response']['GeoObjectCollection']['featureMember']:
msg += object['GeoObject']['metaDataProperty']['GeocoderMetaData']['text']
msg += ' - (%s)\n' % ', '.join(object['GeoObject']['Point']['pos'].split()[::-1])
if msg: msg = '\n' + msg
else: msg = L('Not found!','%s/%s'%(jid,nick))
else: msg = L('Not found Yandex.Map API. Get API-key on http://api.yandex.ru/maps/form.xml','%s/%s'%(jid,nick))
else:
t = cur_execute_fetchone('select * from dist_user where point ilike %s',(text.strip().lower(),))
if not t:
t = cur_execute_fetchone('select * from dist where point ilike %s',(text.strip().lower(),))
if t: msg = L(u'%s - latitude: %s, longtitude: %s') % (city_capitalize(t[0]), t[1], t[2])
else: msg = L('Not found!','%s/%s'%(jid,nick))
else: msg = L('What?','%s/%s'%(jid,nick))
send_msg(type,jid,nick,msg)
def dist(type, jid, nick, text):
text,splitter,splitted,points = text.strip(),[' - ','|','\n',' '],False,''
if ' ' in text and text.split(' ',1)[0].lower() == 'search':
try:
dist_count = int(text.split(' ',2)[2])
dist_count = 1 if dist_count < 1 else dist_max_search_limit if dist_count > dist_max_search_limit else dist_count
except: dist_count = dist_default_search_count
tmp = cur_execute_fetchall('select point from dist_user where point ilike %s order by point limit %s',('%%%s%%' % text.split(' ',2)[1].lower(),dist_count))
if not tmp: tmp = cur_execute_fetchall('select point from dist where point ilike %s order by point limit %s',('%%%s%%' % text.split(' ',2)[1].lower(),dist_count))
if tmp: msg = L('Found: %s','%s/%s'%(jid,nick)) % ', '.join(map(city_capitalize, [t[0] for t in tmp]))
else: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(text.split(' ',2)[1])
else:
for tmp in splitter:
if tmp in text:
points,splitted = text.split(tmp),True
break
if splitted and len(points)==2:
t1 = cur_execute_fetchone('select * from dist_user where point ilike %s',(points[0].lower(),))
t2 = cur_execute_fetchone('select * from dist_user where point ilike %s',(points[1].lower(),))
if not t1 or not t2:
if not t1: t1 = cur_execute_fetchone('select * from dist where point ilike %s',(points[0].lower(),))
if not t2: t2 = cur_execute_fetchone('select * from dist where point ilike %s',(points[1].lower(),))
if t1 and t2: msg = L('%s km','%s/%s'%(jid,nick)) % points2distance((float(t1[1]), float(t1[2])), (float(t2[1]), float(t2[2])))
elif t1: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(points[1])
elif t2: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(points[0])
else: msg = L('Cities not found','%s/%s'%(jid,nick))
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
send_msg(type,jid,nick,msg)
global execute
execute = [(3, 'dist', dist, 2, 'Distance between cities.\ndist search city [count of cities]\ndist city1 - city2'),
(3, 'city', city, 2, 'Cities and other place-name of the world. Examples:\ncity add place-name\n[latitude, longtitude] - add city to database\ncity del place-name - delete city from database\ncity search [count of results|range of results] place-name - search city\ncity map place-name - city on the map\ncity place-name - coordinates of city')]