from flask import Flask, request, send_from_directory
from flask_reggie import Reggie
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
import bcrypt
import difflib
import shutil
import threading
import logging
import random
logging.basicConfig(level = logging.ERROR)
app = Flask(__name__)
Reggie(app)
r_ver = 'v2.6.0'
from func import *
from set_mark.mid_pas import mid_pas
from set_mark.macro import savemark
# set.json 설정 확인
try:
json_data = open('set.json').read()
set_data = json.loads(json_data)
except:
while(1):
print('DB 이름 : ', 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('값을 입력하세요.')
pass
# 디비 연결
conn = sqlite3.connect(set_data['db'] + '.db')
curs = conn.cursor()
# 스킨 불러오기 부분
skin_check(conn)
# 셋업 부분
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)")
curs.execute("create table if not exists ban(block text, end text, why text, band 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)")
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("select name from alist where name = '소유자'")
if(not curs.fetchall()):
curs.execute("insert into alist (name, acl) values ('소유자', 'owner')")
curs.execute("select data from other where name = 'port'")
rep_data = curs.fetchall()
if(not rep_data):
while(1):
print('포트 : ', 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]
curs.execute("select data from other where name = 'key'")
rep_data = curs.fetchall()
if(not rep_data):
while(1):
print('비밀 키 : ', 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]
# 호환성 설정
curs.execute("drop table if exists move")
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")
except:
pass
try:
curs.execute("alter table user add date text default ''")
except:
pass
try:
curs.execute("alter table rb add band text default ''")
except:
pass
try:
curs.execute("alter table ban add login text default ''")
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")
except:
pass
try:
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(robot_test[0][0])
fw_test.close()
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('백업 성공')
except:
print('백업 오류')
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) + '시간 간격으로 백업')
if(__name__ == '__main__'):
back_up()
else:
print('백업하지 않음')
@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():
ip = ip_check()
if(re.search('(?:\.|:)', ip)):
return(redirect('/login'))
da = '
'
curs.execute("select data, date from alarm where name = ? order by date desc", [ip])
dt = curs.fetchall()
if(dt):
da = '(모두 삭제)' + da
for do in dt:
da += '
' + do[0] + ' / ' + do[1] + '
'
else:
da += '
알림이 없습니다.
'
da += '
'
return(html_minify(template('index',
imp = ['알림', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = da,
menu = [['user', '사용자']]
)))
@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 += ' * [[wiki:edit_set/' + str(x) + '|' + li + ']]\r\n'
return(html_minify(template('index',
imp = ['설정 편집', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = namumark(conn, '', '[목차(없음)]\r\n' + \
'== 메뉴 ==\r\n' + \
li_data, 0, 0, 0),
menu = [['manager', '관리자']]
)))
elif(num == 1):
i_list = ['name', 'logo', 'frontpage', 'license', 'upload', 'skin', 'edit', 'reg', 'ip_view', 'back_up', 'all_title']
n_list = ['무명위키', '', '위키:대문', '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 = ''
ch_2 = ''
ch_3 = ''
if(d_list[7]):
ch_1 = 'checked="checked"'
if(d_list[8]):
ch_2 = 'checked="checked"'
if(d_list[10]):
ch_3 = 'checked="checked"'
return(html_minify(template('index',
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['contract'], 'contract'])
curs.execute("update other set data = ? where name = ?", [request.form['no_login_warring'], '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(template('index',
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['content']])
else:
curs.execute("insert into other (name, data) values ('head', ?)", [request.form['content']])
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(template('index',
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['content']])
else:
curs.execute("insert into other (name, data) values ('robot', ?)", [request.form['content']])
conn.commit()
fw = open('./robots.txt', 'w')
fw.write(request.form['content'])
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 = ''
return(html_minify(template('index',
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['recaptcha']])
curs.execute("update other set data = ? where name = 'sec_re'", [request.form['sec_re']])
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(template('index',
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, acl from data where acl = 'admin' or acl = 'user' order by acl 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 = '관리자'
else:
acl = '가입자'
div += '
'
return(html_minify(template('index',
imp = ['관리 그룹 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['manager', '관리자']]
)))
@app.route('/admin_list')
def admin_list():
div = '
'
curs.execute("select id, acl, date from user where not acl = 'user' order by date desc")
user_data = curs.fetchall()
for data in user_data:
name = ip_pas(conn, data[0]) + ' (' + data[1] + ')'
if(data[2] != ''):
name += '(가입 : ' + data[2] + ')'
div += '
' + name + '
'
div += '
'
return(html_minify(template('index',
imp = ['관리자 목록', 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]])
ban_exist = curs.fetchall()
if(ban_exist):
ban_button = ' (해제)'
else:
ban_button = ' (차단)'
else:
ban_button = ''
ip = ip_pas(conn, data[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:
ip = ip_pas(conn, data[0])
list_data += '
'
back = ''
curs.execute("select distinct name from alist order by name asc")
get_list = curs.fetchall()
for data in get_list:
if(back != data[0]):
back = data[0]
list_data += '
(생성)'
return(html_minify(template('index',
imp = ['권한 목록', 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'))
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;")
data = curs.fetchall()
for table in data:
print('----- ' + table[0] + ' -----')
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(n_cul)
sql = 'create index index_' + table[0] + '_' + n_cul + ' on ' + table[0] + '(' + n_cul + ')'
try:
curs.execute(sql)
except:
pass
conn.commit()
return(redirect('/'))
@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 += '
'
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(template('index',
imp = ['필요한 문서', 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 += '
'
data_list = ''
if(not name):
if(not tool2):
div = '(차단자)(관리자)(아이피)(가입자)(영구)(기간)(해제)(현재)' + div
sub = 0
menu = [['other', '기타']]
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'", ['%:%', '%해제%', str(sql_num)])
elif(tool2 == 'end'):
sub = '(해제)'
curs.execute("select why, block, blocker, end, today from rb where end = ? order by today desc limit ?, '50'", ['해제', 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
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 = ' (관리자)'
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 = ' '
b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data[1])
if(b):
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(template('index',
imp = ['차단 기록', 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['search'])))
@app.route('/goto', methods=['POST'])
def goto():
curs.execute("select title from data where title = ?", [request.form['search']])
data = curs.fetchall()
if(data):
return(redirect('/w/' + url_pas(request.form['search'])))
else:
return(redirect('/search/' + url_pas(request.form['search'])))
@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 += ''
test = data[1]
div_plus += '
'
div += next_fix('/search/' + url_pas(name) + '?num=', num, all_list)
return(html_minify(template('index',
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_t = None, num = None):
v_name = name
sub = ' (원본)'
if(not num):
num = request.args.get('num', None)
if(num):
num = int(num)
if(not sub_t and num):
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
hid = curs.fetchall()
if(hid 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) + '판)'
menu = [['history/' + url_pas(name), '역사']]
elif(sub_t):
curs.execute("select data from topic where id = ? and title = ? and sub = ? and block = ''", [str(num), name, sub_t])
v_name = '토론 원본'
sub = ' (' + str(num) + '번)'
menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub_t) + '#' + str(num), '토론']]
else:
curs.execute("select data from data where title = ?", [name])
menu = [['w/' + url_pas(name), '문서']]
data = curs.fetchall()
if(data):
p_data = html.escape(data[0][0])
p_data = ''
return(html_minify(template('index',
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):
ip = ip_check()
can = acl_check(conn, name)
today = get_time()
num = int(request.args.get('num', 0))
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 = ? 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(can == 1):
return(re_error(conn, '/ban'))
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])
d = curs.fetchall()
if(d):
leng = leng_check(len(d[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], today, ip, request.form['send'] + ' (' + str(num) + '판)', leng)
namumark(conn, name, data[0][0], 1, 0, 0)
conn.commit()
return(redirect('/w/' + url_pas(name)))
else:
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
hid = curs.fetchall()
if(hid and admin_check(conn, 6, None) != 1):
return(re_error(conn, '/error/3'))
if(can == 1):
return(re_error(conn, '/ban'))
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(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (되돌리기)', 0])],
data = '',
menu = [['history/' + url_pas(name), '역사'], ['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['content'] + '\r\n'
m = re.findall('(.*)\r\n', data)
for g in m:
curs.execute("select data from data where title = ?", [g])
d = curs.fetchall()
if(d):
curs.execute("delete from back where title = ?", [g])
leng = '-' + str(len(d[0][0]))
curs.execute("delete from data where title = ?", [g])
history_plus(conn, g, '', today, ip, request.form['send'] + ' (대량 삭제)', leng)
data = re.sub('(.*)\r\n', '', data, 1)
conn.commit()
return(redirect('/'))
else:
return(html_minify(template('index',
imp = ['많은 문서 삭제', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '문서명 A 문서명 B 문서명 C이런 식으로 적으세요. \
',
menu = [['manager', '관리자']]
)))
@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(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (이동 기록)', 0])],
data = data,
menu = [['history/' + url_pas(name), '역사']]
)))
@app.route('/move/', methods=['POST', 'GET'])
def move(name = None):
ip = ip_check()
can = acl_check(conn, name)
today = get_time()
if(can == 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['title']])
if(curs.fetchall()):
return(re_error(conn, '/error/19'))
curs.execute("select data from data where title = ?", [name])
data = curs.fetchall()
leng = '0'
if(data):
curs.execute("update data set title = ? where title = ?", [request.form['title'], name])
curs.execute("update back set link = ? where link = ?", [request.form['title'], name])
d = data[0][0]
else:
d = ''
history_plus(conn, name, d, today, ip, request.form['send'] + ' (' + name + ' - ' + request.form['title'] + ' 이동)', leng)
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['title'], name])
conn.commit()
return(redirect('/w/' + url_pas(request.form['title'])))
else:
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (이동)', 0])],
data = '',
menu = [['w/' + url_pas(name), '문서']]
)))
@app.route('/other')
def other():
return(html_minify(template('index',
imp = ['기타 메뉴', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = namumark(conn, '', '[목차(없음)]\r\n' + \
'== 기록 ==\r\n' + \
' * [[wiki:block_log|차단 기록]]\r\n' + \
' * [[wiki:user_log|가입 기록]]\r\n' + \
' * [[wiki:admin_log|권한 사용 기록]]\r\n' + \
' * [[wiki:manager/6|편집 기록]]\r\n' + \
' * [[wiki:manager/7|토론 기록]]\r\n' + \
'== 목록 ==\r\n' + \
' * [[wiki:admin_list|관리자 목록]]\r\n' + \
' * [[wiki:give_log|권한 목록]]\r\n' +
' * [[wiki:not_close_topic|열린 토론 목록]]\r\n' + \
'== 기타 ==\r\n' + \
' * [[wiki:title_index|모든 문서]]\r\n' + \
' * [[wiki:acl_list|ACL 문서]]\r\n' + \
' * [[wiki:please|필요한 문서]]\r\n' + \
' * [[wiki:upload|파일 올리기]]\r\n' + \
' * [[wiki:manager/10|문서 검색]]\r\n' + \
'== 관리자 ==\r\n' + \
' * [[wiki:manager/1|관리자 메뉴]]\r\n' + \
'== 버전 ==\r\n' + \
' * 이 오픈나무는 [[https://github.com/2DU/openNAMU/blob/master/version.md|' + r_ver + ']] 입니다.', 0, 0, 0),
menu = 0
)))
@app.route('/manager', methods=['POST', 'GET'])
@app.route('/manager/', methods=['POST', 'GET'])
def manager(num = 1):
title_list = [['문서 ACL', '문서명', 'acl'], ['사용자 검사', 0, 'check'], ['사용자 차단', 0, 'ban'], ['권한 주기', 0, 'admin'], ['편집 기록', 0, 'record'], ['토론 기록', 0, 'topic_record'], ['그룹 생성', '그룹명', 'admin_plus'], ['편집 필터 생성', '필터명', 'edit_filter'], ['문서 검색', '문서명', 'search'], ['차단자 검색', 0, 'block_user'], ['관리자 검색', 0, 'block_admin'], ['주시 문서 추가', '문서명', 'watch_list']]
if(num == 1):
return(html_minify(template('index',
imp = ['관리자 메뉴', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = namumark(conn, '', '[목차(없음)]\r\n' + \
'== 목록 ==\r\n' + \
' * [[wiki:manager/2|문서 ACL]]\r\n' + \
' * [[wiki:manager/3|사용자 검사]]\r\n' + \
' * [[wiki:manager/100|사용자 비교]]\r\n' + \
' * [[wiki:manager/4|사용자 차단]]\r\n' + \
' * [[wiki:manager/5|권한 주기]]\r\n' + \
' * [[wiki:big_delete|여러 문서 삭제]]\r\n' + \
' * [[wiki:edit_filter|편집 필터]]\r\n' + \
'== 소유자 ==\r\n' + \
' * [[wiki:indexing|인덱싱]]\r\n' + \
' * [[wiki:manager/8|관리 그룹 생성]]\r\n' + \
' * [[wiki:edit_set|설정 편집]]\r\n' + \
'== 기타 ==\r\n' + \
' * 이 메뉴에 없는 기능은 해당 문서의 역사나 토론에서 바로 사용 가능함', 0, 0, 0),
menu = [['other', '기타']]
)))
elif(num in range(2, 14)):
if(request.method == 'POST'):
return(redirect('/' + title_list[(num - 2)][2] + '/' + url_pas(request.form['name'])))
else:
if(title_list[(num - 2)][1] == 0):
placeholder = '사용자명'
else:
placeholder = title_list[(num - 2)][1]
return(html_minify(template('index',
imp = [title_list[(num - 2)][0], wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['manager', '관리자']]
)))
elif(num == 100):
if(request.method == 'POST'):
return(redirect('/check/' + url_pas(request.form['name']) + '?plus=' + url_pas(request.form['name2'])))
else:
return(html_minify(template('index',
imp = ['검사', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['manager', '관리자']]
)))
else:
return(redirect('/'))
@app.route('/title_index')
def title_index():
page = int(request.args.get('page', 1))
num = int(request.args.get('num', 100))
if(page * num > 0):
sql_num = page * num - num
else:
sql_num = 0
if(num != 0):
all_list = sql_num + 1
else:
all_list = 1
if(num > 1000):
return(re_error(conn, '/error/3'))
data = '
(전체)(250)(500)(1000)'
if(num == 0):
curs.execute("select data from other where name = 'all_title'")
all_title_can = curs.fetchall()
if(all_title_can and all_title_can[0][0] != ''):
return(re_error(conn, '/error/3'))
curs.execute("select title from data order by title asc")
else:
curs.execute("select title from data order by title asc limit ?, ?", [str(sql_num), str(num)])
title_list = curs.fetchall()
for list_data in title_list:
data += '
' + all_data + data,
menu = [['topic/' + url_pas(name), '목록']]
)))
@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['topic'] + 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['topic'] + t_num)))
else:
plus = ''
menu = [['topic/' + url_pas(name), '목록']]
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 = '토론 목록'
menu = [['w/' + url_pas(name), '문서']]
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 == '토론 목록'):
curs.execute("select title from stop where title = ? and sub = ? and close = 'O' order by sub asc", [name, data[0]])
close = curs.fetchall()
if(close):
it_p = 1
if(it_p != 1):
div += '
'
if(div == ''):
plus = re.sub('^ ', '', plus)
return(html_minify(template('index',
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['id']])
user = curs.fetchall()
if(not user):
return(re_error(conn, '/error/5'))
if(not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8'))):
return(re_error(conn, '/error/10'))
session['Now'] = 1
session['DREAMER'] = request.form['id']
curs.execute("select css from custom where user = ?", [request.form['id']])
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['id'], ip, agent, get_time()])
conn.commit()
return(redirect('/user'))
else:
return(html_minify(template('index',
imp = ['로그인', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = '',
menu = [['user', '사용자']]
)))
@app.route('/change', methods=['POST', 'GET'])
def change_password():
ip = ip_check()
ban = ban_check(conn)
if(request.method == 'POST'):
if(request.form['pw2'] != request.form['pw3']):
return(re_error(conn, '/error/20'))
if(ban == 1):
return(re_error(conn, '/ban'))
curs.execute("select pw from user where id = ?", [session['DREAMER']])
user = curs.fetchall()
if(not user):
return(re_error(conn, '/error/10'))
if(re.search('(\.|:)', ip)):
return(redirect('/login'))
if(not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8'))):
return(re_error(conn, '/error/5'))
hashed = bcrypt.hashpw(bytes(request.form['pw2'], 'utf-8'), bcrypt.gensalt())
curs.execute("update user set pw = ? where id = ?", [hashed.decode(), session['DREAMER']])
conn.commit()
return(redirect('/user'))
else:
if(ban == 1):
return(re_error(conn, '/ban'))
if(re.search('(\.|:)', ip)):
return(redirect('/login'))
return(html_minify(template('index',
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):
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(template('index',
imp = ['다중 검사', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['manager', '관리자']]
)))
@app.route('/register', methods=['POST', 'GET'])
def register():
ip = ip_check()
ban = ban_check(conn)
if(ban == 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['pw'] != request.form['pw2']):
return(re_error(conn, '/error/20'))
if(re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.form['id'])):
return(re_error(conn, '/error/8'))
if(len(request.form['id']) > 32):
return(re_error(conn, '/error/7'))
curs.execute("select id from user where id = ?", [request.form['id']])
if(curs.fetchall()):
return(re_error(conn, '/error/6'))
hashed = bcrypt.hashpw(bytes(request.form['pw'], 'utf-8'), bcrypt.gensalt())
curs.execute("select id from user limit 1")
user_ex = curs.fetchall()
if(not user_ex):
curs.execute("insert into user (id, pw, acl, date) values (?, ?, '소유자', ?)", [request.form['id'], hashed.decode(), get_time()])
else:
curs.execute("insert into user (id, pw, acl, date) values (?, ?, 'user', ?)", [request.form['id'], hashed.decode(), get_time()])
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(template('index',
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'))
ip = ip_check()
time = get_time()
time_list = [request.form['month'], request.form['day'], request.form['hour'], request.form['minu']]
num = 0
for time_fix in time_list:
if(not re.search("[0-9]{2}", time_fix)):
time_list[num] = '0' + time_fix
num += 1
if(request.form['year'] == '09'):
end = ''
else:
end = request.form['year'] + '-' + time_list[0] + '-' + time_list[1] + ' ' + time_list[2] + ':' + time_list[3] + ':00'
curs.execute("select block from ban where block = ?", [name])
if(curs.fetchall()):
curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, '')", [name, '해제', time, ip, ''])
curs.execute("delete from ban where block = ?", [name])
else:
if(re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name)):
band_d = 'O'
else:
band_d = ''
if(request.form['login_ok'] != ''):
login = 'O'
else:
login = ''
curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, ?)", [name, end, time, ip, request.form['why'], band_d])
curs.execute("insert into ban (block, end, why, band, login) values (?, ?, ?, ?, ?)", [name, end, request.form['why'], band_d, login])
conn.commit()
return(redirect('/ban/' + url_pas(name)))
else:
if(admin_check(conn, 1, None) != 1):
return(re_error(conn, '/error/3'))
curs.execute("select end from ban where block = ?", [name])
end = curs.fetchall()
if(end):
now = '차단 해제'
if(end[0][0] == ''):
data = '영구 차단'
else:
data = end[0][0] + ' 까지 차단'
else:
if(re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name)):
now = '대역 차단'
else:
now = '차단'
now_time = get_time()
m = re.search('^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([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(i == int(g[1])):
month += ''
else:
month += ''
day = ''
for i in range(1, 32):
if(i == int(g[2])):
day += ''
else:
day += ''
hour = ''
for i in range(0, 24):
if(i == int(g[3])):
hour += ''
else:
hour += ''
minu = ''
for i in range(0, 61):
if(i == int(g[4])):
minu += ''
else:
minu += ''
is_it = ''
if(re.search('(\.|:)', name)):
plus = ' 로그인 가능'
else:
plus = ''
data = ' 년 '
data += ' 월 '
data += ' 일 '
data += ' 시 '
data += ' 분 까지'
data += ' ' + plus
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + now + ')', 0])],
data = '',
menu = [['manager', '관리자']]
)))
@app.route('/acl/', methods=['POST', 'GET'])
def acl(name = None):
test = re.search('^사용자:(.+)$', name)
if(request.method == 'POST'):
if(test):
test = test.groups()
ip = ip_check()
if(re.search("(\.|:)", ip)):
return(redirect('/login'))
elif(test[0] != ip):
if(admin_check(conn, 5, 'acl (' + name + ')') != 1):
return(re_error(conn, '/error/3'))
else:
if(admin_check(conn, 5, 'acl (' + name + ')') != 1):
return(re_error(conn, '/error/3'))
if(request.form['select'] == 'admin'):
sql = 'admin'
elif(request.form['select'] == 'all'):
sql = 'all'
elif(request.form['select'] == 'user'):
sql = 'user'
else:
sql = ''
if(sql == ''):
curs.execute("delete from acl where title = ?", [name])
else:
curs.execute("select title from acl where title = ?", [name])
if(curs.fetchall()):
curs.execute("update acl set dec = ? where title = ?", [sql, name])
else:
curs.execute("insert into acl (title, dec, dis, why) values (?, ?, '', '')", [name, sql])
conn.commit()
return(redirect('/w/' + url_pas(name)))
else:
if(test):
test = test.groups()
ip = ip_check()
if(re.search("(\.|:)", ip)):
return(redirect('/login'))
elif(test[0] != ip):
if(admin_check(conn, 5, 'acl (' + name + ')') != 1):
return(re_error(conn, '/error/3'))
else:
if(admin_check(conn, 5, 'acl (' + name + ')') != 1):
return(re_error(conn, '/error/3'))
acl_list = ['', '', '']
curs.execute("select dec from acl where title = ?", [name])
acl_d = curs.fetchall()
if(acl_d):
if(test and acl_d[0][0] == 'all'):
now = '모두'
acl_list[0] = 'selected="selected"'
elif(not test and acl_d[0][0] == 'admin'):
now = '관리자'
acl_list[0] = 'selected="selected"'
elif(acl_d[0][0] == 'user'):
now = '가입자'
acl_list[1] = 'selected="selected"'
else:
now = '일반'
acl_list[2] = 'selected="selected"'
else:
now = '일반'
acl_list[2] = 'selected="selected"'
if(test):
plus = ''
else:
plus = ''
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ACL)', 0])],
data = '',
menu = [['w/' + url_pas(name), '문서'], ['manager', '관리자']]
)))
@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'))
curs.execute('select name from alist where name = ? and acl = "owner"', [request.form['select']])
if(curs.fetchall()):
return(re_error(conn, '/error/3'))
if(request.form['select'] == 'X'):
curs.execute("update user set acl = 'user' where id = ?", [name])
else:
curs.execute("update user set acl = ? where id = ?", [request.form['select'], name])
conn.commit()
return(redirect('/admin/' + url_pas(name)))
else:
if(admin_check(conn, 7, None) != 1):
return(re_error(conn, '/error/3'))
div = ''
curs.execute('select distinct name from alist order by name asc')
get_alist = curs.fetchall()
if(get_alist):
i = 0
name_rem = ''
for data in get_alist:
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(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (권한 부여)', 0])],
data = '',
menu = [['manager', '관리자']]
)))
@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 = diff(diff_data)
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (비교)', 0])],
data = '
' + result + '
',
menu = [['history/' + url_pas(name), '역사']]
)))
return(redirect('/history/' + url_pas(name)))
@app.route('/down/')
def down(name = None):
curs.execute("select title from data where title like ?", ['%' + name + '/%'])
under = curs.fetchall()
div = '
'
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([' (하위)', 0])],
data = div,
menu = [['w/' + url_pas(name), '문서']]
)))
@app.route('/w/')
def read_view(name = None):
data_none = 0
sub = ''
acl = ''
div = ''
topic = 0
num = request.args.get('num', None)
if(num):
num = int(num)
if(not num):
if('View_list' in session):
m = re.findall('([^\n]+)\n', session['View_List'])
if(m[-1] != name):
d = re.sub(name + '\n', '', session['View_List'])
d += name + '\n'
if(len(m) > 50):
d = re.sub('([^\n]+)\n', '', d, 1)
session['View_List'] = d
else:
session['View_List'] = name + '\n'
curs.execute("select sub from rd where title = ? order by date desc", [name])
rd = curs.fetchall()
for data in rd:
curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
if(not curs.fetchall()):
topic = 1
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 = '[목차(없음)]\r\n== 분류 ==\r\n'
u_div = ''
i = 0
for data in back:
if(re.search('^분류:', data[0])):
if(u_div == ''):
u_div = '=== 하위 분류 ===\r\n'
u_div += ' * [[:' + data[0] + ']]\r\n'
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 + ']]', mid_pas(db_data[0][0], 0, 1, 0, 0)[0])):
div += ' * [[' + data[0] + ']]\r\n * [[wiki:xref/' + url_pas(data[0]) + '|' + data[0] + ']] (역링크)\r\n'
else:
div += ' * [[' + data[0] + ']]\r\n'
else:
div += ' * [[' + data[0] + ']]\r\n'
div += u_div
if(num):
curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
hid = curs.fetchall()
if(hid 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):
elsedata = data[0][1]
else:
data_none = 1
response.status = 404
elsedata = ''
if(not num):
curs.execute("select dec from acl where title = ?", [name])
acl_d = curs.fetchall()
if(acl_d):
if(acl_d[0][0] == 'admin'):
acl = ' (관리자)'
elif(acl_d[0][0] == 'user'):
acl = ' (가입자)'
else:
curs.execute('select data from other where name = "edit"')
set_data = curs.fetchall()
if(set_data):
if(set_data[0][0] == 'admin'):
acl = ' (관리자)'
elif(set_data[0][0] == 'user'):
acl = ' (가입자)'
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 = ' (관리자)'
else:
curs.execute("select block from ban where block = ?", [g[0]])
if(curs.fetchall()):
sub = ' (차단)'
else:
acl = ''
curs.execute("select dec from acl where title = ?", [name])
data = curs.fetchall()
if(data):
if(data[0][0] == 'all'):
acl += ' (모두)'
elif(data[0][0] == 'user'):
acl += ' (가입자)'
if(request.args.get('froms', None)):
elsedata = re.sub("^#(?:redirect|넘겨주기) (?P[^\n]*)", " * [[\g]] 문서로 넘겨주기", elsedata)
enddata = namumark(conn, name, elsedata, 0, 0, 1)
if(data_none == 1):
menu = [['edit/' + url_pas(name), '생성'], ['topic/' + url_pas(name), topic], ['history/' + url_pas(name), '역사'], ['move/' + url_pas(name), '이동'], ['xref/' + url_pas(name), '역링크']]
else:
menu = [['edit/' + url_pas(name), '수정'], ['topic/' + url_pas(name), topic], ['history/' + url_pas(name), '역사'], ['delete/' + url_pas(name), '삭제'], ['move/' + url_pas(name), '이동'], ['raw/' + url_pas(name), '원본'], ['xref/' + url_pas(name), '역링크']]
if(admin_memu == 1):
menu += [['acl/' + url_pas(name), 'ACL']]
if(request.args.get('froms', None)):
menu += [['w/' + url_pas(name), '넘기기']]
enddata = '
' + enddata
if(uppage != 0):
menu += [['w/' + url_pas(uppage), '상위']]
if(down):
menu += [['down/' + url_pas(name), '하위']]
if(num):
menu = [['history/' + url_pas(name), '역사']]
sub = ' (' + str(num) + '판)'
acl = ''
r_date = 0
else:
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
if(div != '' and enddata != ''):
div = enddata + ' ' + namumark(conn, name, div, 0, 0, 0)
else:
div = enddata + namumark(conn, name, div, 0, 0, 0)
return(html_minify(template('index',
imp = [name, wiki_set(conn, 1), custom(conn), other2([sub + acl, r_date])],
data = div,
menu = menu
)))
@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 = ' (해제)'
else:
ban = ' (차단)'
else:
ban = ''
ip = ip_pas(conn, data[3])
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 += '
판
편집자
시간
'
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 = '(되돌리기)' + div
div = '(이동) ' + 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 = '%이동)'
elif(what == 'revert'):
sql = '%판)'
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 += '
'
div += '(추가)'
return(html_minify(template('index',
imp = ['편집 필터 목록', wiki_set(conn, 1), custom(conn), other2([0, 0])],
data = div,
menu = [['manager', '관리자']]
)))
@app.route('/watch_list/')
def watch_list_name(name = None):
ip = ip_check()
if(re.search('\.|:', ip)):
return(redirect('/login'))
curs.execute("select count(title) from scan where user = ?", [ip])
count = curs.fetchall()
if(count):
if(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('/view_log')
def view_log():
data = '
'
if(session['View_List']):
data += '
최근 50개
'
m = re.findall('([^\n]+)\n', session['View_List'])
for d in m:
data += '