fix
This commit is contained in:
parent
8f312bc038
commit
4a44be2ed6
205
main.ipynb
205
main.ipynb
@ -102,6 +102,8 @@
|
|||||||
"import email_task as email_task\n",
|
"import email_task as email_task\n",
|
||||||
"from pydantic import EmailStr\n",
|
"from pydantic import EmailStr\n",
|
||||||
"import secrets\n",
|
"import secrets\n",
|
||||||
|
"from pymongo import ReturnDocument\n",
|
||||||
|
"\n",
|
||||||
"logging.basicConfig(level=logging.INFO)\n",
|
"logging.basicConfig(level=logging.INFO)\n",
|
||||||
"logger = logging.getLogger(__name__)"
|
"logger = logging.getLogger(__name__)"
|
||||||
]
|
]
|
||||||
@ -531,35 +533,109 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"@app.get(\"/cron/5\")\n",
|
"@app.get(\"/cron/5\")\n",
|
||||||
"async def cron_every_five_min(token: str = Security(get_token)):\n",
|
"async def cron_every_five_min(token: str = Security(get_token)):\n",
|
||||||
" exhibition = await exhibition_collection.find_one_and_update(\n",
|
" now = datetime.now(timezone.utc)\n",
|
||||||
" {\"prod\": PROD, \"status\": 0, \"date_finish\": {\"$lt\": datetime.now(timezone.utc) + timedelta(hours=3)}},\n",
|
" limit_dt = now + timedelta(hours=3)\n",
|
||||||
" {\"$set\": {\"status\": 2}}, return_document=False)\n",
|
"\n",
|
||||||
" if exhibition:\n",
|
" prod_filter = {\"prod\": PROD}\n",
|
||||||
" tasks = []\n",
|
"\n",
|
||||||
" async for doc in delivery_collection.find({'exhibition_id': str(exhibition.get('_id')), 'status': 'Получено'},{'_id':0}):\n",
|
" # 1) If there's an exhibition that is going to be finished soon -> move deliveries to \"Возврат художнику\"\n",
|
||||||
" new_doc = {**doc, 'delivery_type':'', 'track':'', 'status': 'Возврат художнику', 'receiver': doc.get('sender'), 'sender': doc.get('receiver')}\n",
|
" exhibition_finished = await exhibition_collection.find_one_and_update(\n",
|
||||||
" tasks.append(delivery_collection.update_one({\"prod\": PROD, 'status': 'Возврат художнику', 'post_id': doc.get('post_id'),'exhibition_id': doc.get('exhibition_id')},{'$set':new_doc},upsert=True))\n",
|
" {**prod_filter, \"date_finish\": {\"$lt\": limit_dt}},\n",
|
||||||
" asyncio.gather(*tasks)\n",
|
" {\"$set\": {\"status\": 2}},\n",
|
||||||
" else:\n",
|
" return_document=ReturnDocument.AFTER,\n",
|
||||||
" exhibition = await exhibition_collection.find_one_and_update(\n",
|
" )\n",
|
||||||
" {\"prod\": PROD, \"datetime_start\": {\"$lt\": datetime.now(timezone.utc) + timedelta(hours=3)}},\n",
|
" if exhibition_finished:\n",
|
||||||
" {\"$set\": {\"status\": 1}}, return_document=False)\n",
|
" exhibition_id_str = str(exhibition_finished[\"_id\"])\n",
|
||||||
" if exhibition:\n",
|
"\n",
|
||||||
" if exhibition.get('vk') == [] or exhibition.get('tg') == []:\n",
|
" async for doc in delivery_collection.find(\n",
|
||||||
" await service_social_exhibition(exhibition)\n",
|
" {\"exhibition_id\": exhibition_id_str, \"status\": \"Получено\", **prod_filter},\n",
|
||||||
" tasks = []\n",
|
" {\"_id\": 0},\n",
|
||||||
" async for doc in delivery_collection.find({'exhibition_id': str(exhibition.get('_id')), 'status': 'Получено'},{'_id':0}):\n",
|
" ):\n",
|
||||||
" post = await posts_collection.find_one({'_id': ObjectId(doc.get('post_id'))})\n",
|
" sender = doc.get(\"sender\")\n",
|
||||||
" new_doc = {**doc, 'exhibition': exhibition, 'status': 'На выставке', 'user': post.get('user'), 'post': post}\n",
|
" post_id = doc.get(\"post_id\")\n",
|
||||||
" tasks.append(delivery_collection.update_one({\"prod\": PROD, 'status': 'На выставке', 'post_id': doc.get('post_id'),'exhibition_id': doc.get('exhibition_id')},{'$set':new_doc},upsert=True))\n",
|
" exhibition_id = doc.get(\"exhibition_id\")\n",
|
||||||
" tasks.append(notify_in_profile(NotifyItem(\n",
|
"\n",
|
||||||
" user_id=str(post.get('user',{}).get('_id')),\n",
|
" new_doc = {\n",
|
||||||
" type_item='exhibtion',\n",
|
" **doc,\n",
|
||||||
" title=f'Выставка {doc.get('exhibition',{}).get('title')}',\n",
|
" \"delivery_type\": \"\",\n",
|
||||||
" link=f'/profile/exhibition',\n",
|
" \"track\": \"\",\n",
|
||||||
" text=f'Ваши картины на выставке'\n",
|
" \"status\": \"Возврат художнику\",\n",
|
||||||
" )))\n",
|
" \"receiver\": sender,\n",
|
||||||
" asyncio.gather(*tasks)\n",
|
" \"sender\": doc.get(\"receiver\"),\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" await delivery_collection.update_one(\n",
|
||||||
|
" {**prod_filter, \"status\": \"Возврат художнику\", \"post_id\": post_id, \"exhibition_id\": exhibition_id},\n",
|
||||||
|
" {\"$set\": new_doc},\n",
|
||||||
|
" upsert=True,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" return {}\n",
|
||||||
|
" tasks = []\n",
|
||||||
|
" async for exhibition_to_start in exhibition_collection.find(\n",
|
||||||
|
" {**prod_filter}\n",
|
||||||
|
" ):\n",
|
||||||
|
" exhibition_id_str = str(exhibition_to_start[\"_id\"])\n",
|
||||||
|
" exhibition_title = exhibition_to_start.get(\"title\")\n",
|
||||||
|
"\n",
|
||||||
|
" notified_user_id = None\n",
|
||||||
|
" notified_post_user_id = None\n",
|
||||||
|
"\n",
|
||||||
|
" async for doc in delivery_collection.find(\n",
|
||||||
|
" {\"exhibition_id\": exhibition_id_str, \"status\": \"Получено\", **prod_filter},\n",
|
||||||
|
" {\"_id\": 0},\n",
|
||||||
|
" ):\n",
|
||||||
|
" post_id = doc.get(\"post_id\")\n",
|
||||||
|
" exhibition_id = doc.get(\"exhibition_id\")\n",
|
||||||
|
"\n",
|
||||||
|
" post = await posts_collection.find_one({\"_id\": ObjectId(post_id)})\n",
|
||||||
|
"\n",
|
||||||
|
" # Use user from post; keep them even if multiple deliveries exist\n",
|
||||||
|
" if post and post.get(\"user\") and not notified_post_user_id:\n",
|
||||||
|
" notified_post_user_id = str(post[\"user\"].get(\"_id\"))\n",
|
||||||
|
"\n",
|
||||||
|
" new_doc = {\n",
|
||||||
|
" **doc,\n",
|
||||||
|
" \"exhibition\": exhibition_to_start,\n",
|
||||||
|
" \"status\": \"На выставке\",\n",
|
||||||
|
" \"user\": post.get(\"user\") if post else None,\n",
|
||||||
|
" \"post\": post,\n",
|
||||||
|
" **prod_filter\n",
|
||||||
|
" }\n",
|
||||||
|
" print(new_doc)\n",
|
||||||
|
"\n",
|
||||||
|
" tasks.append(delivery_collection.update_one(\n",
|
||||||
|
" {**prod_filter, \"status\": \"На выставке\", \"post_id\": post_id, \"exhibition_id\": exhibition_id},\n",
|
||||||
|
" {\"$set\": new_doc},\n",
|
||||||
|
" upsert=True,\n",
|
||||||
|
" ))\n",
|
||||||
|
"\n",
|
||||||
|
" # NOTE: your original code used `post` from inside the loop (could be last item / even undefined).\n",
|
||||||
|
" # This version notifies once using the first found post user.\n",
|
||||||
|
" if notified_post_user_id:\n",
|
||||||
|
" await notify_in_profile(\n",
|
||||||
|
" NotifyItem(\n",
|
||||||
|
" user_id=notified_post_user_id,\n",
|
||||||
|
" type_item=\"exhibtion\",\n",
|
||||||
|
" title=f\"Выставка {exhibition_title}\",\n",
|
||||||
|
" link=\"/profile/exhibition\",\n",
|
||||||
|
" text=\"Ваши картины на выставке\",\n",
|
||||||
|
" )\n",
|
||||||
|
" )\n",
|
||||||
|
" asyncio.gather(tasks)\n",
|
||||||
|
" # 2) Otherwise find an exhibition that should start soon -> move deliveries to \"На выставке\"\n",
|
||||||
|
" exhibition_to_start = await exhibition_collection.find_one_and_update(\n",
|
||||||
|
" {**prod_filter, \"status\": 0, \"datetime_start\": {\"$lt\": limit_dt}},\n",
|
||||||
|
" {\"$set\": {\"status\": 1}},\n",
|
||||||
|
" return_document=ReturnDocument.AFTER,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" if not exhibition_to_start:\n",
|
||||||
|
" return {}\n",
|
||||||
|
"\n",
|
||||||
|
" # If vk/tg arrays are empty -> send social invitation\n",
|
||||||
|
" if exhibition_to_start.get(\"vk\") == [] or exhibition_to_start.get(\"tg\") == []:\n",
|
||||||
|
" await service_social_exhibition(bson_clear(exhibition_to_start))\n",
|
||||||
" return {}\n"
|
" return {}\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -2946,7 +3022,7 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "44ea690c",
|
"id": "aabb40cb",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -2956,9 +3032,16 @@
|
|||||||
" current_user: Dict = Security(get_current_user, scopes=[\"create:posts\"])\n",
|
" current_user: Dict = Security(get_current_user, scopes=[\"create:posts\"])\n",
|
||||||
"):\n",
|
"):\n",
|
||||||
" await posts_collection.delete_one({'_id': ObjectId(post_id), 'user._id': current_user.get('_id')})\n",
|
" await posts_collection.delete_one({'_id': ObjectId(post_id), 'user._id': current_user.get('_id')})\n",
|
||||||
" return {'ok': True} \n",
|
" return {'ok': True} \n"
|
||||||
" \n",
|
]
|
||||||
"\n",
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d38cafed",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"@app.post(\"/api/post\", response_model=dict)\n",
|
"@app.post(\"/api/post\", response_model=dict)\n",
|
||||||
"async def post_painting(\n",
|
"async def post_painting(\n",
|
||||||
" background_tasks: BackgroundTasks,\n",
|
" background_tasks: BackgroundTasks,\n",
|
||||||
@ -3013,9 +3096,16 @@
|
|||||||
" return doc_out\n",
|
" return doc_out\n",
|
||||||
" except Exception as e:\n",
|
" except Exception as e:\n",
|
||||||
" print(e)\n",
|
" print(e)\n",
|
||||||
" raise HTTPException(status_code=500, detail=str(e))\n",
|
" raise HTTPException(status_code=500, detail=str(e))\n"
|
||||||
"\n",
|
]
|
||||||
"\n",
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "44ea690c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"@app.put(\"/api/post/{post_id}\", response_model=dict)\n",
|
"@app.put(\"/api/post/{post_id}\", response_model=dict)\n",
|
||||||
"async def put_painting(\n",
|
"async def put_painting(\n",
|
||||||
" background_tasks: BackgroundTasks,\n",
|
" background_tasks: BackgroundTasks,\n",
|
||||||
@ -3067,7 +3157,6 @@
|
|||||||
" if res is None:\n",
|
" if res is None:\n",
|
||||||
" raise HTTPException(status_code=404, detail=\"Картина не найдена\")\n",
|
" raise HTTPException(status_code=404, detail=\"Картина не найдена\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
|
||||||
" doc_out = {\n",
|
" doc_out = {\n",
|
||||||
" \"_id\":post_id,\n",
|
" \"_id\":post_id,\n",
|
||||||
" \"id\":post_id,\n",
|
" \"id\":post_id,\n",
|
||||||
@ -3075,12 +3164,18 @@
|
|||||||
" }\n",
|
" }\n",
|
||||||
" doc_out = bson_clear(doc_out)\n",
|
" doc_out = bson_clear(doc_out)\n",
|
||||||
" \n",
|
" \n",
|
||||||
"\n",
|
|
||||||
" background_tasks.add_task(update_social_post, doc_out)\n",
|
" background_tasks.add_task(update_social_post, doc_out)\n",
|
||||||
" background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)\n",
|
" background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)\n",
|
||||||
" return doc_out\n",
|
" return doc_out\n"
|
||||||
"\n",
|
]
|
||||||
"\n",
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3f18f6a6",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"@app.post(\"/api/posts/media\", response_model=dict)\n",
|
"@app.post(\"/api/posts/media\", response_model=dict)\n",
|
||||||
"async def post_media(\n",
|
"async def post_media(\n",
|
||||||
" medias: Optional[List[UploadFile]] = File(None),\n",
|
" medias: Optional[List[UploadFile]] = File(None),\n",
|
||||||
@ -3096,7 +3191,7 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "abe852d2",
|
"id": "9c463130",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -3136,9 +3231,16 @@
|
|||||||
" background_tasks.add_task(replace_news_medias, doc_out)\n",
|
" background_tasks.add_task(replace_news_medias, doc_out)\n",
|
||||||
" return doc_out\n",
|
" return doc_out\n",
|
||||||
" except Exception as e:\n",
|
" except Exception as e:\n",
|
||||||
" raise HTTPException(status_code=500, detail=str(e))\n",
|
" raise HTTPException(status_code=500, detail=str(e))\n"
|
||||||
"\n",
|
]
|
||||||
"\n",
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "de77638d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"@app.put(\"/api/news/{news_id}\", response_model=dict)\n",
|
"@app.put(\"/api/news/{news_id}\", response_model=dict)\n",
|
||||||
"async def put_news(\n",
|
"async def put_news(\n",
|
||||||
" background_tasks: BackgroundTasks,\n",
|
" background_tasks: BackgroundTasks,\n",
|
||||||
@ -3177,9 +3279,16 @@
|
|||||||
" **{k: v for k, v in update_doc.items()}\n",
|
" **{k: v for k, v in update_doc.items()}\n",
|
||||||
" }\n",
|
" }\n",
|
||||||
" doc_out = bson_clear(doc_out)\n",
|
" doc_out = bson_clear(doc_out)\n",
|
||||||
" return doc_out\n",
|
" return doc_out\n"
|
||||||
"\n",
|
]
|
||||||
"\n",
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "abe852d2",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"@app.post(\"/api/news/media\", response_model=dict)\n",
|
"@app.post(\"/api/news/media\", response_model=dict)\n",
|
||||||
"async def news_media(\n",
|
"async def news_media(\n",
|
||||||
" medias: Optional[List[UploadFile]] = File(None),\n",
|
" medias: Optional[List[UploadFile]] = File(None),\n",
|
||||||
|
|||||||
138
main.py
138
main.py
@ -41,6 +41,8 @@ from templates import templates
|
|||||||
import email_task as email_task
|
import email_task as email_task
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
import secrets
|
import secrets
|
||||||
|
from pymongo import ReturnDocument
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -335,35 +337,109 @@ async def cron_every_day(token: str = Security(get_token)):
|
|||||||
|
|
||||||
@app.get("/cron/5")
|
@app.get("/cron/5")
|
||||||
async def cron_every_five_min(token: str = Security(get_token)):
|
async def cron_every_five_min(token: str = Security(get_token)):
|
||||||
exhibition = await exhibition_collection.find_one_and_update(
|
now = datetime.now(timezone.utc)
|
||||||
{"prod": PROD, "status": 0, "date_finish": {"$lt": datetime.now(timezone.utc) + timedelta(hours=3)}},
|
limit_dt = now + timedelta(hours=3)
|
||||||
{"$set": {"status": 2}}, return_document=False)
|
|
||||||
if exhibition:
|
prod_filter = {"prod": PROD}
|
||||||
tasks = []
|
|
||||||
async for doc in delivery_collection.find({'exhibition_id': str(exhibition.get('_id')), 'status': 'Получено'},{'_id':0}):
|
# 1) If there's an exhibition that is going to be finished soon -> move deliveries to "Возврат художнику"
|
||||||
new_doc = {**doc, 'delivery_type':'', 'track':'', 'status': 'Возврат художнику', 'receiver': doc.get('sender'), 'sender': doc.get('receiver')}
|
exhibition_finished = await exhibition_collection.find_one_and_update(
|
||||||
tasks.append(delivery_collection.update_one({"prod": PROD, 'status': 'Возврат художнику', 'post_id': doc.get('post_id'),'exhibition_id': doc.get('exhibition_id')},{'$set':new_doc},upsert=True))
|
{**prod_filter, "date_finish": {"$lt": limit_dt}},
|
||||||
asyncio.gather(*tasks)
|
{"$set": {"status": 2}},
|
||||||
else:
|
return_document=ReturnDocument.AFTER,
|
||||||
exhibition = await exhibition_collection.find_one_and_update(
|
)
|
||||||
{"prod": PROD, "datetime_start": {"$lt": datetime.now(timezone.utc) + timedelta(hours=3)}},
|
if exhibition_finished:
|
||||||
{"$set": {"status": 1}}, return_document=False)
|
exhibition_id_str = str(exhibition_finished["_id"])
|
||||||
if exhibition:
|
|
||||||
if exhibition.get('vk') == [] or exhibition.get('tg') == []:
|
async for doc in delivery_collection.find(
|
||||||
await service_social_exhibition(exhibition)
|
{"exhibition_id": exhibition_id_str, "status": "Получено", **prod_filter},
|
||||||
tasks = []
|
{"_id": 0},
|
||||||
async for doc in delivery_collection.find({'exhibition_id': str(exhibition.get('_id')), 'status': 'Получено'},{'_id':0}):
|
):
|
||||||
post = await posts_collection.find_one({'_id': ObjectId(doc.get('post_id'))})
|
sender = doc.get("sender")
|
||||||
new_doc = {**doc, 'exhibition': exhibition, 'status': 'На выставке', 'user': post.get('user'), 'post': post}
|
post_id = doc.get("post_id")
|
||||||
tasks.append(delivery_collection.update_one({"prod": PROD, 'status': 'На выставке', 'post_id': doc.get('post_id'),'exhibition_id': doc.get('exhibition_id')},{'$set':new_doc},upsert=True))
|
exhibition_id = doc.get("exhibition_id")
|
||||||
tasks.append(notify_in_profile(NotifyItem(
|
|
||||||
user_id=str(post.get('user',{}).get('_id')),
|
new_doc = {
|
||||||
type_item='exhibtion',
|
**doc,
|
||||||
title=f'Выставка {doc.get('exhibition',{}).get('title')}',
|
"delivery_type": "",
|
||||||
link=f'/profile/exhibition',
|
"track": "",
|
||||||
text=f'Ваши картины на выставке'
|
"status": "Возврат художнику",
|
||||||
)))
|
"receiver": sender,
|
||||||
asyncio.gather(*tasks)
|
"sender": doc.get("receiver"),
|
||||||
|
}
|
||||||
|
|
||||||
|
await delivery_collection.update_one(
|
||||||
|
{**prod_filter, "status": "Возврат художнику", "post_id": post_id, "exhibition_id": exhibition_id},
|
||||||
|
{"$set": new_doc},
|
||||||
|
upsert=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
tasks = []
|
||||||
|
async for exhibition_to_start in exhibition_collection.find(
|
||||||
|
{**prod_filter}
|
||||||
|
):
|
||||||
|
exhibition_id_str = str(exhibition_to_start["_id"])
|
||||||
|
exhibition_title = exhibition_to_start.get("title")
|
||||||
|
|
||||||
|
notified_user_id = None
|
||||||
|
notified_post_user_id = None
|
||||||
|
|
||||||
|
async for doc in delivery_collection.find(
|
||||||
|
{"exhibition_id": exhibition_id_str, "status": "Получено", **prod_filter},
|
||||||
|
{"_id": 0},
|
||||||
|
):
|
||||||
|
post_id = doc.get("post_id")
|
||||||
|
exhibition_id = doc.get("exhibition_id")
|
||||||
|
|
||||||
|
post = await posts_collection.find_one({"_id": ObjectId(post_id)})
|
||||||
|
|
||||||
|
# Use user from post; keep them even if multiple deliveries exist
|
||||||
|
if post and post.get("user") and not notified_post_user_id:
|
||||||
|
notified_post_user_id = str(post["user"].get("_id"))
|
||||||
|
|
||||||
|
new_doc = {
|
||||||
|
**doc,
|
||||||
|
"exhibition": exhibition_to_start,
|
||||||
|
"status": "На выставке",
|
||||||
|
"user": post.get("user") if post else None,
|
||||||
|
"post": post,
|
||||||
|
**prod_filter
|
||||||
|
}
|
||||||
|
print(new_doc)
|
||||||
|
|
||||||
|
tasks.append(delivery_collection.update_one(
|
||||||
|
{**prod_filter, "status": "На выставке", "post_id": post_id, "exhibition_id": exhibition_id},
|
||||||
|
{"$set": new_doc},
|
||||||
|
upsert=True,
|
||||||
|
))
|
||||||
|
|
||||||
|
# NOTE: your original code used `post` from inside the loop (could be last item / even undefined).
|
||||||
|
# This version notifies once using the first found post user.
|
||||||
|
if notified_post_user_id:
|
||||||
|
await notify_in_profile(
|
||||||
|
NotifyItem(
|
||||||
|
user_id=notified_post_user_id,
|
||||||
|
type_item="exhibtion",
|
||||||
|
title=f"Выставка {exhibition_title}",
|
||||||
|
link="/profile/exhibition",
|
||||||
|
text="Ваши картины на выставке",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
asyncio.gather(tasks)
|
||||||
|
# 2) Otherwise find an exhibition that should start soon -> move deliveries to "На выставке"
|
||||||
|
exhibition_to_start = await exhibition_collection.find_one_and_update(
|
||||||
|
{**prod_filter, "status": 0, "datetime_start": {"$lt": limit_dt}},
|
||||||
|
{"$set": {"status": 1}},
|
||||||
|
return_document=ReturnDocument.AFTER,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not exhibition_to_start:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# If vk/tg arrays are empty -> send social invitation
|
||||||
|
if exhibition_to_start.get("vk") == [] or exhibition_to_start.get("tg") == []:
|
||||||
|
await service_social_exhibition(bson_clear(exhibition_to_start))
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
@ -2216,7 +2292,7 @@ async def post_delete(
|
|||||||
):
|
):
|
||||||
await posts_collection.delete_one({'_id': ObjectId(post_id), 'user._id': current_user.get('_id')})
|
await posts_collection.delete_one({'_id': ObjectId(post_id), 'user._id': current_user.get('_id')})
|
||||||
return {'ok': True}
|
return {'ok': True}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/api/post", response_model=dict)
|
@app.post("/api/post", response_model=dict)
|
||||||
async def post_painting(
|
async def post_painting(
|
||||||
@ -2326,7 +2402,6 @@ async def put_painting(
|
|||||||
if res is None:
|
if res is None:
|
||||||
raise HTTPException(status_code=404, detail="Картина не найдена")
|
raise HTTPException(status_code=404, detail="Картина не найдена")
|
||||||
|
|
||||||
|
|
||||||
doc_out = {
|
doc_out = {
|
||||||
"_id":post_id,
|
"_id":post_id,
|
||||||
"id":post_id,
|
"id":post_id,
|
||||||
@ -2334,7 +2409,6 @@ async def put_painting(
|
|||||||
}
|
}
|
||||||
doc_out = bson_clear(doc_out)
|
doc_out = bson_clear(doc_out)
|
||||||
|
|
||||||
|
|
||||||
background_tasks.add_task(update_social_post, doc_out)
|
background_tasks.add_task(update_social_post, doc_out)
|
||||||
background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)
|
background_tasks.add_task(replace_new_medias, bson_clear(doc_out), links_media)
|
||||||
return doc_out
|
return doc_out
|
||||||
|
|||||||
@ -43,11 +43,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<header class="c_77wsp b_qx462">
|
<header class="c_77wsp b_qx462">
|
||||||
<h2 class="c_aiv78 b_6jj0l">{{exhibition.title}}</h2>
|
<h2 class="c_aiv78 b_6jj0l">{{exhibition.title}}</h2>
|
||||||
|
<a class="c_wcdb7 b_ofiw3" href="{% if exhibition.get('tizer_link') %}{{exhibition.tizer_link}}{% else %}/b/exhibition/{{ exhibition.tizer_file_id }}{% endif %}" rel="noopener noreferrer" style="width: 100%;">
|
||||||
|
<span class="b_j2ln2">Релиз выставки</span>
|
||||||
|
</a>
|
||||||
<p>Место проведения: {{ exhibition.get('place') }}</p>
|
<p>Место проведения: {{ exhibition.get('place') }}</p>
|
||||||
{% if posts|length > 0 %}
|
{% if posts|length > 0 %}
|
||||||
<p>Картины: {{posts|length}}</p>
|
<p>Картины: {{posts|length}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ share.share('/exhibition/{}'.format(exhibition._id), exhibition.title, '/b/exhibition/{}'.format(exhibition.poster_file_id), "🎨") }}
|
{{ share.share('/exhibition/{}'.format(exhibition._id), exhibition.title, '/b/exhibition/{}'.format(exhibition.poster_file_id), "Приглашаем на выставку") }}
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
<div style="grid-area: c;display: grid;gap: 10px;">
|
<div style="grid-area: c;display: grid;gap: 10px;">
|
||||||
@ -157,7 +160,7 @@
|
|||||||
.b_thlt1_2 { align-items: center; background: rgba(95, 23, 152, 0.20); border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
|
.b_thlt1_2 { align-items: center; background: rgba(95, 23, 152, 0.20); border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
|
||||||
.b_5dr47_2 { color: #5F1798; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
|
.b_5dr47_2 { color: #5F1798; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
|
||||||
.b_xz6em { align-items: center; align-self: stretch; display: flex; gap: 13px; }
|
.b_xz6em { align-items: center; align-self: stretch; display: flex; gap: 13px; }
|
||||||
.b_sdf{font-size: 12px;font-weight: bold;}
|
.b_sdf{font-size: 11px;font-weight: bold;}
|
||||||
picture{overflow: hidden;}
|
picture{overflow: hidden;}
|
||||||
picture>img{width: 100%;object-fit: contain;}
|
picture>img{width: 100%;object-fit: contain;}
|
||||||
.b_ob59y { border-radius: 1em; height: 70px; min-width: 70px; max-width: 170px; vertical-align: top; object-fit: cover;}
|
.b_ob59y { border-radius: 1em; height: 70px; min-width: 70px; max-width: 170px; vertical-align: top; object-fit: cover;}
|
||||||
|
|||||||
@ -60,6 +60,12 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<a class="c_aq9et" href="{% if exhibition.get('tizer_link') %}{{exhibition.tizer_link}}{% else %}/b/exhibition/{{ exhibition.tizer_file_id }}{% endif %}" rel="noopener noreferrer">
|
||||||
|
<span class="c_som9s">Релиз выставки</span>
|
||||||
|
</a>
|
||||||
|
<a class="c_aq9et" href="{{link}}" rel="noopener noreferrer">
|
||||||
|
<span class="c_som9s">Открыть</span>
|
||||||
|
</a>
|
||||||
<p>Место проведения: {{ exhibition.get('place') }}</p>
|
<p>Место проведения: {{ exhibition.get('place') }}</p>
|
||||||
<div class="b_otttb">
|
<div class="b_otttb">
|
||||||
<span class="c_2fr39 b_tfnz2">С {{ ( exhibition.datetime_start.strftime('%d.%m.%Y')) if exhibition.datetime_start else ''}}</span>
|
<span class="c_2fr39 b_tfnz2">С {{ ( exhibition.datetime_start.strftime('%d.%m.%Y')) if exhibition.datetime_start else ''}}</span>
|
||||||
@ -70,7 +76,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="fl">
|
<div class="fl">
|
||||||
<span class="c_2fr39 b_tfnz2" style="z-index: 2;">
|
<span class="c_2fr39 b_tfnz2" style="z-index: 2;">
|
||||||
{{ share.share('/exhibition/{}'.format(exhibition._id), exhibition.title, '/b/exhibition/{}'.format(exhibition.poster_file_id), "🎨") }}
|
{{ share.share('/exhibition/{}'.format(exhibition._id), exhibition.title, '/b/exhibition/{}'.format(exhibition.poster_file_id), "Приглашаем на выставку") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-1">
|
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-1">
|
||||||
<div class="file-name-display" id="doc_name_1">Выберите файл</div>
|
<div class="file-name-display" id="doc_name_1">Выберите файл</div>
|
||||||
<input type="file" id="tizer" name="tizer" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" required>
|
<input type="file" id="tizer" name="tizer" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" required>
|
||||||
<label for="tizer" class="c_z3ybu floating-label">Тизер (PDF, DOC)</label>
|
<label for="tizer" class="c_z3ybu floating-label">Релиз (PDF, DOC)</label>
|
||||||
|
|
||||||
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
@ -89,7 +89,7 @@
|
|||||||
<!-- Блок ссылки -->
|
<!-- Блок ссылки -->
|
||||||
<div class="c_aihm6 floating-group" id="link-block-1" style="display: none;">
|
<div class="c_aihm6 floating-group" id="link-block-1" style="display: none;">
|
||||||
<input type="url" id="tizer_link" name="tizer_link" class="c_xhd5k" placeholder="https://">
|
<input type="url" id="tizer_link" name="tizer_link" class="c_xhd5k" placeholder="https://">
|
||||||
<label for="tizer_link" class="c_z3ybu floating-label">Тизер (ссылка)</label>
|
<label for="tizer_link" class="c_z3ybu floating-label">Релиз (ссылка)</label>
|
||||||
<div id="link-error-1" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
<div id="link-error-1" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -109,7 +109,7 @@
|
|||||||
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-2">
|
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-2">
|
||||||
<div class="file-name-display" id="doc_name_2">Выберите файл</div>
|
<div class="file-name-display" id="doc_name_2">Выберите файл</div>
|
||||||
<input type="file" id="rules" name="rules" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" required>
|
<input type="file" id="rules" name="rules" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" required>
|
||||||
<label for="rules" class="c_z3ybu floating-label">Условия конкурса (PDF, DOC)</label>
|
<label for="rules" class="c_z3ybu floating-label">Условия выставки (PDF, DOC)</label>
|
||||||
|
|
||||||
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
@ -122,7 +122,7 @@
|
|||||||
<!-- Блок ссылки -->
|
<!-- Блок ссылки -->
|
||||||
<div class="c_aihm6 floating-group" id="link-block-2" style="display: none;">
|
<div class="c_aihm6 floating-group" id="link-block-2" style="display: none;">
|
||||||
<input type="url" id="rules_link" name="rules_link" class="c_xhd5k" placeholder="https://">
|
<input type="url" id="rules_link" name="rules_link" class="c_xhd5k" placeholder="https://">
|
||||||
<label for="rules_link" class="c_z3ybu floating-label">Условия конкурса (ссылка)</label>
|
<label for="rules_link" class="c_z3ybu floating-label">Условия выставки (ссылка)</label>
|
||||||
<div id="link-error-2" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
<div id="link-error-2" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-1">
|
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-1">
|
||||||
<div class="file-name-display" id="doc_name_1">Выберите файл</div>
|
<div class="file-name-display" id="doc_name_1">Выберите файл</div>
|
||||||
<input type="file" id="tizer" name="tizer" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" >
|
<input type="file" id="tizer" name="tizer" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" >
|
||||||
<label for="tizer" class="c_z3ybu floating-label">Тизер (PDF, DOC)</label>
|
<label for="tizer" class="c_z3ybu floating-label">Релиз (PDF, DOC)</label>
|
||||||
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
<path d="M14 2V8H20" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2V8H20" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="c_aihm6 floating-group" id="link-block-1" style="display: none;">
|
<div class="c_aihm6 floating-group" id="link-block-1" style="display: none;">
|
||||||
<input type="url" id="tizer_link" name="tizer_link" class="c_xhd5k" placeholder="https://">
|
<input type="url" id="tizer_link" name="tizer_link" class="c_xhd5k" placeholder="https://">
|
||||||
<label for="tizer_link" class="c_z3ybu floating-label">Тизер (ссылка)</label>
|
<label for="tizer_link" class="c_z3ybu floating-label">Релиз (ссылка)</label>
|
||||||
<div id="link-error-1" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
<div id="link-error-1" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="toggle-group">
|
<div class="toggle-group">
|
||||||
@ -85,7 +85,7 @@
|
|||||||
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-2">
|
<div class="c_nb6gy floating-group file-group poster-group" id="file-block-2">
|
||||||
<div class="file-name-display" id="doc_name_2">Выберите файл</div>
|
<div class="file-name-display" id="doc_name_2">Выберите файл</div>
|
||||||
<input type="file" id="rules" name="rules" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" >
|
<input type="file" id="rules" name="rules" class="c_4ykpn hidden-file" accept=".pdf,.doc,.docx" >
|
||||||
<label for="rules" class="c_z3ybu floating-label">Условия конкурса (PDF, DOC)</label>
|
<label for="rules" class="c_z3ybu floating-label">Условия выставки (PDF, DOC)</label>
|
||||||
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="file-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2H6C4.89543 2 4 2.89543 4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8L14 2Z" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
<path d="M14 2V8H20" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
<path d="M14 2V8H20" stroke="#5F1798" stroke-width="2" stroke-linejoin="round"/>
|
||||||
@ -95,7 +95,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="c_aihm6 floating-group" id="link-block-2" style="display: none;">
|
<div class="c_aihm6 floating-group" id="link-block-2" style="display: none;">
|
||||||
<input type="url" id="rules_link" name="rules_link" class="c_xhd5k" placeholder="https://">
|
<input type="url" id="rules_link" name="rules_link" class="c_xhd5k" placeholder="https://">
|
||||||
<label for="rules_link" class="c_z3ybu floating-label">Условия конкурса (ссылка)</label>
|
<label for="rules_link" class="c_z3ybu floating-label">Условия выставки (ссылка)</label>
|
||||||
<div id="link-error-2" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
<div id="link-error-2" class="error-message" style="display:none; color:#e74c3c; font-size:0.85em; margin-top:4px;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="c_aihm6 floating-group">
|
<div class="c_aihm6 floating-group">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user