Aleksmorshen commited on
Commit
5cc5b45
·
verified ·
1 Parent(s): 1be6cf5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -142
app.py CHANGED
@@ -41,10 +41,8 @@ visitor_data_cache = {}
41
  def download_data_from_hf():
42
  global visitor_data_cache
43
  if not HF_TOKEN_READ:
44
- logging.warning("HF_TOKEN_READ not set. Skipping Hugging Face download.")
45
  return False
46
  try:
47
- logging.info(f"Attempting to download {HF_DATA_FILE_PATH} from {REPO_ID}...")
48
  hf_hub_download(
49
  repo_id=REPO_ID,
50
  filename=HF_DATA_FILE_PATH,
@@ -55,20 +53,17 @@ def download_data_from_hf():
55
  force_download=True,
56
  etag_timeout=10
57
  )
58
- logging.info("Data file successfully downloaded from Hugging Face.")
59
  with _data_lock:
60
  try:
61
  with open(DATA_FILE, 'r', encoding='utf-8') as f:
62
  visitor_data_cache = json.load(f)
63
- logging.info("Successfully loaded downloaded data into cache.")
64
  except (FileNotFoundError, json.JSONDecodeError) as e:
65
- logging.error(f"Error reading downloaded data file: {e}. Starting with empty cache.")
66
  visitor_data_cache = {}
67
  return True
68
  except RepositoryNotFoundError:
69
- logging.error(f"Hugging Face repository '{REPO_ID}' not found. Cannot download data.")
70
  except Exception as e:
71
- logging.error(f"Error downloading data from Hugging Face: {e}")
72
  return False
73
 
74
  def load_visitor_data():
@@ -78,15 +73,11 @@ def load_visitor_data():
78
  try:
79
  with open(DATA_FILE, 'r', encoding='utf-8') as f:
80
  visitor_data_cache = json.load(f)
81
- logging.info("Visitor data loaded from local JSON.")
82
  except FileNotFoundError:
83
- logging.warning(f"{DATA_FILE} not found locally. Starting with empty data.")
84
  visitor_data_cache = {}
85
  except json.JSONDecodeError:
86
- logging.error(f"Error decoding {DATA_FILE}. Starting with empty data.")
87
  visitor_data_cache = {}
88
  except Exception as e:
89
- logging.error(f"Unexpected error loading visitor data: {e}")
90
  visitor_data_cache = {}
91
  return visitor_data_cache
92
 
@@ -96,17 +87,14 @@ def save_visitor_data(data):
96
  visitor_data_cache.update(data)
97
  with open(DATA_FILE, 'w', encoding='utf-8') as f:
98
  json.dump(visitor_data_cache, f, ensure_ascii=False, indent=4)
99
- logging.info(f"Visitor data successfully saved to {DATA_FILE}.")
100
  upload_data_to_hf_async()
101
  except Exception as e:
102
- logging.error(f"Error saving visitor data: {e}")
103
 
104
  def upload_data_to_hf():
105
  if not HF_TOKEN_WRITE:
106
- logging.warning("HF_TOKEN_WRITE not set. Skipping Hugging Face upload.")
107
  return
108
  if not os.path.exists(DATA_FILE):
109
- logging.warning(f"{DATA_FILE} does not exist. Skipping upload.")
110
  return
111
 
112
  try:
@@ -114,10 +102,8 @@ def upload_data_to_hf():
114
  with _data_lock:
115
  file_content_exists = os.path.getsize(DATA_FILE) > 0
116
  if not file_content_exists:
117
- logging.warning(f"{DATA_FILE} is empty. Skipping upload.")
118
  return
119
 
120
- logging.info(f"Attempting to upload {DATA_FILE} to {REPO_ID}/{HF_DATA_FILE_PATH}...")
121
  api.upload_file(
122
  path_or_fileobj=DATA_FILE,
123
  path_in_repo=HF_DATA_FILE_PATH,
@@ -126,9 +112,8 @@ def upload_data_to_hf():
126
  token=HF_TOKEN_WRITE,
127
  commit_message=f"Update visitor data {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
128
  )
129
- logging.info("Visitor data successfully uploaded to Hugging Face.")
130
  except Exception as e:
131
- logging.error(f"Error uploading data to Hugging Face: {e}")
132
 
133
  def upload_data_to_hf_async():
134
  upload_thread = threading.Thread(target=upload_data_to_hf, daemon=True)
@@ -136,11 +121,9 @@ def upload_data_to_hf_async():
136
 
137
  def periodic_backup():
138
  if not HF_TOKEN_WRITE:
139
- logging.info("Periodic backup disabled: HF_TOKEN_WRITE not set.")
140
  return
141
  while True:
142
  time.sleep(3600)
143
- logging.info("Initiating periodic backup...")
144
  upload_data_to_hf()
145
 
146
  def verify_telegram_data(init_data_str):
@@ -163,13 +146,12 @@ def verify_telegram_data(init_data_str):
163
  auth_date = int(parsed_data.get('auth_date', [0])[0])
164
  current_time = int(time.time())
165
  if current_time - auth_date > 86400:
166
- logging.warning(f"Telegram InitData is older than 1 hour (Auth Date: {auth_date}, Current: {current_time}).")
167
  return parsed_data, True
168
  else:
169
- logging.warning(f"Data verification failed. Calculated: {calculated_hash}, Received: {received_hash}")
170
  return parsed_data, False
171
  except Exception as e:
172
- logging.error(f"Error verifying Telegram data: {e}")
173
  return None, False
174
 
175
  TEMPLATE = """
@@ -644,7 +626,7 @@ TEMPLATE = """
644
 
645
  const modal = document.getElementById("saveModal");
646
  const saveCardBtn = document.getElementById("save-card-btn");
647
- const closeBtn = document(Id("modal-close-btn");
648
 
649
  if (saveCardBtn && modal && closeBtn) {
650
  saveCardBtn.addEventListener('click', (e) => {
@@ -902,7 +884,6 @@ dp = Dispatcher()
902
 
903
  def generate_bot_response(query: str, context: str):
904
  if not GEMINI_API_KEY:
905
- logging.warning("GEMINI_API_KEY not set. Cannot use AI.")
906
  return "Извините, функция ответа с использованием AI временно недоступна."
907
 
908
  lower_query = query.lower()
@@ -947,7 +928,6 @@ ASSISTANT RESPONSE:"""
947
  return response.text.strip()
948
 
949
  except Exception as e:
950
- logging.error(f"Error generating AI response: {e}")
951
  return "Извините, произошла ошибка при обработке вашего запроса."
952
 
953
  @dp.message()
@@ -955,7 +935,6 @@ async def handle_message(message: types.Message):
955
  logging.info(f"Received message from user {message.from_user.id}: {message.text}")
956
  user_query = message.text
957
  if not user_query:
958
- logging.warning("Received empty message.")
959
  return
960
 
961
  try:
@@ -974,136 +953,28 @@ async def handle_message(message: types.Message):
974
  try:
975
  await message.answer("Извините, произошла внутренняя ошибка при обработке вашего сообщения.")
976
  except Exception:
977
- logging.error("Failed to send error message to user.")
978
 
979
 
980
- @app.route('/')
981
- def index():
982
- theme_params = {}
983
- return render_template_string(TEMPLATE, theme=theme_params)
984
-
985
- @app.route('/verify', methods=['POST'])
986
- def verify_data():
987
- try:
988
- req_data = request.get_json()
989
- init_data_str = req_data.get('initData')
990
- if not init_data_str:
991
- return jsonify({"status": "error", "message": "Missing initData"}), 400
992
-
993
- user_data_parsed, is_valid = verify_telegram_data(init_data_str)
994
-
995
- user_info_dict = {}
996
- if user_data_parsed and 'user' in user_data_parsed:
997
- try:
998
- user_json_str = unquote(user_data_parsed['user'][0])
999
- user_info_dict = json.loads(user_json_str)
1000
- except Exception as e:
1001
- logging.error(f"Could not parse user JSON: {e}")
1002
- user_info_dict = {}
1003
-
1004
- if is_valid:
1005
- user_id = user_info_dict.get('id')
1006
- if user_id:
1007
- now = time.time()
1008
- user_entry = {
1009
- str(user_id): {
1010
- 'id': user_id,
1011
- 'first_name': user_info_dict.get('first_name'),
1012
- 'last_name': user_info_dict.get('last_name'),
1013
- 'username': user_info_dict.get('username'),
1014
- 'photo_url': user_info_dict.get('photo_url'),
1015
- 'language_code': user_info_dict.get('language_code'),
1016
- 'is_premium': user_info_dict.get('is_premium', False),
1017
- 'phone_number': user_info_dict.get('phone_number'),
1018
- 'visited_at': now,
1019
- 'visited_at_str': datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S')
1020
- }
1021
- }
1022
- save_visitor_data(user_entry)
1023
- return jsonify({"status": "ok", "verified": True, "user": user_info_dict}), 200
1024
- else:
1025
- logging.warning(f"Verification failed for user: {user_info_dict.get('id')}")
1026
- return jsonify({"status": "error", "verified": False, "message": "Invalid data"}), 403
1027
-
1028
- except Exception as e:
1029
- logging.exception("Error in /verify endpoint")
1030
- return jsonify({"status": "error", "message": "Internal server error"}), 500
1031
-
1032
- @app.route('/admin')
1033
- def admin_panel():
1034
- current_data = load_visitor_data()
1035
- users_list = list(current_data.values())
1036
- return render_template_string(ADMIN_TEMPLATE, users=users_list)
1037
-
1038
- @app.route('/admin/download_data', methods=['POST'])
1039
- def admin_trigger_download():
1040
- success = download_data_from_hf()
1041
- if success:
1042
- return jsonify({"status": "ok", "message": "Скачивание данных с Hugging Face завершено. Страница будет обновлена."})
1043
- else:
1044
- return jsonify({"status": "error", "message": "Ошибка скачивания данных с Hugging Face. Проверьте логи."}), 500
1045
-
1046
- @app.route('/admin/upload_data', methods=['POST'])
1047
- def admin_trigger_upload():
1048
- if not HF_TOKEN_WRITE:
1049
- return jsonify({"status": "error", "message": "HF_TOKEN_WRITE не настроен на сервере."}), 400
1050
- upload_data_to_hf_async()
1051
- return jsonify({"status": "ok", "message": "Загрузка данных на Hugging Face запущена в фоновом режиме."})
1052
-
1053
  def start_bot_polling():
1054
- logging.info("Starting bot polling thread...")
1055
  try:
1056
- asyncio.run(dp.start_polling(bot))
 
 
1057
  logging.info("Bot polling stopped.")
1058
  except Exception as e:
1059
  logging.exception("Bot polling failed")
1060
 
1061
  if __name__ == '__main__':
1062
- logging.info("---")
1063
- logging.info("--- MORSHEN GROUP SERVER (FLASK + AIOGRAM) ---")
1064
- logging.info("---")
1065
- logging.info(f"Flask server starting on http://{HOST}:{PORT}")
1066
- logging.info(f"Using Bot Token ID: {BOT_TOKEN.split(':')[0]}")
1067
- logging.info(f"Visitor data file: {DATA_FILE}")
1068
- logging.info(f"Hugging Face Repo: {REPO_ID}")
1069
- logging.info(f"HF Data Path: {HF_DATA_FILE_PATH}")
1070
- if not HF_TOKEN_READ or not HF_TOKEN_WRITE:
1071
- logging.warning("---")
1072
- logging.warning("--- WARNING: HUGGING FACE TOKEN(S) NOT SET ---")
1073
- logging.warning("--- Backup/restore functionality will be limited. Set HF_TOKEN_READ and HF_TOKEN_WRITE environment variables.")
1074
- logging.warning("---")
1075
- else:
1076
- logging.info("--- Hugging Face tokens found.")
1077
- logging.info("--- Attempting initial data download from Hugging Face...")
1078
- download_data_from_hf()
1079
-
1080
- if not GEMINI_API_KEY:
1081
- logging.warning("---")
1082
- logging.warning("--- WARNING: GEMINI_API_KEY NOT SET ---")
1083
- logging.warning("--- AI response functionality will be limited or unavailable. Set GEMINI_API_KEY environment variable.")
1084
- logging.warning("---")
1085
- else:
1086
- logging.info("--- GEMINI_API_KEY found.")
1087
- logging.info(f"--- Using AI model: {GENAI_MODEL}")
1088
-
1089
  load_visitor_data()
1090
 
1091
- logging.warning("---")
1092
- logging.warning("--- SECURITY WARNING ---")
1093
- logging.warning("--- The /admin route and its sub-routes are NOT protected.")
1094
- logging.warning("--- Implement proper authentication before deploying.")
1095
- logging.warning("---")
1096
-
1097
  if HF_TOKEN_WRITE:
1098
  backup_thread = threading.Thread(target=periodic_backup, daemon=True)
1099
  backup_thread.start()
1100
- logging.info("--- Periodic backup thread started (every hour).")
1101
- else:
1102
- logging.info("--- Periodic backup disabled (HF_TOKEN_WRITE missing).")
1103
 
1104
  bot_thread = threading.Thread(target=start_bot_polling, daemon=True)
1105
  bot_thread.start()
1106
- logging.info("--- Telegram bot polling thread initiated.")
1107
 
1108
- logging.info("--- Server Ready ---")
1109
  app.run(host=HOST, port=PORT, debug=False)
 
41
  def download_data_from_hf():
42
  global visitor_data_cache
43
  if not HF_TOKEN_READ:
 
44
  return False
45
  try:
 
46
  hf_hub_download(
47
  repo_id=REPO_ID,
48
  filename=HF_DATA_FILE_PATH,
 
53
  force_download=True,
54
  etag_timeout=10
55
  )
 
56
  with _data_lock:
57
  try:
58
  with open(DATA_FILE, 'r', encoding='utf-8') as f:
59
  visitor_data_cache = json.load(f)
 
60
  except (FileNotFoundError, json.JSONDecodeError) as e:
 
61
  visitor_data_cache = {}
62
  return True
63
  except RepositoryNotFoundError:
64
+ pass
65
  except Exception as e:
66
+ pass
67
  return False
68
 
69
  def load_visitor_data():
 
73
  try:
74
  with open(DATA_FILE, 'r', encoding='utf-8') as f:
75
  visitor_data_cache = json.load(f)
 
76
  except FileNotFoundError:
 
77
  visitor_data_cache = {}
78
  except json.JSONDecodeError:
 
79
  visitor_data_cache = {}
80
  except Exception as e:
 
81
  visitor_data_cache = {}
82
  return visitor_data_cache
83
 
 
87
  visitor_data_cache.update(data)
88
  with open(DATA_FILE, 'w', encoding='utf-8') as f:
89
  json.dump(visitor_data_cache, f, ensure_ascii=False, indent=4)
 
90
  upload_data_to_hf_async()
91
  except Exception as e:
92
+ pass
93
 
94
  def upload_data_to_hf():
95
  if not HF_TOKEN_WRITE:
 
96
  return
97
  if not os.path.exists(DATA_FILE):
 
98
  return
99
 
100
  try:
 
102
  with _data_lock:
103
  file_content_exists = os.path.getsize(DATA_FILE) > 0
104
  if not file_content_exists:
 
105
  return
106
 
 
107
  api.upload_file(
108
  path_or_fileobj=DATA_FILE,
109
  path_in_repo=HF_DATA_FILE_PATH,
 
112
  token=HF_TOKEN_WRITE,
113
  commit_message=f"Update visitor data {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
114
  )
 
115
  except Exception as e:
116
+ pass
117
 
118
  def upload_data_to_hf_async():
119
  upload_thread = threading.Thread(target=upload_data_to_hf, daemon=True)
 
121
 
122
  def periodic_backup():
123
  if not HF_TOKEN_WRITE:
 
124
  return
125
  while True:
126
  time.sleep(3600)
 
127
  upload_data_to_hf()
128
 
129
  def verify_telegram_data(init_data_str):
 
146
  auth_date = int(parsed_data.get('auth_date', [0])[0])
147
  current_time = int(time.time())
148
  if current_time - auth_date > 86400:
149
+ pass
150
  return parsed_data, True
151
  else:
152
+ pass
153
  return parsed_data, False
154
  except Exception as e:
 
155
  return None, False
156
 
157
  TEMPLATE = """
 
626
 
627
  const modal = document.getElementById("saveModal");
628
  const saveCardBtn = document.getElementById("save-card-btn");
629
+ const closeBtn = document.getElementById("modal-close-btn");
630
 
631
  if (saveCardBtn && modal && closeBtn) {
632
  saveCardBtn.addEventListener('click', (e) => {
 
884
 
885
  def generate_bot_response(query: str, context: str):
886
  if not GEMINI_API_KEY:
 
887
  return "Извините, функция ответа с использованием AI временно недоступна."
888
 
889
  lower_query = query.lower()
 
928
  return response.text.strip()
929
 
930
  except Exception as e:
 
931
  return "Извините, произошла ошибка при обработке вашего запроса."
932
 
933
  @dp.message()
 
935
  logging.info(f"Received message from user {message.from_user.id}: {message.text}")
936
  user_query = message.text
937
  if not user_query:
 
938
  return
939
 
940
  try:
 
953
  try:
954
  await message.answer("Извините, произошла внутренняя ошибка при обработке вашего сообщения.")
955
  except Exception:
956
+ pass
957
 
958
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
959
  def start_bot_polling():
960
+ logging.info("Starting bot polling thread (signals disabled)...")
961
  try:
962
+ loop = asyncio.new_event_loop()
963
+ asyncio.set_event_loop(loop)
964
+ loop.run_until_complete(dp.start_polling(bot, handle_signals=False))
965
  logging.info("Bot polling stopped.")
966
  except Exception as e:
967
  logging.exception("Bot polling failed")
968
 
969
  if __name__ == '__main__':
970
+ download_data_from_hf()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
971
  load_visitor_data()
972
 
 
 
 
 
 
 
973
  if HF_TOKEN_WRITE:
974
  backup_thread = threading.Thread(target=periodic_backup, daemon=True)
975
  backup_thread.start()
 
 
 
976
 
977
  bot_thread = threading.Thread(target=start_bot_polling, daemon=True)
978
  bot_thread.start()
 
979
 
 
980
  app.run(host=HOST, port=PORT, debug=False)