Skip to content
Permalink
Browse files

Merge pull request #214 from progsly/converter-bot

Converter bot
  • Loading branch information...
umputun committed Jul 13, 2018
2 parents 7d23683 + 0a2ef08 commit 6ee5f955e908b1de5d0f996f36591ac7409b4bf4
@@ -0,0 +1,12 @@
FROM python:3.5-alpine

COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt

RUN mkdir /usr/converter-bot
COPY . /usr/converter-bot/
WORKDIR /usr/converter-bot/

EXPOSE 8080

CMD ["python", "main.py"]
@@ -0,0 +1,56 @@
# Бот для чата [Радио-Т](https://github.com/umputun/rt-bot)

## Описание
Бот конвертер. Если сообщение начинается с цифры и в тексте есть упоминания единиц измерения, бот конвертирует значение.


### Пример 1
Сообщение:
```json
{
text: "1 миля это сколько?",
username: "test",
display_name: "test"
}
```

Ответ:
**_test_** упомянул 1 миля

Метр 1609.344

Километр 1.609

Миллиметр 1609344.0

Дециметр 16093.44

Дюйм 63359.873

Сантиметр 160934.4

Фут 5280.0

### Пример 2
Сообщение:
```json
{
text: "1 литр это сколько пинт",
username: "test",
display_name: "test"
}
```

Ответ:
**_test_** упомянул 1 литр

Пинта 2.113

### Пример ответа в json
Сообщение:
```json
{
"text": "**_test_** упомянул 1 литр \\nПинта 2.113 ",
"bot": "converter-bot"
}
```
@@ -0,0 +1,13 @@
bot_name: "converter-bot"
bot_display_name: "converter-bot"

ignored_commands:
- "Привет"
- "Как дела?"

test_cases:
- command: "1 метр в сантиметрах"
result: ".+"

- command: "10 мегабайт"
result: ".+"
@@ -0,0 +1,105 @@
from db.length.length import length
from db.mass.mass import mass
from db.temperature.temperature import temperature
from db.time.time import time
from db.volume.volume import volume
from db.data.data import data as data_db
import re


class Converter(object):
units = {}
aliases = {}
categories = []
value = None
DB = {}
LANGUAGE = "ru"

def __init__(self):
self.units["length"] = length
self.units["mass"] = mass
self.units["temperature"] = temperature
self.units["time"] = time
self.units["volume"] = volume
self.units["data"] = data_db
self.map_aliases()

def map_aliases(self):
for category, data in self.units.items():
for unit, items in data["units"].items():
for alias in items["languages"]["ru"]["aliases"]:
self.aliases[alias] = {
"unit": unit,
"category": category,
"from": items["from"],
"to": items["to"],
"name": items["languages"]["ru"]["name"]
}
for alias in items["languages"]["en"]["aliases"]:
self.aliases[alias] = {
"unit": unit,
"category": category,
"from": items["from"],
"to": items["to"],
"name": items["languages"]["en"]["name"]
}

def analyse(self, message):
self.value = self.get_value(message)
if not self.value:
return False, {}

units = self.fetch_aliases(message)
print (units)
if len(units) == 0:
return False, {}
data = self.process_unit(units)
return True, {"value": self.value, "unit": units[0], "data": data}

def process_unit(self, units):
current = self.aliases[units[0]]
original = eval(current["from"].format(n=self.value))
data = []
if len(units) == 2:
current_2 = self.aliases[units[1]]
if current["category"] == current_2["category"] and current["unit"] != current_2["unit"]:
to = eval(current_2["to"].format(n=original))
to = round(to, 3)
data.append({"value": to, "name": self.units[self.aliases[units[0]]["category"]]["units"]
[current_2["unit"]]["languages"][self.LANGUAGE]["name"]})
return data

for unit, item in self.units[self.aliases[units[0]]["category"]]["units"].items():
if unit == current["unit"]:
continue
to = eval(item["to"].format(n=original))
to = round(to, 3)
data.append({"value": to, "name": item["languages"][self.LANGUAGE]["name"]})

return data

def get_value(self, message):
result = re.match(r"^\s*([+-]?((?=\.)\.\d+|\d+(?:[\.,]?\d+)?))", message)
if result is not None:
value = result.group(0)
return value.replace(",", ".")
else:
return None

def fetch_aliases(self, message):
reg = re.compile("[^a-zA-Zа-яёА-ЯЁ ]")
message = reg.sub("", message)
words = message.split()
units = []
while len(words) and len(units) <= 2:
tmp = words.pop()
tmp = tmp.lower()
if self.is_alias(tmp):
units.append(tmp)
return units[::-1]

def get_aliases(self):
return list(self.aliases.keys())

def is_alias(self, word):
return word in self.get_aliases()
No changes.
@@ -0,0 +1,150 @@
# coding: utf-8
data = {
'languages': {
'en': 'Data',
'ru': 'Данные'
},
'units': {
'bit': {
'from': '{n}',
'to': '{n}',
'languages': {
'en': {
'name': 'Bit',
'aliases': ['bit', 'bits']
},
'ru': {
'name': 'Бит',
'aliases': ['бит', 'битов', 'битах', 'бита']
}
}
},
'byte': {
'from': '{n} * (2 ** 3)',
'to': '{n} / (2 ** 3)',
'languages': {
'en': {
'name': 'Byte',
'aliases': ['byte', 'bytes']
},
'ru': {
'name': 'Байт',
'aliases': ['байт', 'байтов', 'байтах', 'байта']
}
}
},
'exabyte': {
'from': '{n} * (2 ** 63)',
'to': '{n} / (2 ** 63)',
'languages': {
'en': {
'name': 'Exabyte',
'aliases': ['exabyte', 'eb', 'exabytes']
},
'ru': {
'name': 'Эксабайт',
'aliases': ['эксабайт', 'эб', 'эксабайтах', 'эксабайтов', 'эксабайта']
}
}
},
'gigabyte': {
'from': '{n} * (2 ** 33)',
'to': '{n} / (2 ** 33)',
'languages': {
'en': {
'name': 'Gigabyte',
'aliases': ['gigabyte', 'gb', 'gigabytes']
},
'ru': {
'name': 'Гигабайт',
'aliases': ['гигабайт', 'гб', 'гигабайтах', 'гигабайтов', 'гигабайта']
}
}
},
'kilobyte': {
'from': '{n} * (2 ** 13)',
'to': '{n} / (2 ** 13)',
'languages': {
'en': {
'name': 'Kilobyte',
'aliases': ['kilobyte', 'kb', 'kilobytes']
},
'ru': {
'name': 'Килобайт',
'aliases': ['кб', 'килобайтах', 'килобайтов', 'килобайт', 'килобайта']
}
}
},
'megabyte': {
'from': '{n} * (2 ** 23)',
'to': '{n} / (2 ** 23)',
'languages': {
'en': {
'name': 'Megabyte',
'aliases': ['megabyte', 'mb', 'megabytes']
},
'ru': {
'name': 'Мегабайт',
'aliases': ['мб', 'мегабайтах', 'мегабайтов', 'мегабайт', 'мегабайта']
}
}
},
'petabyte': {
'from': '{n} * (2 ** 53)',
'to': '{n} / (2 ** 53)',
'languages': {
'en': {
'name': 'Petabyte',
'aliases': ['petabyte', 'pb', 'petabytes']
},
'ru': {
'name': 'Петабайт',
'aliases': ['петабайт', 'пб', 'петабайтах', 'петабайтов', 'петабайта']
}
}
},
'terabyte': {
'from': '{n} * (2 ** 43)',
'to': '{n} / (2 ** 43)',
'languages': {
'en': {
'name': 'Terabyte',
'aliases': ['terabyte', 'tb', 'terabytes']
},
'ru': {
'name': 'Терабайт',
'aliases': ['терабайт', 'тб', 'терабайтах', 'теребайтов', 'терабайта']
}
}
},
'yottabyte': {
'from': '{n} * (2 ** 83)',
'to': '{n} / (2 ** 83)',
'languages': {
'en': {
'name': 'Yottabyte',
'aliases': ['yottabyte', 'yb', 'yottabytes']
},
'ru': {
'name': 'Иоттабайт',
'aliases': ['иоттабайт', 'иб', 'иоттабайтах', 'иоттабайтов', 'иоттабайта']
}
}
},
'zettabyte': {
'from': '{n} * (2 ** 73)',
'to': '{n} / (2 ** 73)',
'languages': {
'en': {
'name': 'Zettabyte',
'aliases': ['zettabyte', 'zb', 'zettabytes']
},
'ru': {
'name': 'Зеттабайт',
'aliases': ['зеттабайт', 'зб', 'зеттабайтах', 'эксабайтов', 'эксабайта']
}
}
},

}
}
Oops, something went wrong.

0 comments on commit 6ee5f95

Please sign in to comment.
You can’t perform that action at this time.