mirror of
https://github.com/openmax-server/server.git
synced 2026-06-13 06:11:41 +03:00
first commit
This commit is contained in:
0
src/common/__init__.py
Normal file
0
src/common/__init__.py
Normal file
40
src/common/config.py
Normal file
40
src/common/config.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
class ServerConfig:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
### Адрес сервера
|
||||
host = os.getenv("host") or "0.0.0.0"
|
||||
|
||||
### Для мобилок
|
||||
oneme_tcp_port = int(os.getenv("oneme_tcp_port") or 443)
|
||||
tamtam_tcp_port = int(os.getenv("tamtam_tcp_port") or 4433)
|
||||
|
||||
### Шлюзы для веба
|
||||
oneme_ws_port = int(os.getenv("oneme_ws_port") or 81)
|
||||
tamtam_ws_port = int(os.getenv("tamtam_ws_port") or 82)
|
||||
|
||||
### Уровень отладки
|
||||
log_level = os.getenv("log_level") or "debug"
|
||||
|
||||
### MySQL
|
||||
db_host = os.getenv("db_host") or "127.0.0.1"
|
||||
db_port = int(os.getenv("db_port") or 3306)
|
||||
db_user = os.getenv("db_user") or "root"
|
||||
db_password = os.getenv("db_password") or "qwerty"
|
||||
db_name = os.getenv("db_name") or "openmax"
|
||||
|
||||
### SSL
|
||||
certfile = os.getenv("certfile") or "cert.pem"
|
||||
keyfile = os.getenv("keyfile") or "key.pem"
|
||||
|
||||
### Avatar base url
|
||||
avatar_base_url = os.getenv("avatar_base_url") or "http://127.0.0.1/avatar/"
|
||||
|
||||
### Telegram bot
|
||||
telegram_bot_token = os.getenv("telegram_bot_token") or "123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
telegram_bot_enabled = bool(os.getenv("telegram_bot_enabled")) or True
|
||||
telegram_whitelist_ids = [x.strip() for x in os.getenv("telegram_whitelist_ids", "").split(",") if x.strip()]
|
||||
84
src/common/static.py
Normal file
84
src/common/static.py
Normal file
@@ -0,0 +1,84 @@
|
||||
class Static:
|
||||
"""Тут просто статические константы для их дальнейшего использования"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
class ErrorTypes:
|
||||
NOT_IMPLEMENTED = "not_implemented"
|
||||
INVALID_PAYLOAD = "invalid_payload"
|
||||
USER_NOT_FOUND = "user_not_found"
|
||||
CODE_EXPIRED = "code_expired"
|
||||
INVALID_CODE = "invalid_code"
|
||||
INVALID_TOKEN = "invalid_token"
|
||||
CHAT_NOT_FOUND = "chat_not_found"
|
||||
CHAT_NOT_ACCESS = "chat_not_access"
|
||||
|
||||
class ChatTypes:
|
||||
DIALOG = "DIALOG"
|
||||
|
||||
ERROR_TYPES = {
|
||||
"not_implemented": {
|
||||
"localizedMessage": "Не реализовано",
|
||||
"error": "proto.opcode",
|
||||
"message": "Not implemented",
|
||||
"title": "Не реализовано"
|
||||
},
|
||||
"invalid_payload": {
|
||||
"localizedMessage": "Ошибка валидации",
|
||||
"error": "proto.payload",
|
||||
"message": "Invalid payload",
|
||||
"title": "Ошибка валидации"
|
||||
},
|
||||
"user_not_found": {
|
||||
"localizedMessage": "Не нашли этот номер, проверьте цифры",
|
||||
"error": "error.phone.wrong",
|
||||
"message": "User not found",
|
||||
"title": "Не нашли этот номер, проверьте цифры"
|
||||
},
|
||||
"code_expired": {
|
||||
"localizedMessage": "Этот код устарел, запросите новый",
|
||||
"error": "error.code.expired",
|
||||
"message": "Code expired",
|
||||
"title": "Этот код устарел, запросите новый"
|
||||
},
|
||||
"invalid_code": {
|
||||
"localizedMessage": "Неверный код",
|
||||
"error": "error.code.wrong",
|
||||
"message": "Invalid code",
|
||||
"title": "Неверный код"
|
||||
},
|
||||
"invalid_token": {
|
||||
"localizedMessage": "Ошибка входа. Пожалуйста, авторизируйтесь снова",
|
||||
"error": "login.token",
|
||||
"message": "Invalid token",
|
||||
"title": "Ошибка входа. Пожалуйста, авторизируйтесь снова"
|
||||
},
|
||||
"chat_not_found": {
|
||||
"localizedMessage": "Чат не найден",
|
||||
"error": "chat.not.found",
|
||||
"message": "Chat not found",
|
||||
"title": "Чат не найден"
|
||||
},
|
||||
"chat_not_access": {
|
||||
"localizedMessage": "Нет доступа к чату",
|
||||
"error": "chat.not.access",
|
||||
"message": "Chat not access",
|
||||
"title": "Нет доступа к чату"
|
||||
}
|
||||
}
|
||||
|
||||
COMPLAIN_REASONS = [
|
||||
# TODO: Было бы очень замечательно заполнить этот лист причинами для жалоб
|
||||
]
|
||||
|
||||
### Заглушка для папок
|
||||
ALL_CHAT_FOLDER = [{
|
||||
"id": "all.chat.folder",
|
||||
"title": "Все",
|
||||
"filters": [],
|
||||
"updateTime": 0,
|
||||
"options": [],
|
||||
"sourceId": 1
|
||||
}]
|
||||
|
||||
ALL_CHAT_FOLDER_ORDER = ["all.chat.folder"]
|
||||
194
src/common/tools.py
Normal file
194
src/common/tools.py
Normal file
@@ -0,0 +1,194 @@
|
||||
import json, time
|
||||
|
||||
class Tools:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def generate_profile(
|
||||
self, id=1, phone=70000000000, avatarUrl=None,
|
||||
photoId=None, updateTime=0,
|
||||
firstName="Test", lastName="Account", options=[],
|
||||
description=None, accountStatus=0, profileOptions=[],
|
||||
includeProfileOptions=True, username=None
|
||||
):
|
||||
contact = {
|
||||
"id": id,
|
||||
"updateTime": updateTime,
|
||||
"phone": phone,
|
||||
"names": [
|
||||
{
|
||||
"name": firstName,
|
||||
"firstName": firstName,
|
||||
"lastName": lastName,
|
||||
"type": "ONEME"
|
||||
}
|
||||
],
|
||||
"options": options,
|
||||
"accountStatus": accountStatus
|
||||
}
|
||||
|
||||
|
||||
if avatarUrl:
|
||||
contact["photoId"] = photoId
|
||||
contact["baseUrl"] = avatarUrl
|
||||
contact["baseRawUrl"] = avatarUrl
|
||||
|
||||
if description:
|
||||
contact["description"] = description
|
||||
|
||||
if username:
|
||||
contact["link"] = "https://max.ru/" + username
|
||||
|
||||
if includeProfileOptions == True:
|
||||
return {
|
||||
"contact": contact,
|
||||
"profileOptions": profileOptions
|
||||
}
|
||||
else:
|
||||
return contact
|
||||
|
||||
def generate_chat(self, id, owner, type, participants, lastMessage, lastEventTime):
|
||||
"""Генерация чата"""
|
||||
# Генерируем список участников
|
||||
result_participants = {
|
||||
str(participant): 0 for participant in participants
|
||||
}
|
||||
|
||||
result = None
|
||||
|
||||
# Генерируем нужный список в зависимости от типа чата
|
||||
if type == "DIALOG":
|
||||
result = {
|
||||
"id": id,
|
||||
"type": type,
|
||||
"status": "ACTIVE",
|
||||
"owner": owner,
|
||||
"participants": result_participants,
|
||||
"lastMessage": lastMessage,
|
||||
"lastEventTime": lastEventTime,
|
||||
"lastDelayedUpdateTime": 0,
|
||||
"lastFireDelayedErrorTime": 0,
|
||||
"created": 1,
|
||||
"joinTime": 1,
|
||||
"modified": lastEventTime
|
||||
}
|
||||
|
||||
# Возвращаем
|
||||
return result
|
||||
|
||||
async def generate_chats(self, chatIds, db_pool, senderId):
|
||||
"""Генерирует чаты для отдачи клиенту"""
|
||||
# Готовый список с чатами
|
||||
chats = []
|
||||
|
||||
# Формируем список чатов
|
||||
for chatId in chatIds:
|
||||
async with db_pool.acquire() as db_connection:
|
||||
async with db_connection.cursor() as cursor:
|
||||
# Получаем чат по id
|
||||
await cursor.execute("SELECT * FROM `chats` WHERE id = %s", (chatId,))
|
||||
row = await cursor.fetchone()
|
||||
|
||||
if row:
|
||||
# Получаем последнее сообщение из чата
|
||||
message, messageTime = await self.get_last_message(
|
||||
chatId, db_pool
|
||||
)
|
||||
|
||||
# Формируем список участников
|
||||
participants = {
|
||||
str(participant): 0 for participant in row.get("participants")
|
||||
}
|
||||
|
||||
# Выносим результат в лист
|
||||
chats.append(
|
||||
{
|
||||
"id": row.get("id"),
|
||||
"type": row.get("type"),
|
||||
"status": "ACTIVE",
|
||||
"owner": row.get("owner"),
|
||||
"participants": participants,
|
||||
"lastMessage": message,
|
||||
"lastEventTime": messageTime,
|
||||
"lastDelayedUpdateTime": 0,
|
||||
"lastFireDelayedErrorTime": 0,
|
||||
"created": 1,
|
||||
"joinTime": 1,
|
||||
"modified": messageTime
|
||||
}
|
||||
)
|
||||
|
||||
# Получаем последнее сообщение из избранного
|
||||
message, messageTime = await self.get_last_message(
|
||||
senderId, db_pool
|
||||
)
|
||||
|
||||
# Хардкодим в лист чатов избранное
|
||||
chats.append(
|
||||
{
|
||||
"id": 0,
|
||||
"type": "DIALOG",
|
||||
"status": "ACTIVE",
|
||||
"owner": senderId,
|
||||
"participants": {
|
||||
str(senderId): 0 # if not messageTime else messageTime
|
||||
},
|
||||
"lastMessage": message,
|
||||
"lastEventTime": messageTime,
|
||||
"lastDelayedUpdateTime": 0,
|
||||
"lastFireDelayedErrorTime": 0,
|
||||
"created": 1,
|
||||
"joinTime": 1,
|
||||
"modified": messageTime
|
||||
}
|
||||
)
|
||||
|
||||
return chats
|
||||
|
||||
async def insert_message(self, chatId, senderId, text, attaches, elements, cid, type, db_pool):
|
||||
"""Добавление сообщения в историю"""
|
||||
async with db_pool.acquire() as db_connection:
|
||||
async with db_connection.cursor() as cursor:
|
||||
# Получаем id последнего сообщения в чате
|
||||
await cursor.execute("SELECT id FROM `messages` WHERE chat_id = %s ORDER BY time DESC LIMIT 1", (chatId,))
|
||||
|
||||
row = await cursor.fetchone() or {}
|
||||
last_message_id = row.get("id") or 0 # последнее id сообщения в чате
|
||||
|
||||
# Вносим новое сообщение в таблицу
|
||||
await cursor.execute(
|
||||
"INSERT INTO `messages` (chat_id, sender, time, text, attaches, cid, elements, type) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
|
||||
(chatId, senderId, int(time.time() * 1000), text, json.dumps(attaches), cid, json.dumps(elements), type)
|
||||
)
|
||||
|
||||
message_id = cursor.lastrowid # id сообщения
|
||||
|
||||
# Возвращаем айдишки
|
||||
return int(message_id), int(last_message_id)
|
||||
|
||||
async def get_last_message(self, chatId, db_pool):
|
||||
"""Получение последнего сообщения в чате"""
|
||||
async with db_pool.acquire() as db_connection:
|
||||
async with db_connection.cursor() as cursor:
|
||||
# Получаем id последнего сообщения в чате
|
||||
await cursor.execute("SELECT * FROM `messages` WHERE chat_id = %s ORDER BY time DESC LIMIT 1", (chatId,))
|
||||
|
||||
row = await cursor.fetchone()
|
||||
|
||||
# Если нет результатов - возвращаем None
|
||||
if not row:
|
||||
return None, None
|
||||
|
||||
# Собираем сообщение
|
||||
message = {
|
||||
"id": row.get("id"),
|
||||
"time": int(row.get("time")),
|
||||
"type": row.get("type"),
|
||||
"sender": row.get("sender"),
|
||||
"text": row.get("text"),
|
||||
"attaches": json.loads(row.get("attaches")),
|
||||
# "reactionInfo": {}
|
||||
}
|
||||
|
||||
# Возвращаем
|
||||
return message, int(row.get("time"))
|
||||
Reference in New Issue
Block a user