Spaces:
Sleeping
Sleeping
Upload 7 files
Browse files- Sertifikat.png +0 -0
- Times New Roman Bold.ttf +0 -0
- app.py +108 -0
- data.json +38 -0
- photograph.py +24 -0
- requirements.txt +2 -0
- utils.py +99 -0
Sertifikat.png
ADDED
![]() |
Times New Roman Bold.ttf
ADDED
Binary file (398 kB). View file
|
|
app.py
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import json
|
4 |
+
import os
|
5 |
+
import asyncio
|
6 |
+
from datetime import datetime, timezone
|
7 |
+
from utils import validate_input, make_certificates
|
8 |
+
import pytz
|
9 |
+
|
10 |
+
async def main():
|
11 |
+
st.set_page_config(
|
12 |
+
page_title="Sertifikatlarni olish",
|
13 |
+
page_icon="🎓",
|
14 |
+
layout="wide",
|
15 |
+
initial_sidebar_state="auto")
|
16 |
+
|
17 |
+
st.markdown("""
|
18 |
+
<div style='text-align: center;'>
|
19 |
+
<h1>Konferensiya ishtirokchilari uchun sertifikat tayyorlash sahifasi</h1>
|
20 |
+
</div>
|
21 |
+
""", unsafe_allow_html=True)
|
22 |
+
st.markdown("<h3 align='center'><i>Ro'yxatga olish formasi</i></h3>", unsafe_allow_html=True)
|
23 |
+
|
24 |
+
st.markdown("---")
|
25 |
+
|
26 |
+
with st.form("Birinchi formamiz", clear_on_submit=True):
|
27 |
+
fish = st.text_input("F.I.SH", placeholder="Misol: Ulug'murodov Shoh Abbos Baxodir o'g'li", help='Bu maydonda FISH kiritiladi')
|
28 |
+
maqola = st.text_input("Maqola mavzuingiz", placeholder="Misol: Ma'lumotlar xavfsizligini oshirishda blockchayn texnologiyalarning o'rni", max_chars=500, help="Bu qismda maqola mavzusi lo'nda kiritilishi kerak")
|
29 |
+
shuba = st.selectbox(
|
30 |
+
"Sho'bani tanlang",
|
31 |
+
options=(
|
32 |
+
"1-sho'ba. Ta'lim tizimini takomillashtirish: dolzarb tendensiyalar va strategik yo'nalishlar",
|
33 |
+
"2-sho'ba. Biomuhandislik va biotexnologiyalar sohasida innovatsiyalar",
|
34 |
+
"3-sho'ba. Raqamli iqtisod va innovatsion axborot-kommunikatsiya texnologiyalarini joriy etishning dolzarb masalalari",
|
35 |
+
"4-sho'ba. Psixologiya, tabiiy va aniq fanlar sohasida dolzarb tadqiqotlar",
|
36 |
+
"5-sho'ba. Zamonaviy jamiyatda filologiya, tilshunoslik va didaktika",
|
37 |
+
"6-sho'ba. Zamonaviy gumanitar ta'limning dolzarb muammolari"
|
38 |
+
),
|
39 |
+
placeholder="O'z sho'bangizni tanlang...", help="O'z sho'bangizni tanlashda qiynalsangiz konferensiya ma'muriyatiga telefon qilishingiz mumkin: https://t.me/UzMU_JF_conf_1_2_3_shuba, https://t.me/UzMU_JF_conf_4_5_6_shuba")
|
40 |
+
ustun_1, ustun_2 = st.columns(2)
|
41 |
+
email = ustun_1.text_input("Email manzilingizni kiriting", placeholder="Misol: [email protected]", help="Elektron manzil barchangizda bo'ladi degan umiddaman")
|
42 |
+
phone = ustun_2.text_input("Telefon raqam", placeholder="+998931189988", help="Telefon raqamni kiriting")
|
43 |
+
rozilik = st.checkbox("Yuqoridagi barcha ma'lumotlar to'g'ri va aniq ekanligini tasdiqlaysizmi?")
|
44 |
+
taqsdiqlash = st.form_submit_button("Sertifikat olish", type='primary')
|
45 |
+
|
46 |
+
if taqsdiqlash and rozilik:
|
47 |
+
|
48 |
+
is_valid, error_message = validate_input(fish, email, maqola, phone)
|
49 |
+
if is_valid:
|
50 |
+
try:
|
51 |
+
with open('data.json', 'r') as f:
|
52 |
+
existing_data = json.load(f)
|
53 |
+
except (FileNotFoundError, json.decoder.JSONDecodeError):
|
54 |
+
existing_data = []
|
55 |
+
|
56 |
+
# Ma'lumotlar mavjudligini tekshirish
|
57 |
+
exact_match = next((item for item in existing_data if item["F.I.SH"] == fish or item["Email"] == email or item["Telefon raqam"] == phone or item["Maqola mavzusi"] == maqola), None)
|
58 |
+
|
59 |
+
if exact_match:
|
60 |
+
certificate_link = exact_match["Sertifikat manzili"]
|
61 |
+
sertifikat_vaqt_utc = datetime.strptime(exact_match["Sertifikat olingan vaqt"], "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
|
62 |
+
sertifikat_vaqt = sertifikat_vaqt_utc.astimezone(pytz.timezone('Asia/Tashkent'))
|
63 |
+
st.warning(f"Siz ro'yxatdan o'tgansiz! Pastda siz olgan sertifikat nusxasi mavjud. Sertifikat olgan sana: {sertifikat_vaqt.strftime('%Y-%m-%d %H:%M:%S')}", icon='⚠️')
|
64 |
+
st.markdown(f"[{fish}ning sertifikat fayli]({certificate_link})")
|
65 |
+
else:
|
66 |
+
sertifikat_vaqt = datetime.now(pytz.timezone('Asia/Tashkent')).strftime("%Y-%m-%d %H:%M:%S")
|
67 |
+
certificate_link = await make_certificates(fish, maqola)
|
68 |
+
st.success("Ma'lumotlar muvaffaqiyatli saqlandi", icon='💾')
|
69 |
+
existing_data.append({
|
70 |
+
"F.I.SH": fish,
|
71 |
+
"Maqola mavzusi": maqola,
|
72 |
+
"Sho'ba": shuba,
|
73 |
+
"Email": email,
|
74 |
+
"Telefon raqam": phone,
|
75 |
+
"Sertifikat manzili": certificate_link,
|
76 |
+
"Sertifikat olingan vaqt": sertifikat_vaqt
|
77 |
+
})
|
78 |
+
with open('data.json', 'w') as f:
|
79 |
+
json.dump(existing_data, f, indent=4)
|
80 |
+
st.markdown(f"[{fish}ning sertifikat fayli]({certificate_link})")
|
81 |
+
|
82 |
+
table = {
|
83 |
+
"F.I.SH": fish,
|
84 |
+
"Maqola mavzusi": maqola,
|
85 |
+
"Sho'ba": shuba,
|
86 |
+
"Email": email,
|
87 |
+
"Telefon raqam": phone,
|
88 |
+
"Sertifikat manzili": certificate_link,
|
89 |
+
"Sertifikat olingan vaqt": sertifikat_vaqt
|
90 |
+
}
|
91 |
+
with st.expander("Siz kiritgan ma'lumotlar bilan tanishing👇👇👇"):
|
92 |
+
st.table(table)
|
93 |
+
|
94 |
+
# Barcha ro'yxatdan o'tganlar ma'lumotlarini ko'rsatish
|
95 |
+
df = pd.DataFrame(existing_data)
|
96 |
+
with st.expander("Umumiy ro'yxat"):
|
97 |
+
# Telefon raqamlarni qisqartirib olish
|
98 |
+
df['Telefon raqam'] = df['Telefon raqam'].apply(lambda x: f"+998***{x[-4:]}")
|
99 |
+
st.dataframe(df)
|
100 |
+
|
101 |
+
else:
|
102 |
+
st.error(f"Xatolik nomi: {error_message}", icon='❌')
|
103 |
+
elif taqsdiqlash and not rozilik:
|
104 |
+
st.error("Ma'lumotlarni to'g'ri kiritilganligini tasdiqlang", icon='✅')
|
105 |
+
|
106 |
+
if __name__ == "__main__":
|
107 |
+
asyncio.run(main())
|
108 |
+
|
data.json
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"F.I.SH": "Ulugmurodov Shokh Abbos Bakhodir ugli",
|
4 |
+
"Maqola mavzusi": "Convolutional neural network (CNN) based approach for braille block recognition with improved noise reduction",
|
5 |
+
"Sho'ba": "3-sho'ba. Raqamli iqtisod va innovatsion axborot-kommunikatsiya texnologiyalarini joriy etishning dolzarb masalalari",
|
6 |
+
"Email": "[email protected]",
|
7 |
+
"Telefon raqam": "+998931189988",
|
8 |
+
"Sertifikat manzili": "https://telegra.ph//file/fc4b0df1da427984cd82c.png",
|
9 |
+
"Sertifikat olingan vaqt": "2024-05-18 16:33:58"
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"F.I.SH": "Normurodova Qunduz Tog\u02bbayevna",
|
13 |
+
"Maqola mavzusi": "\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0438\u043c\u043c\u0443\u043d\u043e\u0442\u0440\u043e\u043f\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043f\u0440\u0438\u0440\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0443\u0431\u0441\u0442\u0430\u043d\u0446\u0438 \u044d\u0440\u0438\u043a\u0441\u0438\u043d\u0430",
|
14 |
+
"Sho'ba": "2-sho'ba. Biomuhandislik va biotexnologiyalar sohasida innovatsiyalar",
|
15 |
+
"Email": "[email protected]",
|
16 |
+
"Telefon raqam": "+998992587415",
|
17 |
+
"Sertifikat manzili": "https://telegra.ph//file/b94beab1e5b9917bb5676.png",
|
18 |
+
"Sertifikat olingan vaqt": "2024-05-18 16:34:44"
|
19 |
+
},
|
20 |
+
{
|
21 |
+
"F.I.SH": "Normatov Ibroximali Xolmamatovich",
|
22 |
+
"Maqola mavzusi": "\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0435\u0437\u0432\u0440\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u0433\u0440\u043e\u0437 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f",
|
23 |
+
"Sho'ba": "1-sho'ba. Ta'lim tizimini takomillashtirish: dolzarb tendensiyalar va strategik yo'nalishlar",
|
24 |
+
"Email": "[email protected]",
|
25 |
+
"Telefon raqam": "+998930332518",
|
26 |
+
"Sertifikat manzili": "https://telegra.ph//file/b0b955a2f15b57360b044.png",
|
27 |
+
"Sertifikat olingan vaqt": "2024-05-18 16:37:08"
|
28 |
+
},
|
29 |
+
{
|
30 |
+
"F.I.SH": "Raxmanova Muqaddas Qaxramonovna",
|
31 |
+
"Maqola mavzusi": "Talabalarning ijodkorligini rivojlantirishning o\u2018ziga xos xususiyatlari",
|
32 |
+
"Sho'ba": "1-sho'ba. Ta'lim tizimini takomillashtirish: dolzarb tendensiyalar va strategik yo'nalishlar",
|
33 |
+
"Email": "[email protected]",
|
34 |
+
"Telefon raqam": "+998912587412",
|
35 |
+
"Sertifikat manzili": "https://telegra.ph//file/894cd979ef4780efe002e.png",
|
36 |
+
"Sertifikat olingan vaqt": "2024-05-18 16:37:53"
|
37 |
+
}
|
38 |
+
]
|
photograph.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import aiohttp
|
2 |
+
import asyncio
|
3 |
+
from io import BytesIO
|
4 |
+
|
5 |
+
async def photo_link(photo_bytes):
|
6 |
+
form = aiohttp.FormData()
|
7 |
+
form.add_field(
|
8 |
+
name='file',
|
9 |
+
value=photo_bytes,
|
10 |
+
)
|
11 |
+
async with aiohttp.ClientSession() as session:
|
12 |
+
async with session.post('https://telegra.ph/upload', data=form) as response:
|
13 |
+
img_src = await response.json()
|
14 |
+
link = 'http://telegra.ph/' + img_src[0]["src"]
|
15 |
+
return link
|
16 |
+
|
17 |
+
async def main():
|
18 |
+
with open('Sertifikat.png', 'rb') as photo_file: # Bunda tirnoqlarni olib tashlang
|
19 |
+
photo_bytes = BytesIO(photo_file.read())
|
20 |
+
link = await photo_link(photo_bytes)
|
21 |
+
print(f"Rasm linki: {link}")
|
22 |
+
|
23 |
+
if __name__ == "__main__":
|
24 |
+
asyncio.run(main())
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
aiohttp
|
utils.py
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import aiohttp
|
2 |
+
import re
|
3 |
+
import asyncio
|
4 |
+
from io import BytesIO
|
5 |
+
from PIL import Image, ImageFont, ImageDraw
|
6 |
+
|
7 |
+
|
8 |
+
# Telefon raqam uchun regex
|
9 |
+
phone_regex = r'^\+998\d{9}$'
|
10 |
+
|
11 |
+
# Email uchun regex
|
12 |
+
email_regex = r'^[\w\.-]+@[\w\.-]+\.\w+$'
|
13 |
+
|
14 |
+
# Telefon raqam bilan email, fish qatorlari to'liq kiritilganligi tekshirilayabdi
|
15 |
+
def validate_input(fish, email, maqola, phone):
|
16 |
+
if fish == "" or email == "" or maqola == "":
|
17 |
+
return False, "Iltimos barcha maydonlar bo'sh bo'lmasligini ta'minlang!!"
|
18 |
+
elif not re.match(phone_regex, phone):
|
19 |
+
return False, "Telefon raqam noto'g'ri formatda kiritildi. Iltimos, +998xxxxxxxx formatida kiriting."
|
20 |
+
elif not re.match(email_regex, email):
|
21 |
+
return False, "Email manzil noto'g'ri formatda kiritildi. Iltimos, to'g'ri formatda kiriting."
|
22 |
+
else:
|
23 |
+
return True, None
|
24 |
+
|
25 |
+
|
26 |
+
# Global Variables
|
27 |
+
FONT_FILE_1 = ImageFont.truetype(r'Times New Roman Bold.ttf', 30)
|
28 |
+
FONT_FILE_2 = ImageFont.truetype(r'Times New Roman Bold.ttf', 14)
|
29 |
+
FONT_COLOR_1 = "#5E17EB"
|
30 |
+
FONT_COLOR_2 = "#0E477D"
|
31 |
+
TEMPLATE_IMAGE = Image.open(r'Sertifikat.png')
|
32 |
+
WIDTH, HEIGHT = TEMPLATE_IMAGE.size
|
33 |
+
MAX_WIDTH = WIDTH - 80 # Ikkinchi matn uchun maksimal eni
|
34 |
+
MAX_WORDS_PER_LINE = 8 # Har bir qatorda maksimal so'z soni
|
35 |
+
OUTPUT_DIR = "out"
|
36 |
+
|
37 |
+
# Rasmni linki hosil qilinmoqda
|
38 |
+
async def photo_link(photo_bytes):
|
39 |
+
form = aiohttp.FormData()
|
40 |
+
form.add_field(
|
41 |
+
name='file',
|
42 |
+
value=photo_bytes,
|
43 |
+
)
|
44 |
+
|
45 |
+
async with aiohttp.ClientSession() as session:
|
46 |
+
async with session.post('https://telegra.ph/upload', data=form) as response:
|
47 |
+
img_src = await response.json()
|
48 |
+
link = 'https://telegra.ph/' + img_src[0]["src"]
|
49 |
+
return link
|
50 |
+
|
51 |
+
# Sertifikat yasash qismi
|
52 |
+
async def make_certificates(name, second_text):
|
53 |
+
template = TEMPLATE_IMAGE.copy()
|
54 |
+
draw = ImageDraw.Draw(template)
|
55 |
+
|
56 |
+
# Birinchi matnning eni va balandligini topish
|
57 |
+
bbox_1 = FONT_FILE_1.getbbox(name)
|
58 |
+
text_width_1 = bbox_1[2] - bbox_1[0]
|
59 |
+
text_height_1 = bbox_1[3] - bbox_1[1]
|
60 |
+
|
61 |
+
# Birinchi matnni markazga joylashtirish
|
62 |
+
draw.text(((WIDTH - text_width_1) / 2 - 40, (HEIGHT - text_height_1) / 2 + 40), name, fill=FONT_COLOR_1, font=FONT_FILE_1)
|
63 |
+
|
64 |
+
# Ikkinchi matnni bir necha qatorga bo'lish
|
65 |
+
words = second_text.split()
|
66 |
+
lines = []
|
67 |
+
line = []
|
68 |
+
for word in words:
|
69 |
+
if len(line) < MAX_WORDS_PER_LINE:
|
70 |
+
line.append(word)
|
71 |
+
else:
|
72 |
+
lines.append(' '.join(line))
|
73 |
+
line = [word]
|
74 |
+
# Har bir qatordan keyin matnning o'lchamini tekshiramiz
|
75 |
+
bbox_2 = FONT_FILE_2.getbbox(' '.join(line))
|
76 |
+
text_width_2 = bbox_2[2] - bbox_2[0]
|
77 |
+
if text_width_2 > MAX_WIDTH:
|
78 |
+
line.pop() # Ohirgi so'zni olib tashlash
|
79 |
+
lines.append(' '.join(line))
|
80 |
+
line = [word]
|
81 |
+
|
82 |
+
if line:
|
83 |
+
lines.append(' '.join(line))
|
84 |
+
|
85 |
+
y = (HEIGHT - text_height_1) / 2 + 55 + text_height_1 + 10
|
86 |
+
for line in lines:
|
87 |
+
bbox_2 = FONT_FILE_2.getbbox(line)
|
88 |
+
text_width_2 = bbox_2[2] - bbox_2[0]
|
89 |
+
text_height_2 = bbox_2[3] - bbox_2[1]
|
90 |
+
draw.text(((WIDTH - text_width_2) / 2 - 40, y), line, fill=FONT_COLOR_2, font=FONT_FILE_2)
|
91 |
+
y += text_height_2 + 5 # Qatorlar orasidagi masofani oshirish
|
92 |
+
|
93 |
+
# Sertifikatni BytesIO obyektiga saqlash
|
94 |
+
image_bytes = BytesIO()
|
95 |
+
template.save(image_bytes, format='PNG')
|
96 |
+
image_bytes.seek(0)
|
97 |
+
|
98 |
+
certificate_link = await photo_link(image_bytes)
|
99 |
+
return certificate_link
|