# 모듈 불러오기
from flask import Flask, request, send_from_directory
from flask_compress import Compress
from flask_reggie import Reggie
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
import platform
import bcrypt
import difflib
import shutil
import threading
import logging
import random
import sys
# 버전 표기
r_ver = 'v3.0.3-Beta-03'
print('Version : ' + r_ver)
# 나머지 불러오기
from func import *
from set_mark.tool import savemark
# set.json 설정 확인
try:
json_data = open('set.json').read()
set_data = json.loads(json_data)
except:
while 1:
print('DB Name : ', end = '')
new_json = str(input())
if new_json != '':
with open("set.json", "w") as f:
f.write('{ "db" : "' + new_json + '" }')
json_data = open('set.json').read()
set_data = json.loads(json_data)
break
else:
print('Insert Values')
pass
# 디비 연결
conn = sqlite3.connect(set_data['db'] + '.db', check_same_thread = False)
curs = conn.cursor()
# 기타 설정 변경
logging.basicConfig(level = logging.ERROR)
app = Flask(__name__, template_folder = './')
Reggie(app)
compress = Compress()
compress.init_app(app)
# 템플릿 설정
def md5_replace(data):
return hashlib.md5(data.encode()).hexdigest()
app.jinja_env.filters['md5_replace'] = md5_replace
# 셋업 부분
curs.execute("create table if not exists data(title text, data text)")
curs.execute("create table if not exists history(id text, title text, data text, date text, ip text, send text, leng text, hide text)")
curs.execute("create table if not exists rd(title text, sub text, date text)")
curs.execute("create table if not exists user(id text, pw text, acl text, date text, email text, skin text)")
curs.execute("create table if not exists ban(block text, end text, why text, band text, login text)")
curs.execute("create table if not exists topic(id text, title text, sub text, data text, date text, ip text, block text, top text)")
curs.execute("create table if not exists stop(title text, sub text, close text)")
curs.execute("create table if not exists rb(block text, end text, today text, blocker text, why text, band text)")
curs.execute("create table if not exists back(title text, link text, type text)")
curs.execute("create table if not exists agreedis(title text, sub text)")
curs.execute("create table if not exists custom(user text, css text)")
curs.execute("create table if not exists other(name text, data text)")
curs.execute("create table if not exists alist(name text, acl text)")
curs.execute("create table if not exists re_admin(who text, what text, time text)")
curs.execute("create table if not exists alarm(name text, data text, date text)")
curs.execute("create table if not exists ua_d(name text, ip text, ua text, today text, sub text)")
curs.execute("create table if not exists filter(name text, regex text, sub text)")
curs.execute("create table if not exists scan(user text, title text)")
curs.execute("create table if not exists acl(title text, dec text, dis text, why text)")
curs.execute("create table if not exists inter(title text, link text)")
# owner 존재 확인
curs.execute("select name from alist where acl = 'owner'")
if not curs.fetchall():
curs.execute("delete from alist where name = 'owner'")
curs.execute("insert into alist (name, acl) values ('owner', 'owner')")
# 포트 점검
curs.execute("select data from other where name = 'port'")
rep_data = curs.fetchall()
if not rep_data:
while 1:
print('Port : ', end = '')
rep_port = int(input())
if rep_port:
curs.execute("insert into other (name, data) values ('port', ?)", [rep_port])
break
else:
pass
else:
rep_port = rep_data[0][0]
print('Port : ' + str(rep_port))
# robots.txt 점검
try:
if not os.path.exists('robots.txt'):
curs.execute("select data from other where name = 'robot'")
robot_test = curs.fetchall()
if robot_test:
fw_test = open('./robots.txt', 'w')
fw_test.write(re.sub('\r\n', '\n', robot_test[0][0]))
fw_test.close()
else:
fw_test = open('./robots.txt', 'w')
fw_test.write('User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/')
fw_test.close()
curs.execute("insert into other (name, data) values ('robot', 'User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/')")
print('robots.txt create')
except:
pass
# 비밀 키 점검
curs.execute("select data from other where name = 'key'")
rep_data = curs.fetchall()
if not rep_data:
while 1:
print('Secret Key : ', end = '')
rep_key = str(input())
if rep_key:
curs.execute("insert into other (name, data) values ('key', ?)", [rep_key])
break
else:
pass
else:
rep_key = rep_data[0][0]
print('Secret Key : ' + rep_key)
# 언어 점검
curs.execute("select data from other where name = 'language'")
rep_data = curs.fetchall()
if not rep_data:
while 1:
print('Language [ko-KR] : ', end = '')
support_language = ['ko-KR']
rep_language = str(input())
if rep_language in support_language:
curs.execute("insert into other (name, data) values ('language', ?)", [rep_language])
break
else:
pass
else:
rep_language = rep_data[0][0]
print('Language : ' + str(rep_language))
json_data = open(os.path.join('language', 'ko-KR.json'), 'rt', encoding='utf-8').read()
lang_data = json.loads(json_data)
# 한번 개행
print('')
# 호환성 설정
try:
curs.execute("alter table history add hide text default ''")
curs.execute('select title, re from hidhi')
for rep in curs.fetchall():
curs.execute("update history set hide = 'O' where title = ? and id = ?", [rep[0], rep[1]])
curs.execute("drop table if exists hidhi")
print('move table hidhi')
except:
pass
try:
curs.execute("alter table user add date text default ''")
print('user table add column date')
except:
pass
try:
curs.execute("alter table rb add band text default ''")
print('rb table add column band')
except:
pass
try:
curs.execute("alter table ban add login text default ''")
print('ban table add column login')
except:
pass
try:
curs.execute("select title, acl from data where acl != ''")
for rep in curs.fetchall():
curs.execute("insert into acl (title, dec, dis, why) values (?, ?, '', '')", [rep[0], rep[1]])
curs.execute("alter table data drop acl")
print('data table delete column acl')
except:
pass
try:
curs.execute("alter table user add email text default ''")
print('user table add column email')
except:
pass
try:
curs.execute('select name, sub from filter where sub != "X" and sub != ""')
filter_name = curs.fetchall()
if filter_name:
for filter_delete in filter_name:
if filter_delete[1] != '' or filter_delete[1] != 'X':
curs.execute("update filter set sub = '' where name = ?", [filter_delete[0]])
print('filter data fix')
except:
pass
try:
curs.execute("alter table user add skin text default ''")
print('user table add column skin')
except:
pass
conn.commit()
# 이미지 폴더 생성
if not os.path.exists('image'):
os.makedirs('image')
# 스킨 폴더 생성
if not os.path.exists('views'):
os.makedirs('views')
# 백업 설정
def back_up():
try:
shutil.copyfile(set_data['db'] + '.db', 'back_' + set_data['db'] + '.db')
print('Back Up Ok')
except:
print('Back Up Error')
threading.Timer(60 * 60 * back_time, back_up).start()
try:
curs.execute('select data from other where name = "back_up"')
back_up_time = curs.fetchall()
back_time = int(back_up_time[0][0])
except:
back_time = 0
# 백업 여부 확인
if back_time != 0:
print(str(back_time) + ' Hours Back Up')
if __name__ == '__main__':
back_up()
else:
print('No Back Up')
@app.route('/del_alarm')
def del_alarm():
curs.execute("delete from alarm where name = ?", [ip_check()])
conn.commit()
return redirect('/alarm')
@app.route('/alarm')
def alarm():
if custom(conn)[2] == 0:
return redirect('/login')
data = '
'
curs.execute("select data, date from alarm where name = ? order by date desc", [ip_check()])
data_list = curs.fetchall()
if data_list:
data = '(삭제)' + data
for data_one in data_list:
data += '
' + data_one[0] + ' (' + data_one[1] + ')
'
else:
data += '
알림이 없습니다.
'
data += '
'
return html_minify(render_template(skin_check(conn),
imp = ['알림', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = data,
menu = [['user', '사용자']]
))
@app.route('/inter_wiki')
def inter_wiki():
div = ''
admin = admin_check(conn, None, None)
curs.execute('select title, link from inter')
db_data = curs.fetchall()
if db_data:
div = '
'
for data in db_data:
div += '
' + data[0] + ' : ' + data[1]
if admin == 1:
div += ' (삭제)'
div += '
'
div += '
'
if admin == 1:
div += '(추가)'
else:
if admin == 1:
div += '(추가)'
return html_minify(render_template(skin_check(conn),
imp = ['인터위키 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['other', '기타']]
))
@app.route('/del_inter/')
def del_inter(name = None):
if admin_check(conn, None, None) == 1:
curs.execute("delete from inter where title = ?", [name])
conn.commit()
return redirect('/inter_wiki')
else:
return re_error(conn, '/error/3')
@app.route('/plus_inter', methods=['POST', 'GET'])
def plus_inter():
if request.method == 'POST':
curs.execute('insert into inter (title, link) values (?, ?)', [request.form.get('title', None), request.form.get('link', None)])
conn.commit()
admin_check(conn, None, 'inter_wiki_plus')
return redirect('/inter_wiki')
else:
return html_minify(render_template(skin_check(conn),
imp = ['인터위키 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['other', '기타']]
))
@app.route('/edit_set')
@app.route('/edit_set/', methods=['POST', 'GET'])
def edit_set(num = 0):
if num != 0 and admin_check(conn, None, None) != 1:
return re_error(conn, '/ban')
if num == 0:
li_list = ['기본 설정', '문구 관련', '전역 HEAD', 'robots.txt', '구글 관련']
x = 0
li_data = ''
for li in li_list:
x += 1
li_data += '
',
menu = [['manager', lang_data['admin']]]
))
elif num == 1:
i_list = ['name', 'logo', 'frontpage', 'license', 'upload', 'skin', 'edit', 'reg', 'ip_view', 'back_up']
n_list = ['Wiki', '', 'FrontPage', 'CC 0', '2', '', 'normal', '', '', '0']
if request.method == 'POST':
i = 0
for data in i_list:
curs.execute("update other set data = ? where name = ?", [request.form.get(data, n_list[i]), data])
i += 1
conn.commit()
admin_check(conn, None, 'edit_set')
return redirect('/edit_set/1')
else:
d_list = []
x = 0
for i in i_list:
curs.execute('select data from other where name = ?', [i])
sql_d = curs.fetchall()
if sql_d:
d_list += [sql_d[0][0]]
else:
curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
d_list += [n_list[x]]
x += 1
conn.commit()
div = ''
if d_list[6] == 'login':
div += ''
div += ''
div += ''
elif d_list[6] == 'admin':
div += ''
div += ''
div += ''
else:
div += ''
div += ''
div += ''
ch_1 = ''
if d_list[7]:
ch_1 = 'checked="checked"'
ch_2 = ''
if d_list[8]:
ch_2 = 'checked="checked"'
div2 = ''
for skin_data in os.listdir(os.path.abspath('views')):
if d_list[5] == skin_data:
div2 = '' + div2
else:
div2 += ''
return html_minify(render_template(skin_check(conn),
imp = ['기본 설정', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['edit_set', '설정']]
))
elif num == 2:
if request.method == 'POST':
curs.execute("update other set data = ? where name = ?", [request.form.get('contract', None), 'contract'])
curs.execute("update other set data = ? where name = ?", [request.form.get('no_login_warring', None), 'no_login_warring'])
conn.commit()
admin_check(conn, None, 'edit_set')
return redirect('/edit_set/2')
else:
i_list = ['contract', 'no_login_warring']
n_list = ['', '']
d_list = []
x = 0
for i in i_list:
curs.execute('select data from other where name = ?', [i])
sql_d = curs.fetchall()
if sql_d:
d_list += [sql_d[0][0]]
else:
curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
d_list += [n_list[x]]
x += 1
conn.commit()
return html_minify(render_template(skin_check(conn),
imp = ['문구 관련', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['edit_set', '설정']]
))
elif num == 3:
if request.method == 'POST':
curs.execute("select name from other where name = 'head'")
if curs.fetchall():
curs.execute("update other set data = ? where name = 'head'", [request.form.get('content', None)])
else:
curs.execute("insert into other (name, data) values ('head', ?)", [request.form.get('content', None)])
conn.commit()
admin_check(conn, None, 'edit_set')
return redirect('/edit_set/3')
else:
curs.execute("select data from other where name = 'head'")
head = curs.fetchall()
if head:
data = head[0][0]
else:
data = ''
return html_minify(render_template(skin_check(conn),
imp = ['전역 HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '<style>CSS</style> <script>JS</script>',
menu = [['edit_set', '설정']]
))
elif num == 4:
if request.method == 'POST':
curs.execute("select name from other where name = 'robot'")
if curs.fetchall():
curs.execute("update other set data = ? where name = 'robot'", [request.form.get('content', None)])
else:
curs.execute("insert into other (name, data) values ('robot', ?)", [request.form.get('content', None)])
conn.commit()
fw = open('./robots.txt', 'w')
fw.write(re.sub('\r\n', '\n', request.form.get('content', None)))
fw.close()
admin_check(conn, None, 'edit_set')
return redirect('/edit_set/4')
else:
curs.execute("select data from other where name = 'robot'")
robot = curs.fetchall()
if robot:
data = robot[0][0]
else:
data = ''
f = open('./robots.txt', 'r')
lines = f.readlines()
f.close()
if not data or data == '':
data = ''.join(lines)
return html_minify(render_template(skin_check(conn),
imp = ['robots.txt', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '(보기)',
menu = [['edit_set', '설정']]
))
elif num == 5:
if request.method == 'POST':
curs.execute("update other set data = ? where name = 'recaptcha'", [request.form.get('recaptcha', None)])
curs.execute("update other set data = ? where name = 'sec_re'", [request.form.get('sec_re', None)])
conn.commit()
admin_check(conn, None, 'edit_set')
return redirect('/edit_set/5')
else:
i_list = ['recaptcha', 'sec_re']
n_list = ['', '']
d_list = []
x = 0
for i in i_list:
curs.execute('select data from other where name = ?', [i])
sql_d = curs.fetchall()
if sql_d:
d_list += [sql_d[0][0]]
else:
curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
d_list += [n_list[x]]
x += 1
conn.commit()
return html_minify(render_template(skin_check(conn),
imp = ['구글 관련', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['edit_set', '설정']]
))
else:
return redirect('/')
@app.route('/not_close_topic')
def not_close_topic():
div = '
'
curs.execute('select title, sub from rd order by date desc')
n_list = curs.fetchall()
for data in n_list:
curs.execute('select * from stop where title = ? and sub = ? and close = "O"', [data[0], data[1]])
is_close = curs.fetchall()
if not is_close:
div += '
'
curs.execute("select title, dec from acl where dec = 'admin' or dec = 'user' order by title desc")
list_data = curs.fetchall()
for data in list_data:
if not re.search('^사용자:', data[0]) and not re.search('^파일:', data[0]):
if data[1] == 'admin':
acl = lang_data['admin']
else:
acl = '가입자'
div += '
'
return html_minify(render_template(skin_check(conn),
imp = ['관리 그룹 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['manager', lang_data['admin']]]
))
@app.route('/admin_list')
def admin_list():
div = '
'
curs.execute("select id, acl, date from user where not acl = 'user' order by date desc")
for data in curs.fetchall():
name = ip_pas(conn, data[0]) + ' (' + data[1] + ')'
if data[2] != '':
name += '(가입 : ' + data[2] + ')'
div += '
' + name + '
'
div += '
'
return html_minify(render_template(skin_check(conn),
imp = [lang_data['admin'] + ' ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['other', '기타']]
))
@app.route('/hidden/')
def history_hidden(name = None):
num = int(request.args.get('num', 0))
if admin_check(conn, 6, 'history_hidden (' + name + '#' + str(num) + ')') == 1:
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
if curs.fetchall():
curs.execute("update history set hide = '' where title = ? and id = ?", [name, str(num)])
else:
curs.execute("update history set hide = 'O' where title = ? and id = ?", [name, str(num)])
conn.commit()
return redirect('/history/' + url_pas(name))
@app.route('/user_log')
def user_log():
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
list_data = '
'
admin_one = admin_check(conn, 1, None)
curs.execute("select id, date from user order by date desc limit ?, '50'", [str(sql_num)])
user_list = curs.fetchall()
for data in user_list:
if admin_one == 1:
curs.execute("select block from ban where block = ?", [data[0]])
if curs.fetchall():
ban_button = ' (' + lang_data['release'] + ')'
else:
ban_button = ' (' + lang_data['ban'] + ')'
else:
ban_button = ''
list_data += '
'
if num == 1:
curs.execute("select count(id) from user")
user_count = curs.fetchall()
if user_count:
count = user_count[0][0]
else:
count = 0
list_data += '
이 위키에는 ' + str(count) + '명의 사람이 있습니다.
'
list_data += next_fix('/user_log?num=', num, user_list)
return html_minify(render_template(skin_check(conn),
imp = ['최근 가입', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = list_data,
menu = 0
))
@app.route('/admin_log')
def admin_log():
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
list_data = '
'
curs.execute("select who, what, time from re_admin order by time desc limit ?, '50'", [str(sql_num)])
get_list = curs.fetchall()
for data in get_list:
list_data += '
'
back = ''
curs.execute("select distinct name from alist order by name asc")
for data in curs.fetchall():
if back != data[0]:
back = data[0]
list_data += '
(생성)'
return html_minify(render_template(skin_check(conn),
imp = ['관리 그룹 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = list_data,
menu = [['other', '기타']]
))
@app.route('/indexing')
def indexing():
if admin_check(conn, None, 'indexing') != 1:
return re_error(conn, '/error/3')
print('')
curs.execute("select name from sqlite_master where type = 'index'")
data = curs.fetchall()
if data:
for delete_index in data:
print('Delete : ' + delete_index[0])
sql = 'drop index if exists ' + delete_index[0]
try:
curs.execute(sql)
except:
pass
else:
curs.execute("select name from sqlite_master where type in ('table', 'view') and name not like 'sqlite_%' union all select name from sqlite_temp_master where type in ('table', 'view') order by 1;")
for table in curs.fetchall():
curs.execute('select sql from sqlite_master where name = ?', [table[0]])
cul = curs.fetchall()
r_cul = re.findall('(?:([^ (]*) text)', str(cul[0]))
for n_cul in r_cul:
print('Create : index_' + table[0] + '_' + n_cul)
sql = 'create index index_' + table[0] + '_' + n_cul + ' on ' + table[0] + '(' + n_cul + ')'
try:
curs.execute(sql)
except:
pass
conn.commit()
print('')
return redirect('/')
@app.route('/re_start')
def re_start():
if admin_check(conn, None, 're_start') != 1:
return re_error(conn, '/error/3')
print('')
print('Re Start')
print('')
os.execl(sys.executable, sys.executable, *sys.argv)
@app.route('/update')
def update():
if admin_check(conn, None, 'update') != 1:
return re_error(conn, '/error/3')
if platform.system() == 'Linux':
print('')
print('Update')
ok = os.system('git pull')
if ok == 0:
print('Re Start')
print('')
os.execl(sys.executable, sys.executable, *sys.argv)
return html_minify(render_template(skin_check(conn),
imp = ['업데이트', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '수동 업데이트를 권장 합니다. (깃허브)',
menu = [['manager/1', lang_data['admin']]]
))
@app.route('/xref/')
def xref(name = None):
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
div = '
'
curs.execute("select link, type from back where title = ? and not type = 'cat' and not type = 'no' order by link asc limit ?, '50'", [name, str(sql_num)])
data_list = curs.fetchall()
for data in data_list:
div += '
' + data[0] + ''
if data[1]:
if data[1] == 'include':
side = '포함'
elif data[1] == 'file':
side = '파일'
else:
side = '넘겨주기'
div += ' (' + side + ')'
div += '
' + next_fix('/xref/' + url_pas(name) + '?num=', num, data_list)
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (역링크)', 0])],
data = div,
menu = [['w/' + url_pas(name), lang_data['document']]]
))
@app.route('/please')
def please():
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
div = '
'
var = ''
curs.execute("select distinct title from back where type = 'no' order by title asc limit ?, '50'", [str(sql_num)])
data_list = curs.fetchall()
for data in data_list:
if var != data[0]:
div += '
' + next_fix('/please?num=', num, data_list)
return html_minify(render_template(skin_check(conn),
imp = ['필요한 ' + lang_data['document'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['other', '기타']]
))
@app.route('/recent_discuss')
@app.route('/recent_discuss/')
def recent_discuss(tools = 'normal'):
if tools == 'normal' or tools == 'close':
div = ''
if tools == 'normal':
div += '(닫힘)'
m_sub = 0
else:
div += '(열림)'
m_sub = ' (닫힘)'
div += '
토론명
시간
'
else:
return redirect('/')
curs.execute("select title, sub, date from rd order by date desc limit 50")
for data in curs.fetchall():
title = html.escape(data[0])
sub = html.escape(data[1])
close = 0
if tools == 'normal':
curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [data[0], data[1]])
if curs.fetchall():
close = 1
else:
curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [data[0], data[1]])
if not curs.fetchall():
close = 1
if close == 0:
div += '
'
return html_minify(render_template(skin_check(conn),
imp = ['최근 토론', wiki_set(conn, 1), custom(conn), other2([m_sub, 0])],
data = div,
menu = 0
))
@app.route('/block_log')
@app.route('/block_log/')
@app.route('//')
def block_log(name = None, tool = None, tool2 = None):
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
div = '
차단자
' + lang_data['admin'] + '
기간
'
data_list = ''
if not name:
if not tool2:
div = '(차단자)(' + lang_data['admin'] + ')(아이피)(가입자)(무기한)(기간)(' + lang_data['release'] + ')(현재)(편집 필터)' + div
sub = 0
menu = 0
curs.execute("select why, block, blocker, end, today from rb order by today desc limit ?, '50'", [str(sql_num)])
else:
menu = [['block_log', '일반']]
if tool2 == 'ip':
sub = ' (아이피)'
curs.execute("select why, block, blocker, end, today from rb where (block like ? or block like ?) order by today desc limit ?, '50'", ['%.%', '%:%', str(sql_num)])
elif tool2 == 'user':
sub = ' (가입자)'
curs.execute("select why, block, blocker, end, today from rb where not (block like ? or block like ?) order by today desc limit ?, '50'", ['%.%', '%:%', str(sql_num)])
elif tool2 == 'never_end':
sub = '(무기한)'
curs.execute("select why, block, blocker, end, today from rb where not end like ? and not end like ? order by today desc limit ?, '50'", ['%:%', '%' + lang_data['release'] + '%', str(sql_num)])
elif tool2 == 'end':
sub = '(' + lang_data['release'] + ')'
curs.execute("select why, block, blocker, end, today from rb where end = ? order by today desc limit ?, '50'", [lang_data['release'], str(sql_num)])
elif tool2 == 'now':
sub = '(현재)'
data_list = []
curs.execute("select block from ban limit ?, '50'", [str(sql_num)])
for in_data in curs.fetchall():
curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit 1", [in_data[0]])
data_list = [curs.fetchall()[0]] + data_list
elif tool2 == 'edit_filter':
sub = '(편집 필터)'
curs.execute("select why, block, blocker, end, today from rb where blocker = ? order by today desc limit ?, '50'", ['도구:편집 필터', str(sql_num)])
else:
sub = '(기간)'
curs.execute("select why, block, blocker, end, today from rb where end like ? order by today desc limit ?, '50'", ['%\-%', str(sql_num)])
else:
menu = [['block_log', '일반']]
if tool == 'block_user':
sub = ' (차단자)'
curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit ?, '50'", [name, str(sql_num)])
else:
sub = ' (' + lang_data['admin'] + ')'
curs.execute("select why, block, blocker, end, today from rb where blocker = ? order by today desc limit ?, '50'", [name, str(sql_num)])
if data_list == '':
data_list = curs.fetchall()
for data in data_list:
why = html.escape(data[0])
if why == '':
why = ' '
band = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data[1])
if band:
ip = data[1] + ' (대역)'
else:
ip = ip_pas(conn, data[1])
if data[3] != '':
end = data[3]
else:
end = '무기한'
div += '
' + ip + '
' + ip_pas(conn, data[2]) + '
시작 : ' + data[4] + ' 끝 : ' + end + '
'
div += '
' + why + '
'
div += '
'
if not name:
if not tool2:
div += next_fix('/block_log?num=', num, data_list)
else:
div += next_fix('/block_log/' + url_pas(tool2) + '?num=', num, data_list)
else:
div += next_fix('/' + url_pas(tool) + '/' + url_pas(name) + '?num=', num, data_list)
return html_minify(render_template(skin_check(conn),
imp = ['최근 ' + lang_data['ban'] + ' ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([sub, 0])],
data = div,
menu = menu
))
@app.route('/search', methods=['POST'])
def search():
return redirect('/search/' + url_pas(request.form.get('search', None)))
@app.route('/goto', methods=['POST'])
def goto():
curs.execute("select title from data where title = ?", [request.form.get('search', None)])
data = curs.fetchall()
if data:
return redirect('/w/' + url_pas(request.form.get('search', None)))
else:
return redirect('/search/' + url_pas(request.form.get('search', None)))
@app.route('/search/')
def deep_search(name = None):
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
div = '
'
div_plus = ''
no = 0
start = 2
test = ''
curs.execute("select title from data where title = ?", [name])
if curs.fetchall():
div = '
'
curs.execute("select distinct title, case when title like ? then '제목' else '내용' end from data where title like ? or data like ? order by case when title like ? then 1 else 2 end limit ?, '50'", ['%' + name + '%', '%' + name + '%', '%' + name + '%', '%' + name + '%', str(sql_num)])
all_list = curs.fetchall()
if all_list:
test = all_list[0][1]
for data in all_list:
if data[1] != test:
div_plus += '
'
div += next_fix('/search/' + url_pas(name) + '?num=', num, all_list)
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (검색)', 0])],
data = div,
menu = 0
))
@app.route('/raw/')
@app.route('/topic//sub//raw/')
def raw_view(name = None, sub_title = None, num = None):
v_name = name
sub = ' (원본)'
if not num:
num = request.args.get('num', None)
if num:
num = int(num)
if not sub_title and num:
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
if curs.fetchall() and admin_check(conn, 6, None) != 1:
return re_error(conn, '/error/3')
curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
sub += ' (' + str(num) + lang_data['version'] + ')'
menu = [['history/' + url_pas(name), lang_data['history']]]
elif sub_title:
curs.execute("select data from topic where id = ? and title = ? and sub = ? and block = ''", [str(num), name, sub_title])
v_name = '토론 원본'
sub = ' (' + str(num) + '번)'
menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub_title) + '#' + str(num), '토론'], ['topic/' + url_pas(name) + '/sub/' + url_pas(sub_title) + '/admin/' + str(num), '도구']]
else:
curs.execute("select data from data where title = ?", [name])
menu = [['w/' + url_pas(name), lang_data['document']]]
data = curs.fetchall()
if data:
p_data = html.escape(data[0][0])
p_data = ''
return html_minify(render_template(skin_check(conn),
imp = [v_name, wiki_set(conn, 1), custom(conn), other2([sub, 0])],
data = p_data,
menu = menu
))
else:
return redirect('/w/' + url_pas(name))
@app.route('/revert/', methods=['POST', 'GET'])
def revert(name = None):
num = int(request.args.get('num', 0))
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
if curs.fetchall() and admin_check(conn, 6, None) != 1:
return re_error(conn, '/error/3')
if acl_check(conn, name) == 1:
return re_error(conn, '/ban')
if request.method == 'POST':
if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
return re_error(conn, '/error/13')
else:
captcha_post('', conn, 0)
curs.execute("delete from back where link = ?", [name])
conn.commit()
curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
data = curs.fetchall()
if data:
curs.execute("select data from data where title = ?", [name])
data_old = curs.fetchall()
if data_old:
leng = leng_check(len(data_old[0][0]), len(data[0][0]))
curs.execute("update data set data = ? where title = ?", [data[0][0], name])
else:
leng = '+' + str(len(data[0][0]))
curs.execute("insert into data (title, data) values (?, ?)", [name, data[0][0]])
history_plus(conn, name, data[0][0], get_time(), ip_check(), request.form.get('send', None) + ' (' + str(num) + lang_data['version'] + ')', leng)
namumark(conn, name, data[0][0], 1)
conn.commit()
return redirect('/w/' + url_pas(name))
else:
curs.execute("select title from history where title = ? and id = ?", [name, str(num)])
if not curs.fetchall():
return redirect('/w/' + url_pas(name))
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + lang_data['revert'] + ')', 0])],
data = '',
menu = [['history/' + url_pas(name), lang_data['history']], ['recent_changes', '최근 변경']]
))
@app.route('/big_delete', methods=['POST', 'GET'])
def big_delete():
if admin_check(conn, 2, 'big_delete') != 1:
return re_error(conn, '/error/3')
if request.method == 'POST':
today = get_time()
ip = ip_check()
data = request.form.get('content', None) + '\r\n'
match = re.findall('(.*)\r\n', data)
for list_one in match:
curs.execute("select data from data where title = ?", [list_one])
data_old = curs.fetchall()
if data_old:
curs.execute("delete from back where title = ?", [list_one])
curs.execute("delete from data where title = ?", [list_one])
leng = '-' + str(len(data_old[0][0]))
history_plus(conn, list_one, '', today, ip, request.form.get('send', None) + ' (대량 삭제)', leng)
data = re.sub('(.*)\r\n', '', data, 1)
conn.commit()
return redirect('/')
else:
return html_minify(render_template(skin_check(conn),
imp = ['많은 문서 삭제', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '문서명 A 문서명 B 문서명 C이런 식으로 적으세요.',
menu = [['manager', lang_data['admin']]]
))
@app.route('/edit_filter')
def edit_filter():
div = '
'
curs.execute("select name from filter")
data = curs.fetchall()
for data_list in data:
div += '
'
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + lang_data['move'] + ' ' + lang_data['history'] + ')', 0])],
data = data,
menu = [['history/' + url_pas(name), lang_data['history']]]
))
@app.route('/move/', methods=['POST', 'GET'])
def move(name = None):
if acl_check(conn, name) == 1:
return re_error(conn, '/ban')
if request.method == 'POST':
if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
return re_error(conn, '/error/13')
else:
captcha_post('', conn, 0)
curs.execute("select title from history where title = ?", [request.form.get('title', None)])
if curs.fetchall():
return re_error(conn, '/error/19')
curs.execute("select data from data where title = ?", [name])
data = curs.fetchall()
if data:
curs.execute("update data set title = ? where title = ?", [request.form.get('title', None), name])
curs.execute("update back set link = ? where link = ?", [request.form.get('title', None), name])
data_in = data[0][0]
else:
data_in = ''
history_plus(conn, name, data_in, get_time(), ip_check(), request.form.get('send', None) + ' (' + name + ' - ' + request.form.get('title', None) + ' ' + lang_data['move'] + ')', '0')
curs.execute("select title, link from back where title = ? and not type = 'cat' and not type = 'no'", [name])
for data in curs.fetchall():
curs.execute("insert into back (title, link, type) values (?, ?, 'no')", [data[0], data[1]])
curs.execute("update history set title = ? where title = ?", [request.form.get('title', None), name])
conn.commit()
return redirect('/w/' + url_pas(request.form.get('title', None)))
else:
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + lang_data['move'] + ')', 0])],
data = '',
menu = [['w/' + url_pas(name), lang_data['document']]]
))
@app.route('/other')
def other():
return html_minify(render_template(skin_check(conn),
imp = ['기타 메뉴', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '
'
all_list += 1
if page == 1:
count_end = []
curs.execute("select count(title) from data")
count = curs.fetchall()
if count:
count_end += [count[0][0]]
else:
count_end += [0]
sql_list = ['틀:', '분류:', '사용자:', '파일:']
for sql in sql_list:
curs.execute("select count(title) from data where title like ?", [sql + '%'])
count = curs.fetchall()
if count:
count_end += [count[0][0]]
else:
count_end += [0]
count_end += [count_end[0] - count_end[1] - count_end[2] - count_end[3] - count_end[4]]
data += '
이 위키에는 총 ' + str(count_end[0]) + '개의 문서가 있습니다.
'
data += '
틀 문서는 총 ' + str(count_end[1]) + '개의 문서가 있습니다.
'
data += '
분류 문서는 총 ' + str(count_end[2]) + '개의 문서가 있습니다.
'
data += '
사용자 문서는 총 ' + str(count_end[3]) + '개의 문서가 있습니다.
'
data += '
파일 문서는 총 ' + str(count_end[4]) + '개의 문서가 있습니다.
'
data += '
나머지 문서는 총 ' + str(count_end[5]) + '개의 문서가 있습니다.
'
data += '
' + next_fix('/title_index?num=' + str(num) + '&page=', page, title_list, num)
sub = ' (' + str(num) + '개)'
return html_minify(render_template(skin_check(conn),
imp = [lang_data['all'] + ' ' + lang_data['document'], wiki_set(conn, 1), custom(conn), other2([sub, 0])],
data = data,
menu = [['other', '기타']]
))
@app.route('/topic//sub//b/')
def topic_block(name = None, sub = None, num = None):
if admin_check(conn, 3, 'blind (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
return re_error(conn, '/error/3')
curs.execute("select block from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
block = curs.fetchall()
if block:
if block[0][0] == 'O':
curs.execute("update topic set block = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
else:
curs.execute("update topic set block = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
rd_plus(conn, name, sub, get_time())
conn.commit()
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
@app.route('/topic//sub//notice/')
def topic_top(name = None, sub = None, num = None):
if admin_check(conn, 3, 'notice (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
return re_error(conn, '/error/3')
curs.execute("select title from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
if curs.fetchall():
curs.execute("select top from topic where id = ? and title = ? and sub = ?", [str(num), name, sub])
top_data = curs.fetchall()
if top_data:
if top_data[0][0] == 'O':
curs.execute("update topic set top = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
else:
curs.execute("update topic set top = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
rd_plus(conn, name, sub, get_time())
conn.commit()
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
@app.route('/topic//sub//tool/')
def topic_stop(name = None, sub = None, tool = None):
if tool == 'close':
set_list = ['O', '', '토론 닫기', '토론 열림']
elif tool == 'stop':
set_list = ['', 'O', '토론 정지', '토론 재개']
elif tool == 'agree':
pass
else:
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
if admin_check(conn, 3, 'topic ' + tool + ' (' + name + ' - ' + sub + ')') != 1:
return re_error(conn, '/error/3')
ip = ip_check()
time = get_time()
curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
topic_check = curs.fetchall()
if topic_check:
if tool == 'agree':
curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub])
if curs.fetchall():
curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, '합의 결렬', ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
curs.execute("delete from agreedis where title = ? and sub = ?", [name, sub])
else:
curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, '합의 완료', ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
curs.execute("insert into agreedis (title, sub) values (?, ?)", [name, sub])
else:
curs.execute("select title from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[0]])
if curs.fetchall():
curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, set_list[3], time, ip])
curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[0]])
else:
curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, set_list[2], time, ip])
curs.execute("insert into stop (title, sub, close) values (?, ?, ?)", [name, sub, set_list[0]])
curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[1]])
rd_plus(conn, name, sub, time)
conn.commit()
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
@app.route('/topic//sub//admin/')
def topic_admin(name = None, sub = None, num = None):
curs.execute("select block, ip, date from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
data = curs.fetchall()
if not data:
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
ban = ''
if admin_check(conn, 3, None) == 1:
ban += '
' + ban
return html_minify(render_template(skin_check(conn),
imp = ['토론 도구', wiki_set(conn, 1), custom(conn), other2([' (' + str(num) + '번)', 0])],
data = ban,
menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num), '토론']]
))
@app.route('/topic//sub/', methods=['POST', 'GET'])
def topic(name = None, sub = None):
ban = topic_check(conn, name, sub)
admin = admin_check(conn, 3, None)
if request.method == 'POST':
if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
return re_error(conn, '/error/13')
else:
captcha_post('', conn, 0)
ip = ip_check()
today = get_time()
if ban == 1:
return re_error(conn, '/ban')
curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
old_num = curs.fetchall()
if old_num:
num = int(old_num[0][0]) + 1
else:
num = 1
match = re.search('^사용자:([^/]+)', name)
if match:
curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [match.groups()[0], ip + '님이 사용자 토론을 시작했습니다.', today])
data = re.sub("\[\[(분류:(?:(?:(?!\]\]).)*))\]\]", "[br]", request.form.get('content', None))
for rd_data in re.findall("(?:#([0-9]+))", data):
curs.execute("select ip from topic where title = ? and sub = ? and id = ?", [name, sub, rd_data])
ip_data = curs.fetchall()
if ip_data and not re.search('(\.|:)', ip_data[0][0]):
curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [ip_data[0][0], ip + '님이 토론에서 언급 했습니다.', today])
data = re.sub("(?P#(?:[0-9]+))", '[[\g]]', data)
data = savemark(data)
rd_plus(conn, name, sub, today)
curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '')", [str(num), name, sub, data, today, ip])
conn.commit()
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
else:
curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, sub])
close_data = curs.fetchall()
curs.execute("select title from stop where title = ? and sub = ? and close = ''", [name, sub])
stop_data = curs.fetchall()
curs.execute("select id from topic where title = ? and sub = ? limit 1", [name, sub])
topic_exist = curs.fetchall()
display = ''
all_data = ''
data = ''
number = 1
if admin == 1 and topic_exist:
if close_data:
all_data += '(열기) '
else:
all_data += '(닫기) '
if stop_data:
all_data += '(재개) '
else:
all_data += '(정지) '
curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub])
if curs.fetchall():
all_data += '(' + lang_data['release'] + ')'
else:
all_data += '(합의)'
all_data += ''
if (close_data or stop_data) and admin != 1:
display = 'display: none;'
curs.execute("select data, id, date, ip, block, top from topic where title = ? and sub = ? order by id + 0 asc", [name, sub])
topic = curs.fetchall()
curs.execute("select data, id, date, ip from topic where title = ? and sub = ? and top = 'O' order by id + 0 asc", [name, sub])
for topic_data in curs.fetchall():
who_plus = ''
curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['notice (' + name + ' - ' + sub + '#' + topic_data[1] + ')'])
topic_data_top = curs.fetchall()
if topic_data_top:
who_plus += ' @' + topic_data_top[0][0] + ' '
all_data += '
'
for topic_data in topic:
if number == 1:
start = topic_data[3]
if topic_data[4] == 'O':
blind_data = 'style="background: gainsboro;"'
if admin != 1:
curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['blind (' + name + ' - ' + sub + '#' + str(number) + ')'])
who_blind = curs.fetchall()
if who_blind:
user_write = '[[사용자:' + who_blind[0][0] + ']] ' + lang_data['hide']
else:
user_write = lang_data['hide']
else:
blind_data = ''
user_write = namumark(conn, '', topic_data[0], 0)
ip = ip_pas(conn, topic_data[3])
curs.execute('select acl from user where id = ?', [topic_data[3]])
user_acl = curs.fetchall()
if user_acl and user_acl[0][0] != 'user':
ip += ' ★'
if admin == 1 or blind_data == '':
ip += ' (도구)'
curs.execute("select end from ban where block = ?", [topic_data[3]])
if curs.fetchall():
ip += ' †'
if topic_data[5] == '1':
color = '_blue'
elif topic_data[3] == start:
color = '_green'
else:
color = ''
if user_write == '':
user_write = ' '
all_data += '
'
number += 1
if ban != 1 or admin == 1:
data += '(새로고침)'
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (토론)', 0])],
data = '
' + sub + '
' + all_data + data,
menu = [['topic/' + url_pas(name), lang_data['list']]]
))
@app.route('/topic/', methods=['POST', 'GET'])
@app.route('/topic//', methods=['GET'])
def close_topic_list(name = None, tool = None):
div = ''
list_d = 0
if request.method == 'POST':
t_num = ''
while 1:
curs.execute("select title from topic where title = ? and sub = ? limit 1", [name, request.form.get('topic', None) + t_num])
if curs.fetchall():
if t_num == '':
t_num = ' 2'
else:
t_num = ' ' + str(int(t_num.replace(' ', '')) + 1)
else:
break
return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(request.form.get('topic', None) + t_num))
else:
plus = ''
menu = [['topic/' + url_pas(name), lang_data['list']]]
if tool == 'close':
curs.execute("select sub from stop where title = ? and close = 'O' order by sub asc", [name])
sub = '닫힘'
elif tool == 'agree':
curs.execute("select sub from agreedis where title = ? order by sub asc", [name])
sub = '합의'
else:
curs.execute("select sub from rd where title = ? order by date desc", [name])
sub = '토론 ' + lang_data['list']
menu = [['w/' + url_pas(name), lang_data['document']]]
plus = '(닫힘)(합의)'
for data in curs.fetchall():
curs.execute("select data, date, ip, block from topic where title = ? and sub = ? and id = '1'", [name, data[0]])
if curs.fetchall():
it_p = 0
if sub == '토론 ' + lang_data['list']:
curs.execute("select title from stop where title = ? and sub = ? and close = 'O' order by sub asc", [name, data[0]])
if curs.fetchall():
it_p = 1
if it_p != 1:
div += '
'
if div == '':
plus = re.sub('^ ', '', plus)
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + sub + ')', 0])],
data = '',
menu = menu
))
@app.route('/login', methods=['POST', 'GET'])
def login():
if 'Now' in session and session['Now'] == 1:
return re_error(conn, '/error/11')
ip = ip_check()
agent = request.headers.get('User-Agent')
curs.execute("select block from ban where block = ? and login = 'O'", [ip])
if not curs.fetchall():
ban = ban_check(conn)
else:
ban = 0
if ban == 1:
return re_error(conn, '/ban')
if request.method == 'POST':
if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
return re_error(conn, '/error/13')
else:
captcha_post('', conn, 0)
curs.execute("select pw from user where id = ?", [request.form.get('id', None)])
user = curs.fetchall()
if not user:
return re_error(conn, '/error/5')
if not bcrypt.checkpw(bytes(request.form.get('pw', None), 'utf-8'), bytes(user[0][0], 'utf-8')):
return re_error(conn, '/error/10')
session['Now'] = 1
session['DREAMER'] = request.form.get('id', None)
curs.execute("select css from custom where user = ?", [request.form.get('id', None)])
css_data = curs.fetchall()
if css_data:
session['Daydream'] = css_data[0][0]
else:
session['Daydream'] = ''
curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')", [request.form.get('id', None), ip, agent, get_time()])
conn.commit()
return redirect('/user')
else:
return html_minify(render_template(skin_check(conn),
imp = ['로그인', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['user', '사용자']]
))
@app.route('/change', methods=['POST', 'GET'])
def change_password():
if ban_check(conn) == 1:
return re_error(conn, '/ban')
if custom(conn)[2] == 0:
return redirect('/login')
if request.method == 'POST':
if request.form.get('pw', None):
if request.form.get('pw2', None) != request.form.get('pw3', None):
return re_error(conn, '/error/20')
curs.execute("select pw from user where id = ?", [session['DREAMER']])
user = curs.fetchall()
if not user:
return re_error(conn, '/error/10')
if not bcrypt.checkpw(bytes(request.form.get('pw', None), 'utf-8'), bytes(user[0][0], 'utf-8')):
return re_error(conn, '/error/5')
hashed = bcrypt.hashpw(bytes(request.form.get('pw2', None), 'utf-8'), bcrypt.gensalt())
curs.execute("update user set pw = ? where id = ?", [hashed.decode(), session['DREAMER']])
curs.execute("update user set email = ? where id = ?", [request.form.get('email', ''), ip_check()])
curs.execute("update user set skin = ? where id = ?", [request.form.get('skin', ''), ip_check()])
conn.commit()
return redirect('/change')
else:
ip = ip_check()
curs.execute('select email from user where id = ?', [ip])
data = curs.fetchall()
if data:
email = data[0][0]
else:
email = ''
div2 = ''
curs.execute('select skin from user where id = ?', [ip])
data = curs.fetchall()
for skin_data in os.listdir(os.path.abspath('views')):
if not data:
curs.execute('select data from other where name = "skin"')
sql_data = curs.fetchall()
if sql_data and sql_data[0][0] == skin_data:
div2 = '' + div2
else:
div2 += ''
elif data[0][0] == skin_data:
div2 = '' + div2
else:
div2 += ''
return html_minify(render_template(skin_check(conn),
imp = ['내 정보 수정', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['user', '사용자']]
))
@app.route('/check/')
def user_check(name = None):
if admin_check(conn, 4, 'check (' + name + ')') != 1:
return re_error(conn, '/error/3')
curs.execute("select acl from user where id = ? or id = ?", [name, request.args.get('plus', 'None-Data')])
user = curs.fetchall()
if user and user[0][0] != 'user':
if admin_check(conn, None, None) != 1:
return re_error(conn, '/error/4')
if request.args.get('plus', None):
if re.search('(?:\.|:)', name):
if re.search('(?:\.|:)', request.args.get('plus', None)):
curs.execute("select name, ip, ua, today from ua_d where ip = ? or ip = ? order by today desc", [name, request.args.get('plus', None)])
else:
curs.execute("select name, ip, ua, today from ua_d where ip = ? or name = ? order by today desc", [name, request.args.get('plus', None)])
else:
if re.search('(?:\.|:)', request.args.get('plus', None)):
curs.execute("select name, ip, ua, today from ua_d where name = ? or ip = ? order by today desc", [name, request.args.get('plus', None)])
else:
curs.execute("select name, ip, ua, today from ua_d where name = ? or name = ? order by today desc", [name, request.args.get('plus', None)])
elif re.search('(?:\.|:)', name):
curs.execute("select name, ip, ua, today from ua_d where ip = ? order by today desc", [name])
else:
curs.execute("select name, ip, ua, today from ua_d where name = ? order by today desc", [name])
record = curs.fetchall()
if record:
if not request.args.get('plus', None):
div = '(비교)'
else:
div = '(주요 대상)(비교 대상)'
div += '
'
div += '
이름
아이피
언제
'
for data in record:
if data[2]:
ua = data[2]
else:
ua = ' '
div += '
' + ip_pas(conn, data[0]) + '
' + ip_pas(conn, data[1]) + '
' + data[3] + '
'
div += '
' + ua + '
'
div += '
'
else:
return re_error(conn, '/error/5')
return html_minify(render_template(skin_check(conn),
imp = ['다중 검사', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['manager', lang_data['admin']]]
))
@app.route('/plus_check/', methods=['POST', 'GET'])
def plus_check(name):
if request.method == 'POST':
return redirect('/check/' + url_pas(name) + '?plus=' + url_pas(request.form.get('name2', None)))
else:
return html_minify(render_template(skin_check(conn),
imp = ['대상 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['manager', lang_data['admin']]]
))
@app.route('/register', methods=['POST', 'GET'])
def register():
if ban_check(conn) == 1:
return re_error(conn, '/ban')
if not admin_check(conn, None, None) == 1:
curs.execute('select data from other where name = "reg"')
set_d = curs.fetchall()
if set_d and set_d[0][0] == 'on':
return re_error(conn, '/ban')
if request.method == 'POST':
if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
return re_error(conn, '/error/13')
else:
captcha_post('', conn, 0)
if request.form.get('pw', None) != request.form.get('pw2', None):
return re_error(conn, '/error/20')
if re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.form.get('id', None)):
return re_error(conn, '/error/8')
if len(request.form.get('id', None)) > 32:
return re_error(conn, '/error/7')
curs.execute("select id from user where id = ?", [request.form.get('id', None)])
if curs.fetchall():
return re_error(conn, '/error/6')
hashed = bcrypt.hashpw(bytes(request.form.get('pw', None), 'utf-8'), bcrypt.gensalt())
curs.execute("select id from user limit 1")
if not curs.fetchall():
curs.execute("insert into user (id, pw, acl, date, email) values (?, ?, 'owner', ?, ?)", [request.form.get('id', None), hashed.decode(), get_time(), request.form.get('email', '')])
else:
curs.execute("insert into user (id, pw, acl, date, email) values (?, ?, 'user', ?, ?)", [request.form.get('id', None), hashed.decode(), get_time(), request.form.get('email', '')])
conn.commit()
return redirect('/login')
else:
contract = ''
curs.execute('select data from other where name = "contract"')
data = curs.fetchall()
if data and data[0][0] != '':
contract = data[0][0] + ''
return html_minify(render_template(skin_check(conn),
imp = ['회원가입', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['user', '사용자']]
))
@app.route('/logout')
def logout():
session['Now'] = 0
session.pop('DREAMER', None)
return redirect('/user')
@app.route('/ban/', methods=['POST', 'GET'])
def user_ban(name = None):
curs.execute("select acl from user where id = ?", [name])
user = curs.fetchall()
if user and user[0][0] != 'user':
if admin_check(conn, None, None) != 1:
return re_error(conn, '/error/4')
if request.method == 'POST':
if admin_check(conn, 1, 'ban (' + name + ')') != 1:
return re_error(conn, '/error/3')
if request.form.get('year', 'no_end') == 'no_end':
end = ''
else:
end = request.form.get('year', '') + '-' + request.form.get('month', '') + '-' + request.form.get('day', '')
if end == '--':
end = ''
ban_insert(conn, name, end, request.form.get('why', ''), request.form.get('login', ''), ip_check())
return redirect('/ban/' + url_pas(name))
else:
if admin_check(conn, 1, None) != 1:
return re_error(conn, '/error/3')
curs.execute("select end, why from ban where block = ?", [name])
end = curs.fetchall()
if end:
now = lang_data['ban'] + ' ' + lang_data['release']
if end[0][0] == '':
data = '
무기한 ' + lang_data['ban'] + '
'
else:
data = '
' + lang_data['ban'] + ' : ' + end[0][0] + '
'
if end[0][1] != '':
data += '
사유 : ' + end[0][1] + '
'
else:
data += '
'
else:
if re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name):
now = '대역 ' + lang_data['ban']
else:
now = lang_data['ban']
now_time = get_time()
m = re.search('^([0-9]{4})-([0-9]{2})-([0-9]{2})', now_time)
g = m.groups()
year = ''
for i in range(int(g[0]), int(g[0]) + 11):
if i == int(g[0]):
year += ''
else:
year += ''
month = ''
for i in range(1, 13):
if int(i / 10) == 0:
num = '0' + str(i)
else:
num = str(i)
if i == int(g[1]):
month += ''
else:
month += ''
day = ''
for i in range(1, 32):
if int(i / 10) == 0:
num = '0' + str(i)
else:
num = str(i)
if i == int(g[2]):
day += ''
else:
day += ''
if re.search('(\.|:)', name):
plus = ' 로그인 가능'
else:
plus = ''
data = ' 년 '
data += ' 월 '
data += ' 일 '
data += '' + plus
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + now + ')', 0])],
data = '',
menu = [['manager', lang_data['admin']]]
))
@app.route('/acl/', methods=['POST', 'GET'])
def acl(name = None):
check_ok = ''
if request.method == 'POST':
check_data = 'acl (' + name + ')'
else:
check_data = None
user_data = re.search('^사용자:(.+)$', name)
if user_data:
if custom(conn)[2] == 0:
return redirect('/login')
elif user_data.groups()[0] != ip_check():
if admin_check(conn, 5, check_data) != 1:
if check_data:
return re_error(conn, '/error/3')
else:
check_ok = 'disable'
else:
if admin_check(conn, 5, check_data) != 1:
if check_data:
return re_error(conn, '/error/3')
else:
check_ok = 'disabled'
if request.method == 'POST':
curs.execute("select title from acl where title = ?", [name])
if curs.fetchall():
curs.execute("update acl set dec = ? where title = ?", [request.form.get('dec', ''), name])
curs.execute("update acl set dis = ? where title = ?", [request.form.get('dis', ''), name])
curs.execute("update acl set why = ? where title = ?", [request.form.get('why', ''), name])
else:
curs.execute("insert into acl (title, dec, dis, why) values (?, ?, ?, ?)", [name, request.form.get('dec', ''), request.form.get('dis', ''), request.form.get('why', '')])
curs.execute("select title from acl where title = ? and dec = '' and dis = ''", [name])
if curs.fetchall():
curs.execute("delete from acl where title = ?", [name])
conn.commit()
return redirect('/acl/' + url_pas(name))
else:
data = '
문서 ACL
'
if not re.search('^사용자:', name):
data += '
토론 ACL
'
if acl_data:
data += ''
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ACL)', 0])],
data = '',
menu = [['w/' + url_pas(name), lang_data['document']], ['manager', lang_data['admin']]]
))
@app.route('/admin/', methods=['POST', 'GET'])
def user_admin(name = None):
owner = admin_check(conn, None, None)
curs.execute("select acl from user where id = ?", [name])
user = curs.fetchall()
if not user:
return re_error(conn, '/error/5')
else:
if owner != 1:
curs.execute('select name from alist where name = ? and acl = "owner"', [user[0][0]])
if curs.fetchall():
return re_error(conn, '/error/3')
if ip_check() == name:
return re_error(conn, '/error/3')
if request.method == 'POST':
if admin_check(conn, 7, 'admin (' + name + ')') != 1:
return re_error(conn, '/error/3')
if owner != 1:
curs.execute('select name from alist where name = ? and acl = "owner"', [request.form.get('select', None)])
if curs.fetchall():
return re_error(conn, '/error/3')
if request.form.get('select', None) == 'X':
curs.execute("update user set acl = 'user' where id = ?", [name])
else:
curs.execute("update user set acl = ? where id = ?", [request.form.get('select', None), name])
conn.commit()
return redirect('/admin/' + url_pas(name))
else:
if admin_check(conn, 7, None) != 1:
return re_error(conn, '/error/3')
div = ''
i = 0
name_rem = ''
curs.execute('select distinct name from alist order by name asc')
for data in curs.fetchall():
if user[0][0] == data[0]:
div += ''
else:
if owner != 1:
curs.execute('select name from alist where name = ? and acl = "owner"', [data[0]])
if not curs.fetchall():
div += ''
else:
div += ''
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (권한 관리)', 0])],
data = '',
menu = [['manager', lang_data['admin']]]
))
@app.route('/diff/')
def diff_data(name = None):
first = request.args.get('first', '1')
second = request.args.get('second', '1')
curs.execute("select data from history where id = ? and title = ?", [first, name])
first_raw_data = curs.fetchall()
if first_raw_data:
curs.execute("select data from history where id = ? and title = ?", [second, name])
second_raw_data = curs.fetchall()
if second_raw_data:
first_data = html.escape(first_raw_data[0][0])
second_data = html.escape(second_raw_data[0][0])
if first == second:
result = '내용이 같습니다.'
else:
diff_data = difflib.SequenceMatcher(None, first_data, second_data)
result = re.sub('\r', '', diff(diff_data))
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (비교)', 0])],
data = '
' + result + '
',
menu = [['history/' + url_pas(name), lang_data['history']]]
))
return redirect('/history/' + url_pas(name))
@app.route('/down/')
def down(name = None):
div = '
'
curs.execute("select title from data where title like ?", ['%' + name + '/%'])
for data in curs.fetchall():
div += '
'
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (하위)', 0])],
data = div,
menu = [['w/' + url_pas(name), lang_data['document']]]
))
@app.route('/w/')
def read_view(name = None):
data_none = 0
sub = ''
acl = ''
div = ''
num = request.args.get('num', None)
if num:
num = int(num)
curs.execute("select sub from rd where title = ? order by date desc", [name])
for data in curs.fetchall():
curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
if not curs.fetchall():
sub += ' (토론)'
break
curs.execute("select title from data where title like ?", ['%' + name + '/%'])
if curs.fetchall():
down = 1
else:
down = 0
m = re.search("^(.*)\/(.*)$", name)
if m:
uppage = m.groups()[0]
else:
uppage = 0
if admin_check(conn, 5, None) == 1:
admin_memu = 1
else:
admin_memu = 0
if re.search("^분류:", name):
curs.execute("select link from back where title = ? and type = 'cat' order by link asc", [name])
back = curs.fetchall()
if back:
div = '
분류
'
u_div = ''
i = 0
for data in back:
if re.search('^분류:', data[0]):
u_div += '
'
elif re.search('^틀:', data[0]):
curs.execute("select data from data where title = ?", [data[0]])
db_data = curs.fetchall()
if db_data:
if re.search('\[\[' + name + '#include]]', db_data[0][0]):
div += '
'
if num:
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
if curs.fetchall() and admin_check(conn, 6, None) != 1:
return redirect('/history/' + url_pas(name))
curs.execute("select title, data from history where title = ? and id = ?", [name, str(num)])
else:
curs.execute("select title, data from data where title = ?", [name])
data = curs.fetchall()
if data:
else_data = data[0][1]
response_data = 200
else:
data_none = 1
response_data = 404
else_data = ''
m = re.search("^사용자:([^/]*)", name)
if m:
g = m.groups()
curs.execute("select acl from user where id = ?", [g[0]])
test = curs.fetchall()
if test and test[0][0] != 'user':
acl = ' (' + lang_data['admin'] + ')'
else:
curs.execute("select block from ban where block = ?", [g[0]])
if curs.fetchall():
sub += ' (' + lang_data['ban'] + ')'
else:
acl = ''
curs.execute("select dec from acl where title = ?", [name])
data = curs.fetchall()
if data:
acl += ' (ACL)'
if request.args.get('froms', None):
else_data = re.sub('\r\n#(?:redirect|넘겨주기) (?P(?:(?!\r\n).)+)\r\n', ' * [[\g]] 문서로 넘겨주기', '\r\n' + else_data + '\r\n')
else_data = re.sub('^\r\n', '', else_data)
else_data = re.sub('\r\n$', '', else_data)
end_data = namumark(conn, name, else_data, 0)
if num:
menu = [['history/' + url_pas(name), lang_data['history']]]
sub = ' (' + str(num) + lang_data['version'] + ')'
acl = ''
r_date = 0
else:
if data_none == 1:
menu = [['edit/' + url_pas(name), '생성']]
else:
menu = [['edit/' + url_pas(name), '수정']]
menu += [['topic/' + url_pas(name), '토론'], ['history/' + url_pas(name), lang_data['history']], ['xref/' + url_pas(name), '역링크'], ['acl/' + url_pas(name), 'ACL']]
if request.args.get('froms', None):
menu += [['w/' + url_pas(name), '넘기기']]
end_data = '
' + end_data
if uppage != 0:
menu += [['w/' + url_pas(uppage), '상위']]
if down:
menu += [['down/' + url_pas(name), '하위']]
curs.execute("select date from history where title = ? order by date desc limit 1", [name])
date = curs.fetchall()
if date:
r_date = date[0][0]
else:
r_date = 0
div = end_data + div
return html_minify(render_template(skin_check(conn),
imp = [name, wiki_set(conn, 1), custom(conn), other2([sub + acl, r_date])],
data = div,
menu = menu
)), response_data
@app.route('/topic_record/')
def user_topic_list(name = None):
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
one_admin = admin_check(conn, 1, None)
div = '
'
div += '
토론명
작성자
시간
'
curs.execute("select title, id, sub, ip, date from topic where ip = ? order by date desc limit ?, '50'", [name, str(sql_num)])
data_list = curs.fetchall()
for data in data_list:
title = html.escape(data[0])
sub = html.escape(data[2])
if one_admin == 1:
curs.execute("select * from ban where block = ?", [data[3]])
if curs.fetchall():
ban = ' (' + lang_data['release'] + ')'
else:
ban = ' (' + lang_data['ban'] + ')'
else:
ban = ''
div += '
'
div += next_fix('/topic_record/' + url_pas(name) + '?num=', num, data_list)
curs.execute("select end from ban where block = ?", [name])
if curs.fetchall():
sub = ' (' + lang_data['ban'] + ')'
else:
sub = 0
return html_minify(render_template(skin_check(conn),
imp = ['토론 기록', wiki_set(conn, 1), custom(conn), other2([sub, 0])],
data = div,
menu = [['other', '기타'], ['user', '사용자'], ['count/' + url_pas(name), '횟수'], ['record/' + url_pas(name), lang_data['edit']]]
))
@app.route('/recent_changes')
@app.route('//')
@app.route('//', methods=['POST', 'GET'])
def recent_changes(name = None, tool = 'record'):
if request.method == 'POST':
return redirect('/diff/' + url_pas(name) + '?first=' + request.form.get('b', None) + '&second=' + request.form.get('a', None))
else:
one_admin = admin_check(conn, 1, None)
six_admin = admin_check(conn, 6, None)
ban = ''
select = ''
what = request.args.get('what', 'all')
div = '
'
if name:
num = int(request.args.get('num', 1))
if num * 50 > 0:
sql_num = num * 50 - 50
else:
sql_num = 0
if tool == 'history':
div += '
' + lang_data['version'] + '
편집자
시간
'
curs.execute("select id, title, date, ip, send, leng from history where title = ? order by id + 0 desc limit ?, '50'", [name, str(sql_num)])
else:
div += '
문서명
편집자
시간
'
if what == 'all':
div = '(' + lang_data['revert'] + ')' + div
div = '(' + lang_data['move'] + ') ' + div
div = '(삭제) ' + div
curs.execute("select id, title, date, ip, send, leng from history where ip = ? order by date desc limit ?, '50'", [name, str(sql_num)])
else:
if what == 'delete':
sql = '%(삭제)'
elif what == 'move':
sql = '%' + lang_data['move'] + ')'
elif what == 'revert':
sql = '%' + lang_data['version'] + ')'
else:
return redirect('/')
curs.execute("select id, title, date, ip, send, leng from history where ip = ? and send like ? order by date desc limit ?, '50'", [name, sql, str(sql_num)])
else:
div += '
',
menu = 0
))
@app.route('/watch_list')
def watch_list():
div = '한도 : 10개'
if custom(conn)[2] == 0:
return redirect('/login')
curs.execute("select title from scan where user = ?", [ip_check()])
data = curs.fetchall()
for data_list in data:
div += '
'
div += '(추가)'
return html_minify(render_template(skin_check(conn),
imp = ['주시 문서 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['manager', lang_data['admin']]]
))
@app.route('/watch_list/')
def watch_list_name(name = None):
if custom(conn)[2] == 0:
return redirect('/login')
ip = ip_check()
curs.execute("select count(title) from scan where user = ?", [ip])
count = curs.fetchall()
if count and count[0][0] > 9:
return redirect('/watch_list')
curs.execute("select title from scan where user = ? and title = ?", [ip, name])
if curs.fetchall():
curs.execute("delete from scan where user = ? and title = ?", [ip, name])
else:
curs.execute("insert into scan (user, title) values (?, ?)", [ip, name])
conn.commit()
return redirect('/watch_list')
@app.route('/custom_head', methods=['GET', 'POST'])
def custom_head_view():
ip = ip_check()
if request.method == 'POST':
if custom(conn)[2] != 0:
curs.execute("select user from custom where user = ?", [ip + ' (head)'])
if curs.fetchall():
curs.execute("update custom set css = ? where user = ?", [request.form.get('content', None), ip + ' (head)'])
else:
curs.execute("insert into custom (user, css) values (?, ?)", [ip + ' (head)', request.form.get('content', None)])
conn.commit()
session['MyMaiToNight'] = request.form.get('content', None)
return redirect('/user')
else:
if custom(conn)[2] != 0:
start = ''
curs.execute("select css from custom where user = ?", [ip + ' (head)'])
head_data = curs.fetchall()
if head_data:
data = head_data[0][0]
else:
data = ''
else:
start = '' + lang_data['user_css_warring'] + ''
if 'MyMaiToNight' in session:
data = session['MyMaiToNight']
else:
data = ''
start += '<style>CSS</style> <script>JS</script>'
return html_minify(render_template(skin_check(conn),
imp = ['사용자 HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = start + '',
menu = [['user', '사용자']]
))
@app.route('/count')
@app.route('/count/')
def count_edit(name = None):
if name == None:
that = ip_check()
else:
that = name
curs.execute("select count(title) from history where ip = ?", [that])
count = curs.fetchall()
if count:
data = count[0][0]
else:
data = 0
curs.execute("select count(title) from topic where ip = ?", [that])
count = curs.fetchall()
if count:
t_data = count[0][0]
else:
t_data = 0
return html_minify(render_template(skin_check(conn),
imp = ['활동 횟수', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '