|
from flask import Flask, request, render_template_string, send_from_directory, jsonify, render_template, Response |
|
from flask import render_template |
|
import sqlite3 |
|
import os |
|
import uuid |
|
import shutil |
|
import requests |
|
|
|
|
|
import re |
|
import json |
|
import base64 |
|
import logging |
|
import csv |
|
|
|
|
|
from datetime import datetime |
|
import pytz |
|
|
|
|
|
import psutil |
|
|
|
|
|
from base import replace_null_with_empty_string |
|
|
|
|
|
|
|
|
|
from ns import send_ns |
|
api_key_sys = os.getenv('api_key_sys') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__, template_folder="./") |
|
|
|
app.config['DEBUG'] = True |
|
|
|
UPLOAD_FOLDER = 'static' |
|
HTML_FOLDER = 'html' |
|
|
|
|
|
if not os.path.exists(UPLOAD_FOLDER): |
|
os.makedirs(UPLOAD_FOLDER) |
|
|
|
if not os.path.exists(HTML_FOLDER): |
|
os.makedirs(HTML_FOLDER) |
|
|
|
|
|
|
|
|
|
|
|
DATABASES = ['data_gc.db', 'data1.db', 'data2.db', 'data3.db', 'data4.db', 'data5.db'] |
|
|
|
|
|
|
|
def init_db(db_name): |
|
conn = sqlite3.connect(db_name) |
|
cursor = conn.cursor() |
|
cursor.execute(''' |
|
CREATE TABLE IF NOT EXISTS contacts ( |
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
name TEXT NOT NULL, |
|
phone TEXT NOT NULL, |
|
email TEXT NOT NULL, |
|
vk_id TEXT, |
|
chat_id TEXT, |
|
ws_st TEXT, |
|
ws_stop TEXT, |
|
web_st INTEGER, |
|
fin_prog INTEGER, |
|
b_city TEXT, |
|
b_fin TEXT, |
|
b_ban TEXT, |
|
b_ign TEXT, |
|
b_baners TEXT, |
|
b_butt TEXT, |
|
b_mess TEXT, |
|
orders TEXT, |
|
curator TEXT, |
|
pr1 TEXT, |
|
pr2 TEXT, |
|
pr3 TEXT, |
|
pr4 TEXT, |
|
pr5 TEXT, |
|
gc_url TEXT, |
|
key_pr TEXT, |
|
n_con TEXT, |
|
canal TEXT, |
|
data_on TEXT, |
|
data_t TEXT, |
|
utm_source TEXT, |
|
utm_medium TEXT, |
|
utm_campaign TEXT, |
|
utm_term TEXT, |
|
utm_content TEXT, |
|
gcpc TEXT |
|
) |
|
''') |
|
conn.commit() |
|
conn.close() |
|
|
|
for db in DATABASES: |
|
init_db(db) |
|
|
|
|
|
DATABASE_NEW = 'data_gc.db' |
|
|
|
|
|
import logging |
|
|
|
logging.basicConfig(level=logging.DEBUG) |
|
|
|
|
|
|
|
def clean_phone_number_ss(phone_number): |
|
return re.sub(r'\D', '', phone_number) |
|
|
|
@app.route('/order_new', methods=['GET']) |
|
def shop_order_new(): |
|
try: |
|
logging.debug("Starting shop_order_new") |
|
api_sys_control = request.args.get('api_sys') |
|
|
|
if api_sys_control != api_key_sys: |
|
logging.warning("Unauthorized access attempt") |
|
return json.dumps({"error": "Unauthorized access"}), 403 |
|
|
|
name = request.args.get('name', '') |
|
email = request.args.get('email', '') |
|
phone = request.args.get('phone', '').lstrip('+') |
|
order = request.args.get('order', '') |
|
status = request.args.get('status', '') |
|
del_flag = request.args.get('del', '') |
|
n_con_flag = request.args.get('n_con', '') |
|
|
|
if not email or not phone: |
|
logging.error("Email and phone are required") |
|
return json.dumps({"error": "Email and phone are required"}), 400 |
|
|
|
phone = clean_phone_number_ss(phone) |
|
|
|
conn = sqlite3.connect(DATABASE_NEW) |
|
cursor = conn.cursor() |
|
|
|
cursor.execute("SELECT * FROM contacts WHERE email = ? OR phone = ?", (email, phone)) |
|
result = cursor.fetchone() |
|
|
|
if result: |
|
shop_st = result[17] if result[17] else '{}' |
|
shop_st_data = json.loads(shop_st) |
|
logging.debug(f"Existing record found. Loaded JSON: {shop_st_data}") |
|
else: |
|
shop_st_data = {} |
|
|
|
if del_flag == '1': |
|
if order in shop_st_data: |
|
del shop_st_data[order] |
|
elif order and status: |
|
shop_st_data[order] = status |
|
|
|
shop_st_json = json.dumps(shop_st_data) |
|
|
|
utc_now = datetime.utcnow() |
|
msk_tz = pytz.timezone('Europe/Moscow') |
|
msk_now = utc_now.replace(tzinfo=pytz.utc).astimezone(msk_tz) |
|
data_on = msk_now.strftime('%Y-%m-%d %H:%M:%S') |
|
|
|
columns_to_update = ['name', 'phone', 'email', 'orders', 'n_con', 'data_on'] |
|
values_to_update = [name, phone, email, shop_st_json, n_con_flag, data_on] |
|
|
|
if result: |
|
set_clause = ', '.join([f"{col} = ?" for col in columns_to_update]) |
|
query = f"UPDATE contacts SET {set_clause} WHERE email = ? OR phone = ?" |
|
cursor.execute(query, values_to_update + [email, phone]) |
|
else: |
|
query = f"INSERT INTO contacts ({', '.join(columns_to_update)}) VALUES ({', '.join(['?' for _ in columns_to_update])})" |
|
cursor.execute(query, values_to_update) |
|
|
|
conn.commit() |
|
|
|
replace_null_with_empty_string(conn) |
|
|
|
conn.close() |
|
|
|
return json.dumps(shop_st_data), 200 |
|
|
|
except Exception as e: |
|
logging.error(f"An error occurred: {str(e)}") |
|
return json.dumps({"error": str(e)}), 500 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/data_gc_tab', methods=['GET']) |
|
def data_gc_tab(): |
|
api_sys_control = request.args.get('api_sys') |
|
if api_sys_control != api_key_sys: |
|
return "EUR 22", 200 |
|
return render_template('data_gc_tab.html') |
|
|
|
|
|
@app.route('/data_gc_tab_out', methods=['GET']) |
|
def data_gc_tab_out(): |
|
try: |
|
api_sys_control = request.args.get('api_sys') |
|
|
|
if api_sys_control != api_key_sys: |
|
return "EUR 22", 200 |
|
|
|
conn = sqlite3.connect('data_gc.db') |
|
cursor = conn.cursor() |
|
cursor.execute(''' |
|
SELECT id, name, phone, email, vk_id, chat_id, ws_st, ws_stop, web_st, fin_prog, |
|
b_city, b_fin, b_ban, b_ign, b_baners, b_butt, b_mess, orders, curator, |
|
pr1, pr2, pr3, pr4, pr5, gc_url, key_pr, n_con, canal, data_on, data_t, utm_source, utm_medium, utm_campaign, utm_term, utm_content, gcpc |
|
FROM contacts |
|
''') |
|
contacts = cursor.fetchall() |
|
conn.close() |
|
|
|
contacts_json = [{ |
|
'id': contact[0], 'name': contact[1], 'phone': contact[2], 'email': contact[3], |
|
'vk_id': contact[4], 'chat_id': contact[5], 'ws_st': contact[6], 'ws_stop': contact[7], |
|
'web_st': contact[8], 'fin_prog': contact[9], 'b_city': contact[10], 'b_fin': contact[11], |
|
'b_ban': contact[12], 'b_ign': contact[13], 'b_baners': contact[14], 'b_butt': contact[15], |
|
'b_mess': contact[16], 'orders': contact[17], 'curator': contact[18], 'pr1': contact[19], |
|
'pr2': contact[20], 'pr3': contact[21], 'pr4': contact[22], 'pr5': contact[23], |
|
'gc_url': contact[24], 'key_pr': contact[25], 'n_con': contact[26], 'canal': contact[27],'data_on': contact[28], |
|
'data_t': contact[29],'utm_source': contact[30], 'utm_medium': contact[31], 'utm_campaign': contact[32], |
|
'utm_term': contact[33], 'utm_content': contact[34], 'gcpc': contact[34] |
|
} for contact in contacts] |
|
return jsonify(contacts_json), 200 |
|
except Exception as e: |
|
error_message = f"Error getting data from data_gc: {e}" |
|
print(error_message) |
|
return error_message, 500 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/get_current_time', methods=['GET']) |
|
def get_current_time(): |
|
utc_now = datetime.utcnow() |
|
msk_tz = pytz.timezone('Europe/Moscow') |
|
msk_now = utc_now.replace(tzinfo=pytz.utc).astimezone(msk_tz) |
|
current_time = msk_now.strftime('%Y-%m-%d %H:%M:%S') |
|
return jsonify({'current_time': current_time}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/add_ns', methods=['GET']) |
|
def handle_in1(): |
|
name = request.args.get('name') |
|
email = request.args.get('email') |
|
phone = request.args.get('phone') |
|
base_url = 'https://api.notisend.ru/v1' |
|
token = request.args.get('token') |
|
list_id = request.args.get('list_id') |
|
phone_id = request.args.get('phone_id') |
|
name_id = request.args.get('name_id') |
|
|
|
|
|
if not all([name, email, phone, token, list_id, phone_id, name_id]): |
|
return jsonify({'error': 'Missing required parameters'}), 400 |
|
|
|
|
|
response_ns = send_ns(base_url, token, list_id, email, phone, name, phone_id, name_id) |
|
|
|
|
|
return jsonify({'responses': [response_ns]}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/upload', methods=['POST']) |
|
def upload_file(): |
|
if 'file' not in request.files: |
|
return "No file part", 400 |
|
file = request.files['file'] |
|
if file.filename == '': |
|
return "No selected file", 400 |
|
|
|
|
|
unique_filename = str(uuid.uuid4()) + os.path.splitext(file.filename)[1] |
|
save_path = os.path.join(UPLOAD_FOLDER, unique_filename) |
|
file.save(save_path) |
|
|
|
|
|
full_url = request.url_root.replace('http://', 'https://') + 'uploads/' + unique_filename |
|
return f"File uploaded successfully and saved to {full_url}", 200 |
|
|
|
|
|
|
|
|
|
@app.route('/uploads/<filename>', methods=['GET']) |
|
def uploaded_file(filename): |
|
return send_from_directory(UPLOAD_FOLDER, filename) |
|
|
|
|
|
|
|
|
|
|
|
@app.route('/up_fa', methods=['GET']) |
|
def up_fa(): |
|
return render_template('up_fa.html') |
|
|
|
|
|
@app.route('/ns_info', methods=['GET']) |
|
def ns_info(): |
|
return render_template('ns_info.html') |
|
|
|
@app.route('/api/group/<int:group_id>/parameters', methods=['GET']) |
|
def get_group_parameters(group_id): |
|
api_token = request.args.get('apiToken') |
|
|
|
if not api_token: |
|
return jsonify({'error': 'API Token is required'}), 400 |
|
|
|
url = f'https://api.notisend.ru/v1/email/lists/{group_id}/parameters' |
|
headers = { |
|
'Content-Type': 'application/json', |
|
'Authorization': f'Bearer {api_token}' |
|
} |
|
|
|
try: |
|
response = requests.get(url, headers=headers) |
|
response.raise_for_status() |
|
data = response.json() |
|
return jsonify(data) |
|
except requests.RequestException as e: |
|
return jsonify({'error': str(e)}), 500 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/up_page', methods=['POST']) |
|
def upload_page(): |
|
if 'file' not in request.files: |
|
return "No file part", 400 |
|
file = request.files['file'] |
|
if file.filename == '': |
|
return "No selected file", 400 |
|
|
|
filename = request.form.get('filename') |
|
if not filename: |
|
return "Filename is required", 400 |
|
|
|
save_path = os.path.join(HTML_FOLDER, filename + '.html') |
|
file.save(save_path) |
|
|
|
|
|
full_url = request.url_root.replace('http://', 'https://') + filename |
|
return f"Page uploaded successfully and saved to {full_url}", 200 |
|
|
|
@app.route('/<path:filename>', methods=['GET']) |
|
def serve_html(filename): |
|
if not filename.endswith('.html'): |
|
filename += '.html' |
|
return send_from_directory(HTML_FOLDER, filename) |
|
|
|
@app.route('/up_page', methods=['GET']) |
|
def up_page(): |
|
return render_template('up_page.html') |
|
|
|
@app.route('/monitor', methods=['GET']) |
|
def monitor(): |
|
|
|
files = os.listdir(UPLOAD_FOLDER) |
|
html_files = os.listdir(HTML_FOLDER) |
|
|
|
|
|
total, used, free = shutil.disk_usage("/") |
|
|
|
|
|
total_gb = total // (2**30) |
|
used_gb = used // (2**30) |
|
free_gb = free // (2**30) |
|
|
|
|
|
memory = psutil.virtual_memory() |
|
memory_total_gb = memory.total // (2**30) |
|
memory_used_gb = memory.used // (2**30) |
|
memory_free_gb = memory.free // (2**30) |
|
|
|
|
|
cpu_count = psutil.cpu_count(logical=True) |
|
|
|
return render_template('monitor.html', |
|
uploaded_files=files, |
|
uploaded_html_files=html_files, |
|
disk_space={ |
|
'total': f"{total_gb} GB", |
|
'used': f"{used_gb} GB", |
|
'free': f"{free_gb} GB" |
|
}, |
|
memory_usage={ |
|
'total': f"{memory_total_gb} GB", |
|
'used': f"{memory_used_gb} GB", |
|
'free': f"{memory_free_gb} GB" |
|
}, |
|
cpu_count=cpu_count) |
|
|
|
if __name__ == '__main__': |
|
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860))) |