import os import sys import platform for i in range(0, 2): try: from diff_match_patch import diff_match_patch import werkzeug.routing import werkzeug.debug import flask_compress import flask_reggie import tornado.ioloop import tornado.httpserver import tornado.wsgi import urllib.request import email.mime.text import flask_minify import sqlite3 import pymysql import hashlib import smtplib import zipfile import shutil import threading import logging import random import flask import json import html import re if sys.version_info < (3, 6): import sha3 from .mark import * except ImportError as e: if i == 0: print(e) print('----') if platform.system() == 'Linux': ok = os.system('python3 -m pip install --user -r requirements.txt') if ok == 0: print('----') os.execl(sys.executable, sys.executable, *sys.argv) else: raise elif platform.system() == 'Windows': ok = os.system('python -m pip install --user -r requirements.txt') if ok == 0: print('----') os.execl(sys.executable, sys.executable, *sys.argv) else: raise else: print('----') print(e) raise else: print('----') print(e) raise app_var = json.loads(open('data/app_var.json', encoding='utf8').read()) def load_conn(data): global conn global curs conn = data curs = conn.cursor() load_conn2(data) def send_email(who, title, data): try: curs.execute(db_change('' + \ 'select name, data from other ' + \ 'where name = "smtp_email" or name = "smtp_pass" or name = "smtp_server" or name = "smtp_port" or name = "smtp_security"' + \ '')) rep_data = curs.fetchall() smtp_email = '' smtp_pass = '' smtp_server = '' smtp_security = '' smtp_port = '' smtp = '' if rep_data: smtp_email = '' smtp_pass = '' for i in rep_data: if i[0] == 'smtp_email': smtp_email = i[1] elif i[0] == 'smtp_pass': smtp_pass = i[1] elif i[0] == 'smtp_server': smtp_server = i[1] elif i[0] == 'smtp_security': smtp_security = i[1] elif i[0] == 'smtp_port': smtp_port = i[1] smtp_port = int(smtp_port) if smtp_security == 'plain': smtp = smtplib.SMTP(smtp_server, smtp_port) elif smtp_security == 'starttls': smtp = smtplib.SMTP(smtp_server, smtp_port) smtp.starttls() else: # if smtp_security == 'tls': smtp = smtplib.SMTP_SSL(smtp_server, smtp_port) smtp.login(smtp_email, smtp_pass) msg = email.mime.text.MIMEText(data) msg['Subject'] = title smtp.sendmail(smtp_email, who, msg.as_string()) smtp.quit() except: print('----') print('Error : Email send error') def last_change(data): json_address = re.sub(r"(((?!\.|\/).)+)\.html$", "set.json", skin_check()) try: json_data = json.loads(open(json_address, encoding='utf8').read()) except: json_data = 0 if json_data != 0: for j_data in json_data: if "class" in json_data[j_data]: if "require" in json_data[j_data]: re_data = re.compile("<((?:" + j_data + ")( (?:(?!>).)*)?)>") s_data = re_data.findall(data) for i_data in s_data: e_data = 0 for j_i_data in json_data[j_data]["require"]: re_data_2 = re.compile("( |^)" + j_i_data + " *= *[\'\"]" + json_data[j_data]["require"][j_i_data] + "[\'\"]") if not re_data_2.search(i_data[1]): re_data_2 = re.compile("( |^)" + j_i_data + "=" + json_data[j_data]["require"][j_i_data] + "(?: |$)") if not re_data_2.search(i_data[1]): e_data = 1 break if e_data == 0: re_data_3 = re.compile("<" + i_data[0] + ">") data = re_data_3.sub("<" + i_data[0] + " class=\"" + json_data[j_data]["class"] + "\">", data) else: re_data = re.compile("<(?P" + j_data + "(?: (?:(?!>).)*)?)>") data = re_data.sub("<\g class=\"" + json_data[j_data]["class"] + "\">", data) return data def easy_minify(data, tool = None): return last_change(data) def render_set(title = '', data = '', num = 0, s_data = 0, include = None): if acl_check(title, 'render') == 1: return 'HTTP Request 401.3' elif s_data == 1: return data else: if data != None: return render_do(title, data, num, include) else: return 'HTTP Request 404' def update(ver_num, set_data): print('----') # 업데이트 하위 호환 유지 함수 if ver_num < 3160027: print('Add init set') set_init() if ver_num < 3170002: curs.execute(db_change("select html from html_filter where kind = 'extension'")) if not curs.fetchall(): for i in ['jpg', 'jpeg', 'png', 'gif', 'webp']: curs.execute(db_change("insert into html_filter (html, kind) values (?, 'extension')"), [i]) if ver_num < 3170400: curs.execute(db_change("select title, sub, code from topic where id = '1'")) change_topic = curs.fetchall() for i in change_topic: curs.execute(db_change("update topic set code = ? where title = ? and sub = ?"), [i[2], i[0], i[1]]) curs.execute(db_change("update rd set code = ? where title = ? and sub = ?"), [i[2], i[0], i[1]]) if ver_num < 3171800: curs.execute(db_change("select data from other where name = 'recaptcha'")) change_rec = curs.fetchall() if change_rec and change_rec[0][0] != '': new_rec = re.search(r'data-sitekey="([^"]+)"', change_rec[0][0]) if new_rec: curs.execute(db_change("update other set data = ? where name = 'recaptcha'"), [new_rec.group(1)]) else: curs.execute(db_change("update other set data = '' where name = 'recaptcha'")) curs.execute(db_change("update other set data = '' where name = 'sec_re'")) if ver_num < 3172800 and set_data['db_type'] == 'mysql': get_data_mysql = json.loads(open('data/mysql.json').read()) with open('data/mysql.json', 'w') as f: f.write('{ "user" : "' + get_data_mysql['user'] + '", "password" : "' + get_data_mysql['password'] + '", "host" : "localhost" }') if ver_num < 3182000: curs.execute(db_change('delete from cache_data')) if ver_num < 3183603: curs.execute(db_change("select block from ban where band = 'O'")) change_band = curs.fetchall() for i in change_band: curs.execute(db_change("update ban set block = ?, band = 'regex' where block = ? and band = 'O'"), [ '^' + i[0].replace('.', '\\.'), i[0] ]) curs.execute(db_change("select block from rb where band = 'O'")) change_band = curs.fetchall() for i in change_band: curs.execute(db_change("update rb set block = ?, band = 'regex' where block = ? and band = 'O'"), [ '^' + i[0].replace('.', '\\.'), i[0] ]) conn.commit() print('Update pass') def set_init(): # 초기값 설정 함수 curs.execute(db_change("select html from html_filter where kind = 'email'")) if not curs.fetchall(): for i in ['naver.com', 'gmail.com', 'daum.net', 'kakao.com']: curs.execute(db_change("insert into html_filter (html, kind) values (?, 'email')"), [i]) curs.execute(db_change("select html from html_filter where kind = 'extension'")) if not curs.fetchall(): for i in ['jpg', 'jpeg', 'png', 'gif', 'webp']: curs.execute(db_change("insert into html_filter (html, kind) values (?, 'extension')"), [i]) curs.execute(db_change('select data from other where name = "smtp_server" or name = "smtp_port" or name = "smtp_security"')) if not curs.fetchall(): for i in [['smtp_server', 'imap.google.com'], ['smtp_port', '587'], ['smtp_security', 'tls']]: curs.execute(db_change("insert into other (name, data) values (?, ?)"), [i[0], i[1]]) def pw_encode(data, data2 = '', type_d = ''): if type_d == '': curs.execute(db_change('select data from other where name = "encode"')) set_data = curs.fetchall() type_d = set_data[0][0] if type_d == 'sha256': return hashlib.sha256(bytes(data, 'utf-8')).hexdigest() else: if sys.version_info < (3, 6): return sha3.sha3_256(bytes(data, 'utf-8')).hexdigest() else: return hashlib.sha3_256(bytes(data, 'utf-8')).hexdigest() def pw_check(data, data2, type_d = 'no', id_d = ''): curs.execute(db_change('select data from other where name = "encode"')) db_data = curs.fetchall() if type_d != 'no': if type_d == '': set_data = 'sha3' else: set_data = type_d else: set_data = db_data[0][0] if pw_encode(data = data, type_d = set_data) == data2: re_data = 1 else: re_data = 0 if db_data[0][0] != set_data and re_data == 1 and id_d != '': curs.execute(db_change("update user set pw = ?, encode = ? where id = ?"), [pw_encode(data), db_data[0][0], id_d]) return re_data def captcha_get(): data = '' if ip_or_user() != 0: curs.execute(db_change('select data from other where name = "recaptcha"')) recaptcha = curs.fetchall() if recaptcha and recaptcha[0][0] != '': curs.execute(db_change('select data from other where name = "sec_re"')) sec_re = curs.fetchall() if sec_re and sec_re[0][0] != '': curs.execute(db_change('select data from other where name = "recaptcha_ver"')) rec_ver = curs.fetchall() if not rec_ver or rec_ver[0][0] == '': data += '' + \ '' + \ '
' + \ '
' + \ '' else: data += '' + \ '' + \ '' + \ '' + \ '' return data def captcha_post(re_data, num = 1): if num == 1: curs.execute(db_change('select data from other where name = "sec_re"')) sec_re = curs.fetchall() if sec_re and sec_re[0][0] != '' and ip_or_user() != 0 and captcha_get() != '': try: data = urllib.request.urlopen('https://www.google.com/recaptcha/api/siteverify?secret=' + sec_re[0][0] + '&response=' + re_data) except: data = None if data and data.getcode() == 200: json_data = json.loads(data.read().decode(data.headers.get_content_charset())) if json_data['success'] == True: return 0 else: return 1 else: return 0 else: return 0 else: pass def load_lang(data, num = 2, safe = 0): if num == 1: curs.execute(db_change("select data from other where name = 'language'")) rep_data = curs.fetchall() json_data = open(os.path.join('language', rep_data[0][0] + '.json'), encoding='utf8').read() lang = json.loads(json_data) if data in lang: if safe == 1: return lang[data] else: return html.escape(lang[data]) else: return html.escape(data + ' (M)') else: curs.execute(db_change('select data from user_set where name = "lang" and id = ?'), [ip_check()]) rep_data = curs.fetchall() if rep_data: try: json_data = open(os.path.join('language', rep_data[0][0] + '.json'), encoding='utf8').read() lang = json.loads(json_data) except: return load_lang(data, 1, safe) if data in lang: if safe == 1: return lang[data] else: return html.escape(lang[data]) else: return load_lang(data, 1, safe) else: return load_lang(data, 1, safe) def load_oauth(provider): oauth_supported = ["discord", "facebook", "naver", "kakao"] if(provider == '_README'): return { "support" : oauth_supported } else: try: oauth = json.loads(open(app_var['path_oauth_setting'], encoding='utf8').read()) except: return_json_data = '{ "publish_url" : "", ' for i in range(len(oauth_supported)): return_json_data += '"' + oauth_supported[i] + '" : { ' for j in range(2): if j == 0: load_target = 'id' elif j == 1: load_target = 'secret' return_json_data += '"client_' + load_target + '" : ""' + (',' if j == 0 else '') return_json_data += ' }' try: _ = oauth_supported[i + 1] return_json_data += ', ' except: return_json_data += ' }' with open(app_var['path_oauth_setting'], 'w', encoding='utf-8') as f: f.write(return_json_data) oauth = json.loads(open(app_var['path_oauth_setting'], encoding='utf8').read()) return oauth[provider] def update_oauth(provider, target, content): oauth = json.loads(open(app_var['path_oauth_setting'], encoding='utf8').read()) oauth[provider][target] = content with open(app_var['path_oauth_setting'], 'w', encoding='utf8') as f: f.write(json.dumps(oauth, sort_keys = True, indent = 4)) return 'Done' def ip_or_user(data = ''): if data == '': data = ip_check() if re.search(r'(\.|:)', data): return 1 else: return 0 def edit_button(): insert_list = [] curs.execute(db_change("select html, plus from html_filter where kind = 'edit_top'")) db_data = curs.fetchall() for get_data in db_data: insert_list += [[get_data[1], get_data[0]]] data = '' for insert_data in insert_list: data += '(' + insert_data[1] + ') ' if admin_check() == 1: data += (' ' if data != '' else '') + '(' + load_lang('add') + ')' return data + '
' def ip_warring(): if ip_or_user() != 0: curs.execute(db_change('select data from other where name = "no_login_warring"')) data = curs.fetchall() if data and data[0][0] != '': text_data = '' + data[0][0] + '
' else: text_data = '' + load_lang('no_login_warring') + '
' else: text_data = '' return text_data def skin_check(set_n = 0): skin = 'marisa' curs.execute(db_change('select data from other where name = "skin"')) skin_exist = curs.fetchall() if skin_exist and skin_exist[0][0] != '': if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1: skin = skin_exist[0][0] curs.execute(db_change('select data from user_set where name = "skin" and id = ?'), [ip_check()]) skin_exist = curs.fetchall() if skin_exist and skin_exist[0][0] != '': if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1: skin = skin_exist[0][0] if set_n == 0: return './views/' + skin + '/index.html' else: return skin def next_fix(link, num, page, end = 50): list_data = '' if num == 1: if len(page) == end: list_data += '
(' + load_lang('next') + ')' elif len(page) != end: list_data += '
(' + load_lang('previous') + ')' else: list_data += '
(' + load_lang('previous') + ') (' + load_lang('next') + ')' return list_data def other2(data): for _ in range(0, 3 - len(data)): data += [''] req_list = '' main_css_ver = 38 if not 'main_css_load' in flask.session or not 'main_css_ver' in flask.session or flask.session['main_css_ver'] != main_css_ver: for i_data in os.listdir(os.path.join("views", "main_css", "css")): req_list += '' for i_data in os.listdir(os.path.join("views", "main_css", "js")): req_list += '' flask.session['main_css_load'] = req_list flask.session['main_css_ver'] = main_css_ver else: req_list = flask.session['main_css_load'] data = data[0:2] + ['', ''' ''' + req_list + ''] + data[2:] return data def cut_100(data): if re.search(r'^\/w\/', flask.request.path): data = re.sub(r'' else: end = load_lang('authority_error') return easy_minify(flask.render_template(skin_check(), imp = [load_lang('error'), wiki_set(1), custom(), other2([0, 0])], data = '

' + load_lang('error') + '

' + end, menu = 0 )) else: num = int(number_check(data.replace('/error/', ''))) if num == 1: data = load_lang('no_login_error') elif num == 2: data = load_lang('no_exist_user_error') elif num == 3: data = load_lang('authority_error') elif num == 4: data = load_lang('no_admin_block_error') elif num == 5: data = load_lang('skin_error') elif num == 6: data = load_lang('same_id_exist_error') elif num == 7: data = load_lang('long_id_error') elif num == 8: data = load_lang('id_char_error') + ' (' + load_lang('id_filter_list') + ')' elif num == 9: data = load_lang('file_exist_error') elif num == 10: data = load_lang('password_error') elif num == 11: data = load_lang('topic_long_error') elif num == 12: data = load_lang('email_error') elif num == 13: data = load_lang('recaptcha_error') elif num == 14: data = load_lang('file_extension_error') + ' (' + load_lang('extension_filter_list') + ')' elif num == 15: data = load_lang('edit_record_error') elif num == 16: data = load_lang('same_file_error') elif num == 17: data = load_lang('file_capacity_error') + wiki_set(3) elif num == 19: data = load_lang('decument_exist_error') elif num == 20: data = load_lang('password_diffrent_error') elif num == 21: data = load_lang('edit_filter_error') elif num == 22: data = load_lang('file_name_error') elif num == 23: data = load_lang('regex_error') elif num == 24: curs.execute(db_change("select data from other where name = 'slow_edit'")) slow_data = curs.fetchall() data = load_lang('fast_edit_error') + slow_data[0][0] elif num == 25: data = load_lang('too_many_dec_error') elif num == 26: data = load_lang('application_not_found') elif num == 27: data = load_lang("invalid_password_error") elif num == 28: data = load_lang('watchlist_overflow_error') elif num == 29: data = load_lang('copyright_disagreed') else: data = '???' if num == 5: get_url = flask.request.path return easy_minify(flask.render_template(skin_check(), imp = [(load_lang('skin_set') if get_url != '/main_skin_set' else load_lang('main_skin_set')), wiki_set(1), custom(), other2([0, 0])], data = '' + \ '
' + \ '

' + load_lang('error') + '

' + \ '
    ' + \ '
  • ' + data + '
  • ' + \ '
' + \ '
' + \ ('' if get_url == '/main_skin_set' else ''), menu = ([['main_skin_set', load_lang('main_skin_set')]] if get_url != '/main_skin_set' else [['skin_set', load_lang('skin_set')]]) )) else: return easy_minify(flask.render_template(skin_check(), imp = [load_lang('error'), wiki_set(1), custom(), other2([0, 0])], data = '

' + load_lang('error') + '

', menu = 0 )), 401