fix
This commit is contained in:
parent
60aa58844c
commit
f72102e7b1
@ -11,7 +11,9 @@ PROD = os.getenv("PROD", "True").lower() != "false"
|
||||
ATOKEN = os.getenv("ATOKEN")
|
||||
MONGO_PASSWORD = os.getenv("MONGO_INITDB_ROOT_PASSWORD")
|
||||
MONGODB_HOST = os.getenv("MONGODB_SERVICE_HOST")
|
||||
MONGO_PORT = os.getenv("MONGODB_SERVICE_PORT", 27017)
|
||||
REDIS_HOST = os.getenv("REDIS_SERVICE_HOST")
|
||||
REDIS_PORT = os.getenv("REDIS_SERVICE_PORT", 6379)
|
||||
FROM_NAME = "Avtopost Kultmost"
|
||||
BOT_TOKEN = os.getenv("BOT_TOKEN")
|
||||
FULL_DOMAIN = os.getenv("FULL_PATH_DOMAIN")
|
||||
@ -28,7 +30,9 @@ REFRESH_TOKEN_EXPIRE_DAYS = 170
|
||||
TOKEN_TTL_DAYS = 7
|
||||
ACCESS_COOKIE = "access_token"
|
||||
REFRESH_COOKIE = "refresh_token"
|
||||
RABBITMQ_HOST = "rabbit.spiritofweb.ru:31023"
|
||||
RABBITMQ_USER = os.getenv("RABBITMQ_USER", 'admin')
|
||||
RABBITMQ_HOST = os.getenv("RABBITMQ_HOST")
|
||||
RABBITMQ_PORT = os.getenv("RABBITMQ_PORT", 5671)
|
||||
EMAIL_SUBJECT = 'Культмост'
|
||||
PROTECTED_FIELDS_USER = {"_id", "img", 'original_img', "hashed_password", "password", "roles"}
|
||||
VK_CLIENT_ID = os.getenv("VK_CLIENT_ID")
|
||||
|
||||
11
db.py
11
db.py
@ -2,7 +2,7 @@ import os
|
||||
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorGridFSBucket
|
||||
import redis.asyncio as redis
|
||||
import asyncio
|
||||
from config import PROD, MONGO_PASSWORD, MONGODB_HOST, REDIS_HOST
|
||||
from config import *
|
||||
|
||||
# Create a new event loop for asyncio
|
||||
loop = asyncio.new_event_loop()
|
||||
@ -13,7 +13,6 @@ if not all([MONGO_PASSWORD, MONGODB_HOST, REDIS_HOST]):
|
||||
raise EnvironmentError("Missing required environment variables for MongoDB/Redis")
|
||||
|
||||
# ========================= DATABASE URI =========================
|
||||
MONGO_PORT = 27017 if PROD else 30002
|
||||
mongo_uri = f"mongodb://admin:{MONGO_PASSWORD}@{MONGODB_HOST}:{MONGO_PORT}/"
|
||||
|
||||
# ========================= MONGO CLIENT =========================
|
||||
@ -51,8 +50,6 @@ gridfs_map = {
|
||||
|
||||
|
||||
# ========================= REDIS CLIENT =========================
|
||||
REDIS_PORT = 6379 if PROD else 30003
|
||||
|
||||
redis_client = redis.Redis(
|
||||
host=REDIS_HOST,
|
||||
port=REDIS_PORT,
|
||||
@ -60,13 +57,17 @@ redis_client = redis.Redis(
|
||||
decode_responses=True
|
||||
)
|
||||
|
||||
redis_uri = f'redis://{REDIS_HOST}:{REDIS_PORT}/'
|
||||
rabbit_mq_uri = f'amqps://{RABBITMQ_USER}:{RABBITMQ_PASS}@{RABBITMQ_HOST}:{RABBITMQ_PORT}/'
|
||||
|
||||
# Exporting collections and clients
|
||||
__all__ = [
|
||||
"competitions_col", "competition_request_col",
|
||||
"users_collection", "users_token_collection",
|
||||
"notify_collection", "social_collection",
|
||||
"posts_collection", "news_collection",
|
||||
"gridfs_map", "redis_client",
|
||||
"gridfs_map", "redis_client", "redis_uri"
|
||||
"mongo_client", "invitations_collection",
|
||||
"delivery_collection", "exhibition_collection",
|
||||
"rabbit_mq_uri"
|
||||
]
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
"from email.mime.text import MIMEText\n",
|
||||
"from celery import Celery\n",
|
||||
"from config import *\n",
|
||||
"from db import *\n",
|
||||
"from templates import templates\n",
|
||||
"import logging\n",
|
||||
"from typing import Optional\n",
|
||||
@ -95,7 +96,7 @@
|
||||
" \n",
|
||||
" msg.attach(MIMEText(html_content, 'html'))\n",
|
||||
" \n",
|
||||
" return msg"
|
||||
" return msg\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -111,7 +112,6 @@
|
||||
" return server\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def send_email(\n",
|
||||
" to_email: str,\n",
|
||||
" html_content: str,\n",
|
||||
@ -125,7 +125,6 @@
|
||||
" user_id=user_id,\n",
|
||||
" ))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" with connect(EMAIL_SMTP_SERVER, EMAIL_SMTP_PORT) as server:\n",
|
||||
" server.login(FROM_EMAIL, EMAIL_PASS)\n",
|
||||
@ -150,7 +149,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"celery_app_email = Celery('emails', broker=f'amqps://admin:{RABBITMQ_PASS}@{RABBITMQ_HOST}/email', backend=f'redis://{REDIS_HOST}:{6379 if PROD else 30003}/0', task_track_started=True )\n"
|
||||
"celery_app_email = Celery('emails', broker=f'{redis_uri}2', backend=f'{redis_uri}2', task_track_started=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -189,7 +188,7 @@
|
||||
" logging.warning(\n",
|
||||
" f\"Ошибка при отправке email на {to_email} (попытка {self.request.retries + 1}): {exc}\"\n",
|
||||
" )\n",
|
||||
" raise self.retry(exc=exc)"
|
||||
" raise self.retry(exc=exc)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -35,6 +35,7 @@ from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from celery import Celery
|
||||
from config import *
|
||||
from db import *
|
||||
from templates import templates
|
||||
import logging
|
||||
from typing import Optional
|
||||
@ -73,13 +74,13 @@ async def create_email_message(
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def connect(email_server, email_port):
|
||||
server = smtplib.SMTP(email_server, email_port)
|
||||
server.starttls(context=ctx)
|
||||
return server
|
||||
|
||||
|
||||
|
||||
def send_email(
|
||||
to_email: str,
|
||||
html_content: str,
|
||||
@ -93,7 +94,6 @@ def send_email(
|
||||
user_id=user_id,
|
||||
))
|
||||
|
||||
|
||||
try:
|
||||
with connect(EMAIL_SMTP_SERVER, EMAIL_SMTP_PORT) as server:
|
||||
server.login(FROM_EMAIL, EMAIL_PASS)
|
||||
@ -111,7 +111,7 @@ def send_email(
|
||||
return False
|
||||
|
||||
|
||||
celery_app_email = Celery('emails', broker=f'amqps://admin:{RABBITMQ_PASS}@{RABBITMQ_HOST}/email', backend=f'redis://{REDIS_HOST}:{6379 if PROD else 30003}/0', task_track_started=True )
|
||||
celery_app_email = Celery('emails', broker=f'{redis_uri}2', backend=f'{redis_uri}2', task_track_started=True)
|
||||
|
||||
|
||||
@celery_app_email.task(
|
||||
@ -143,4 +143,4 @@ def notify(self, to_email: str, data: dict, subject: str = EMAIL_SUBJECT, templa
|
||||
logging.warning(
|
||||
f"Ошибка при отправке email на {to_email} (попытка {self.request.retries + 1}): {exc}"
|
||||
)
|
||||
raise self.retry(exc=exc)
|
||||
raise self.retry(exc=exc)
|
||||
|
||||
@ -2759,8 +2759,9 @@
|
||||
" user: Dict = Security(get_current_user)\n",
|
||||
"):\n",
|
||||
" post = await posts_collection.find_one({'_id':ObjectId(post_id)})\n",
|
||||
" data = json.dumps(post, cls=MongoJSONEncoder, ensure_ascii=False)\n",
|
||||
" return templates.TemplateResponse(\n",
|
||||
" request=request, name=\"form/post_edit.html\", context={\"post\": post, \"user\": user}\n",
|
||||
" request=request, name=\"form/post_edit.html\", context={\"post\": data, \"user\": user}\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
@ -3076,7 +3077,7 @@
|
||||
" \n",
|
||||
"\n",
|
||||
" background_tasks.add_task(update_social_post, doc_out)\n",
|
||||
" background_tasks.add_task(replace_new_medias, bson_clear(res), links_media)\n",
|
||||
" background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)\n",
|
||||
" return doc_out\n",
|
||||
"\n",
|
||||
"\n",
|
||||
|
||||
5
main.py
5
main.py
@ -2072,8 +2072,9 @@ async def form_post_edit(
|
||||
user: Dict = Security(get_current_user)
|
||||
):
|
||||
post = await posts_collection.find_one({'_id':ObjectId(post_id)})
|
||||
data = json.dumps(post, cls=MongoJSONEncoder, ensure_ascii=False)
|
||||
return templates.TemplateResponse(
|
||||
request=request, name="form/post_edit.html", context={"post": post, "user": user}
|
||||
request=request, name="form/post_edit.html", context={"post": data, "user": user}
|
||||
)
|
||||
|
||||
@app.get("/form/news", response_class=HTMLResponse)
|
||||
@ -2335,7 +2336,7 @@ async def put_painting(
|
||||
|
||||
|
||||
background_tasks.add_task(update_social_post, doc_out)
|
||||
background_tasks.add_task(replace_new_medias, bson_clear(res), links_media)
|
||||
background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)
|
||||
return doc_out
|
||||
|
||||
|
||||
|
||||
@ -343,7 +343,7 @@ function bindLinkValidation({
|
||||
|
||||
</script>
|
||||
<script defer>
|
||||
const competition = JSON.parse({{competition|tojson}})
|
||||
const competition = JSON.parse({{competition|tojson}})
|
||||
const competitionId = competition._id
|
||||
|
||||
document.getElementById('title').value = competition.title;
|
||||
|
||||
@ -43,22 +43,6 @@
|
||||
<span class="c_som9s">Сохранить</span>
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.getElementById('author').value = '{{post.author|safe or ""}}';
|
||||
{% if user.get('grade') is none %}
|
||||
document.getElementById('grade').value = '{{post.grade|safe or ""}}';
|
||||
{% endif %}
|
||||
document.getElementById('title').value = '{{post.title|safe or ""}}';
|
||||
document.getElementById('city').value = '{{post.city|safe or ""}}';
|
||||
document.getElementById('size').value = '{{post.size|safe or ""}}';
|
||||
document.getElementById('material').value = '{{post.material|safe or ""}}';
|
||||
document.getElementById('genre').value = '{{post.genre|safe or ""}}';
|
||||
document.getElementById('price').value = '{{post.price|safe or ""}}';
|
||||
document.getElementById('description').value = `{{post.description|safe or ""}}`;
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="c_rtopc">
|
||||
<label class="c_aq9et" for="fileInput">
|
||||
<span class="c_som9s">Добавить фото</span>
|
||||
@ -66,27 +50,39 @@
|
||||
<input class="c_1gai0" id="fileInput" type="file" multiple accept="image/*" style="display: none;"/>
|
||||
<div class="preview" id="preview"></div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
</form>
|
||||
<script defer>
|
||||
const post = JSON.parse({{post|tojson}})
|
||||
const postId = post._id
|
||||
const fileInput = document.getElementById('fileInput');
|
||||
const preview = document.getElementById('preview');
|
||||
document.getElementById('author').value = post.author;
|
||||
|
||||
document.getElementById('grade').value = post.grade;
|
||||
|
||||
const inputEl = document.getElementById('grade');
|
||||
|
||||
let list = inputEl.dataset.list;
|
||||
list = JSON.parse(list.replace(/'/g, '"'));
|
||||
|
||||
list.push(post.grade);
|
||||
list = [...new Set(list)];
|
||||
|
||||
inputEl.dataset.list = JSON.stringify(list);
|
||||
inputEl.dataset.value = post.grade;
|
||||
|
||||
|
||||
|
||||
document.getElementById('title').value = post.title;
|
||||
document.getElementById('city').value = post.city;
|
||||
document.getElementById('size').value = post.size;
|
||||
document.getElementById('material').value = post.material;
|
||||
document.getElementById('genre').value = post.genre;
|
||||
document.getElementById('price').value = post.price;
|
||||
document.getElementById('description').value = post.description;
|
||||
let filesOrdered = []; // теперь храним строки (имена файлов) + существующие медиа
|
||||
|
||||
const existingMedias = [
|
||||
{% if post %}
|
||||
{% for media in post.medias_original %}
|
||||
{
|
||||
url: "/b/posts/{{ media }}",
|
||||
name: "{{ media }}",
|
||||
isExisting: true,
|
||||
type: "image"
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
];
|
||||
console.log(post.medias_original) // ["6a5c33dcc10bbb64e654ba63"]
|
||||
const existingMedias = (post?.medias_original ?? []).map((media) => ({ url: `/b/posts/${media}`, name: `${media}`, isExisting: true, type: "image",}));
|
||||
|
||||
async function uploadMediaFiles(files) {
|
||||
if (!files || files.length === 0) return [];
|
||||
@ -266,7 +262,6 @@
|
||||
const grade = '{{user.grade}}';
|
||||
const form = document.getElementById('postForm');
|
||||
const createBtn = document.getElementById('createBtn');
|
||||
const postId= '{{post._id}}'
|
||||
|
||||
createBtn.addEventListener('click', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
14
vk.ipynb
14
vk.ipynb
@ -79,7 +79,7 @@
|
||||
"from fastapi import status\n",
|
||||
"from fastapi import APIRouter,Depends\n",
|
||||
"from fastapi.responses import RedirectResponse\n",
|
||||
"from images import insert_logo"
|
||||
"from images import insert_logo\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -97,7 +97,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"celery_app_vk = Celery('vk ', broker=f'amqps://admin:{RABBITMQ_PASS}@{RABBITMQ_HOST}/vk', task_track_started=True )\n"
|
||||
"celery_app_vk = Celery('vk', broker=f'{redis_uri}1', backend=f'{redis_uri}1', task_track_started=True )\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -159,7 +159,7 @@
|
||||
" background = insert_logo(Image.open(background).convert(\"RGBA\"), logo)\n",
|
||||
" images[_id] = (\"photo\", (name, background, \"image/jpeg\"))\n",
|
||||
" \n",
|
||||
" return images"
|
||||
" return images\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -231,7 +231,8 @@
|
||||
" return {'ok': False}\n",
|
||||
" update_spec = {\"$push\": {\"vk\": res}}\n",
|
||||
" await mongo_client[db_name][item.get('col')].update_one({'_id': ObjectId(item.get('_id'))}, update_spec)\n",
|
||||
" return {\"ok\": True}\n"
|
||||
" return {\"ok\": True}\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -306,7 +307,8 @@
|
||||
" return {'ok': False}\n",
|
||||
" update_spec = {\"$push\": {\"vk\": res}}\n",
|
||||
" await mongo_client[db_name][item.get('col')].update_one({'_id': ObjectId(item.get('_id'))}, update_spec)\n",
|
||||
" return {\"ok\": True}\n"
|
||||
" return {\"ok\": True}\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -338,7 +340,7 @@
|
||||
" logging.info(doc)\n",
|
||||
" logging.info(social)\n",
|
||||
"\n",
|
||||
" owner_id = f\"-{doc['id']}\" if \"group\" in doc else doc[\"id\"]\n",
|
||||
" owner_id = f\"-{doc.get('id')}\" if \"group\" in doc else doc.get(\"id\")\n",
|
||||
"\n",
|
||||
" # ---- VK request ----\n",
|
||||
" async with httpx.AsyncClient(http2=True, verify=ctx) as client:\n",
|
||||
|
||||
8
vk.py
8
vk.py
@ -52,9 +52,10 @@ from fastapi import APIRouter,Depends
|
||||
from fastapi.responses import RedirectResponse
|
||||
from images import insert_logo
|
||||
|
||||
|
||||
### Конфигурация
|
||||
|
||||
celery_app_vk = Celery('vk ', broker=f'amqps://admin:{RABBITMQ_PASS}@{RABBITMQ_HOST}/vk', task_track_started=True )
|
||||
celery_app_vk = Celery('vk', broker=f'{redis_uri}1', backend=f'{redis_uri}1', task_track_started=True )
|
||||
|
||||
|
||||
token_manager = TokenManager()
|
||||
@ -96,6 +97,7 @@ async def get_images(db_name: str, file_ids: list, sign_avatar: bool = True):
|
||||
|
||||
return images
|
||||
|
||||
|
||||
@router.post("/send")
|
||||
async def send_vk(data:dict, request: Request):
|
||||
auth = request.headers.get("Authorization")
|
||||
@ -161,6 +163,7 @@ async def send_vk(data:dict, request: Request):
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
|
||||
@router.post("/edit")
|
||||
async def edit_vk(data:dict, request: Request):
|
||||
auth = request.headers.get("Authorization")
|
||||
@ -229,6 +232,7 @@ async def edit_vk(data:dict, request: Request):
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
|
||||
@router.post("/delete")
|
||||
async def wall_delete(data: dict, request: Request):
|
||||
# ---- auth ----
|
||||
@ -251,7 +255,7 @@ async def wall_delete(data: dict, request: Request):
|
||||
logging.info(doc)
|
||||
logging.info(social)
|
||||
|
||||
owner_id = f"-{doc['id']}" if "group" in doc else doc["id"]
|
||||
owner_id = f"-{doc.get('id')}" if "group" in doc else doc.get("id")
|
||||
|
||||
# ---- VK request ----
|
||||
async with httpx.AsyncClient(http2=True, verify=ctx) as client:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user