7 Commits
0.1 ... 0.2

7 changed files with 154 additions and 75 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ assets/cert*
main.db
main.db-journal
settings.ini
code.png

BIN
.worker.py.swo Normal file

Binary file not shown.

BIN
.worker.py.swp Normal file

Binary file not shown.

View File

@ -1,5 +1,6 @@
import datetime as dt
class DataBase:
def __init__(self, basefile, scheme):
import sqlite3
@ -35,10 +36,10 @@ class DataBase:
return(self.execute(sql)[0][0])
def add_user(self,
username,
user_id,
first_name,
last_name):
username,
user_id,
first_name,
last_name):
date = int(dt.datetime.now().strftime("%s"))
sql = """INSERT OR IGNORE INTO
user('id', 'username', 'first_name', 'last_name', 'date')
@ -74,9 +75,9 @@ class DataBase:
date
)
self.execute(sql)
def get_top(self, user_id, conf_id, limit=10):
sql= """
sql = """
SELECT w.word, COUNT(*) as count FROM relations r
LEFT JOIN word w ON w.id = r.word_id
LEFT JOIN `user` u ON u.id = r.user_id
@ -99,7 +100,7 @@ class DataBase:
return(result)
def here(self, user_id, conf_id):
sql= """
sql = """
SELECT DISTINCT(u.username) FROM relations r
LEFT JOIN user u
ON u.id = r.user_id
@ -129,20 +130,20 @@ class DataBase:
def command(self, sql):
if 'DELETE' in sql.upper() \
or 'INSERT' in sql.upper() \
or 'UPDATE' in sql.upper() \
or 'DROP' in sql.upper() \
or 'CREATE' in sql.upper() \
or 'ALTER' in sql.upper():
or 'INSERT' in sql.upper() \
or 'UPDATE' in sql.upper() \
or 'DROP' in sql.upper() \
or 'CREATE' in sql.upper() \
or 'ALTER' in sql.upper():
return('gtfo')
try:
if 'LIMIT' in sql.upper()[-9:]:
result = self.execute(sql)
result = self.execute(sql)
else:
result = self.execute(sql + ' limit 20')
result = self.execute(sql + ' limit 20')
except Exception as err:
result = err
return(result)
def close(self):
self.conn.close()

View File

@ -12,4 +12,4 @@ db = DataBase(
scheme='assets/main.db.sql')
global worker
worker = MessageWorker(db = db)
worker = MessageWorker(db=db)

View File

@ -1,20 +1,21 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from http.server import HTTPServer,SimpleHTTPRequestHandler,CGIHTTPRequestHandler
from http.server import HTTPServer, SimpleHTTPRequestHandler, CGIHTTPRequestHandler
from socketserver import BaseServer
import ssl
import json
import settings
# fuckin dirty hack. idk the best way to inherit return func into
# fuckin dirty hack. idk the best way to inherit return func into
# RequestHandler class
class RequestHandler(SimpleHTTPRequestHandler):
def __init__(self,
request,
client_address,
server):
request,
client_address,
server):
self.worker = settings.worker
super(RequestHandler, self).__init__(
request=request,
@ -26,30 +27,29 @@ class RequestHandler(SimpleHTTPRequestHandler):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
length = self.headers.get('content-length')
post_body = self.rfile.read(int(length))
msg = json.loads(post_body.decode("utf-8"))
self.worker.handleUpdate(msg)
def do_GET(self):
pass
class WebHook:
def __init__(self,
certfile,
keyfile,
address = '0.0.0.0',
port=8443,
RequestHandler=RequestHandler):
certfile,
keyfile,
address='0.0.0.0',
port=8443,
RequestHandler=RequestHandler):
self.httpd = HTTPServer((address, port), RequestHandler)
self.httpd.socket = ssl.wrap_socket (self.httpd.socket,
certfile=certfile,
keyfile=keyfile,
server_side=True)
self.httpd.socket = ssl.wrap_socket(self.httpd.socket,
certfile=certfile,
keyfile=keyfile,
server_side=True)
def serve(self):
try:

161
worker.py
View File

@ -7,17 +7,63 @@ from database import DataBase
import os
import urllib.request
from urllib.parse import urlencode
import requests
import json
import settings
import re
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.lexers import guess_lexer, get_lexer_by_name
from pygments.styles import get_style_by_name
from pygments.formatters import ImageFormatter
class MessageWorker:
def __init__(self, db, stop_words = 'assets/stop-word.ru'):
def __init__(self, db, stop_words='assets/stop-word.ru', settings=settings):
self.stop_words = stop_words
self.db = db
self.telegram_key = settings.parser.get('bot', 'telegram_key')
self.telegram_api = settings.parser.get('bot', 'telegram_api')
self.me = self.getMe()
print("My name is %s" % self.me['result']['username'])
def getMe(self):
url = self.telegram_api + 'bot' + self.telegram_key + '/getMe'
print(url)
urllib.request.Request(url)
request = urllib.request.Request(url)
raw = urllib.request.urlopen(request).read().decode()
return json.loads(raw)
def handleUpdate(self, msg):
try:
if msg['message']['text'] == '/scheme':
try:
input_message = msg['message']['text']
if ('@here' in input_message) or (' @'+self.me['result']['username'] in input_message):
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
self.db.add_conf(conf_id, chat_title)
if msg['message']['text'] != '@here':
message = msg['message']['text'].replace('@here', '\n').replace(' @'+self.me['result']['username'], '\n')
else:
message = """I summon you!\n"""
users = self.db.here(
user_id=user_id,
conf_id=conf_id
)
for user in users:
message += ' @%s ' % (user[0])
self.send(id=conf_id, msg=message)
return True
input_message = msg['message']['text'].replace(
'@' + self.me['result']['username'], '')
except:
input_message = msg['message']['text']
if input_message == '/scheme':
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
@ -25,7 +71,7 @@ class MessageWorker:
self.send(id=conf_id, msg='```\n' + self.db.scheme + '\n```')
return True
if msg['message']['text'] == '/stat':
if input_message == '/stat':
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
@ -41,7 +87,7 @@ class MessageWorker:
self.send(id=conf_id, msg=message)
return True
if msg['message']['text'] == '/reset':
if input_message == '/reset':
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
@ -53,7 +99,7 @@ class MessageWorker:
user_id=user_id)
return True
if msg['message']['text'][:4] == '/sql':
if input_message[:4] == '/sql':
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
@ -62,35 +108,63 @@ class MessageWorker:
res = self.db.command(sql)
if 'syntax' in str(res) \
or 'ambiguous' in str(res):
self.send(id=conf_id, msg=str(res))
return False
or 'ambiguous' in str(res):
self.send(id=conf_id, msg=str(res))
return False
try:
msg = '```\n'
for z in res:
for i in z:
msg = msg + str(i) + '\t'
msg = msg + '\n'
msg = '```\n'
for z in res:
for i in z:
msg = msg + str(i) + '\t'
msg = msg + '\n'
except:
msg = res
msg = res
self.send(id=conf_id, msg=msg + ' ```')
return True
if msg['message']['text'][:5] == '@here' or \
msg['message']['text'][5:] == '@here':
# if '@here' in input_message:
# conf_id = msg['message']['chat']['id']
# user_id = msg['message']['from']['id']
# chat_title = msg['message']['chat']['title']
# self.db.add_conf(conf_id, chat_title)
# if msg['message']['text'] != '@here':
# message = msg['message']['text'].replace('@here', '\n')
# else:
# message = """I summon you!\n"""
# users = self.db.here(
# user_id=user_id,
# conf_id=conf_id
# )
# for user in users:
# message += ' @%s ' % (user[0])
# self.send(id=conf_id, msg=message)
# return True
if input_message[:5] == '/code':
conf_id = msg['message']['chat']['id']
user_id = msg['message']['from']['id']
chat_title = msg['message']['chat']['title']
self.db.add_conf(conf_id, chat_title)
message = """I summon you!\n"""
users = self.db.here(
user_id=user_id,
conf_id=conf_id
)
for user in users:
message += '@%s ' % (user[0])
self.send(id=conf_id, msg=message)
if len(msg['message']['text'][6:]) < 10000:
code = msg['message']['text'][6:]
code_tag = code[code.rfind('#') + 1:]
try:
lexer = get_lexer_by_name(code_tag)
code = code[:code.rfind('#')]
print("Lexer is defined as %s" % lexer)
except:
lexer = guess_lexer(code)
print("lexer is %s" % lexer)
if lexer.name == 'Text only':
lexer = get_lexer_by_name('python')
highlight(code, lexer, ImageFormatter(
font_size=16,
line_number_bg="#242e0c",
line_number_fg="#faddf2",
line_number_bold=True,
font_name='DejaVuSansMono',
style=get_style_by_name('monokai')), outfile="code.png")
self.send_img(conf_id)
return True
except:
return False
@ -108,35 +182,34 @@ class MessageWorker:
user_id = msg['message']['from']['id']
chat_id = msg['message']['chat']['id']
chat_title = msg['message']['chat']['title']
#print(self.clean_text(text))
except:
return False
collection = self.clean_text(text)
self.db.add_user(username,
user_id,
first_name,
last_name)
user_id,
first_name,
last_name)
self.db.add_conf(chat_id, chat_title)
for word in collection:
self.db.add_relation(word=word, user_id=user_id, conf_id=chat_id)
def clean_text(self, s):
file = open(self.stop_words, 'rt')
sw = file.read().split('\n')
file.close()
s = re.sub(r'(https?:\/\/)?([\da-z\.-]+)\.([\/\w\.-]*)*\/?\S','',s,flags=re.MULTILINE)
s = re.sub(
r'(https?:\/\/)?([\da-z\.-]+)\.([\/\w\.-]*)*\/?\S', '', s, flags=re.MULTILINE)
print(s)
# dirty hack with dat fucking file
fh = open("tmp.txt","w")
fh = open("tmp.txt", "w")
fh.write(s)
fh.close()
cmd = "./assets/mystem -nlwd < tmp.txt"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
ps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
output = ps.communicate()[0]
os.remove("tmp.txt")
# end of the fuckin' dirty hack
@ -145,7 +218,7 @@ class MessageWorker:
s = s.split('\n')
collection = []
for word in s:
if len(word) >2:
if len(word) > 2:
if word not in sw:
collection.append(word)
else:
@ -155,17 +228,21 @@ class MessageWorker:
return collection
def send(self, id, msg):
print(msg)
url = settings.parser.get('bot', 'telegram_api') + \
'bot'+ settings.parser.get('bot', 'telegram_key') \
+ '/sendMessage'
# print(msg)
url = self.telegram_api + 'bot' + self.telegram_key + '/sendMessage'
post_fields = {
'text': msg,
'chat_id': id,
'parse_mode': 'Markdown',
'disable_web_page_preview': 1
}
}
urllib.request.Request(url, urlencode(post_fields).encode())
request = urllib.request.Request(url, urlencode(post_fields).encode())
json = urllib.request.urlopen(request).read().decode()
return json
def send_img(self, id):
url = self.telegram_api + 'bot' + self.telegram_key + '/sendPhoto'
data = {'chat_id': id}
files = {'photo': open('code.png', 'rb')}
r = requests.post(url, files=files, data=data)