from bottle import * from bottle.ext import beaker import json import sqlite3 import bcrypt import os import difflib from css_html_js_minify import html_minify from multiprocessing import Process try: json_data = open('set.json').read() set_data = json.loads(json_data) except: new_json = [] print('DB 이름 : ', end = '') new_json += [input()] print('포트 : ', end = '') new_json += [input()] with open("set.json", "w") as f: f.write('{ "db" : "' + new_json[0] + '", "port" : "' + new_json[1] + '" }') json_data = open('set.json').read() set_data = json.loads(json_data) conn = sqlite3.connect(set_data['db'] + '.db') curs = conn.cursor() session_opts = { 'session.type': 'file', 'session.data_dir': './app_session/', 'session.auto': 1 } app = beaker.middleware.SessionMiddleware(app(), session_opts) from func import * BaseRequest.MEMFILE_MAX = 1000 ** 4 def redirect(data): return('') def re_error(data): if(data == '/ban'): ip = ip_check() end = '권한이 맞지 않는 상태 입니다.' if(ban_check() == 1): curs.execute("select end, why from ban where block = ?", [ip]) d = curs.fetchall() if(not d): m = re.search("^([0-9]{1,3}\.[0-9]{1,3})", ip) if(m): curs.execute("select end, why from ban where block = ? and band = 'O'", [m.groups()[0]]) d = curs.fetchall() if(d): if(d[0][0]): end = d[0][0] + ' 까지 차단 상태 입니다. / 사유 : ' + d[0][1] now = re.sub(':', '', get_time()) now = re.sub('\-', '', now) now = int(re.sub(' ', '', now)) day = re.sub('\-', '', d[0][0]) if(now >= int(day + '000000')): curs.execute("delete from ban where block = ?", [ip]) conn.commit() end = '차단이 풀렸습니다. 다시 시도 해 보세요.' else: end = '영구 차단 상태 입니다. / 사유 : ' + d[0][1] return( html_minify( template('index', imp = ['권한 오류', wiki_set(1), custom(), other2([0, 0])], data = end, menu = 0 ) ) ) d = re.search('\/error\/([0-9]+)', data) if(d): num = int(d.groups()[0]) if(num == 1): title = '권한 오류' data = '비 로그인 상태 입니다.' elif(num == 2): title = '권한 오류' data = '이 계정이 없습니다.' elif(num == 3): title = '권한 오류' data = '권한이 모자랍니다.' elif(num == 4): title = '권한 오류' data = '관리자는 차단, 검사 할 수 없습니다.' elif(num == 5): title = '사용자 오류' data = '그런 계정이 없습니다.' elif(num == 6): title = '가입 오류' data = '동일한 아이디의 사용자가 있습니다.' elif(num == 7): title = '가입 오류' data = '아이디는 20글자보다 짧아야 합니다.' elif(num == 8): title = '가입 오류' data = '아이디에는 한글과 알파벳과 공백만 허용 됩니다.' elif(num == 9): title = '파일 올리기 오류' data = '파일이 없습니다.' elif(num == 10): title = '변경 오류' data = '비밀번호가 다릅니다.' elif(num == 11): title = '로그인 오류' data = '이미 로그인 되어 있습니다.' elif(num == 14): title = '파일 올리기 오류' data = 'jpg, gif, jpeg, png, webp만 가능 합니다.' elif(num == 15): title = '편집 오류' data = '편집 기록은 500자를 넘을 수 없습니다.' elif(num == 16): title = '파일 올리기 오류' data = '동일한 이름의 파일이 있습니다.' elif(num == 17): title = '파일 올리기 오류' data = '파일 용량은 ' + wiki_set(3) + 'MB를 넘길 수 없습니다.' elif(num == 18): title = '편집 오류' data = '내용이 원래 문서와 동일 합니다.' elif(num == 19): title = '이동 오류' data = '이동 하려는 곳에 문서가 이미 있습니다.' elif(num == 20): title = '비밀번호 오류' data = '재 확인이랑 비밀번호가 다릅니다.' if(title): return( html_minify( template( 'index', imp = [title, wiki_set(1), custom(), other2([0, 0])], data = data, menu = 0 ) ) ) else: return(redirect('/')) else: return(redirect('/')) r_ver = '2.3.5' p_ver = 's' try: curs.execute("select title from data limit 1") try: curs.execute('select new from move limit 1') except: curs.execute("create table move(origin text, new text, date text, who text, send text)") print('move 테이블 생성') curs.execute('select data from other where name = "skin"') skin_exist = curs.fetchall() if(skin_exist): if(os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.tpl')) == 1): TEMPLATE_PATH.insert(0, './views/' + skin_exist[0][0] + '/') else: TEMPLATE_PATH.insert(0, './views/acme/') else: TEMPLATE_PATH.insert(0, './views/acme/') try: curs.execute('select name from alarm limit 1') except: curs.execute("create table alarm(name text, data text, date text)") print('alarm 테이블 생성') try: curs.execute('select name from ua_d limit 1') except: curs.execute("create table ua_d(name text, ip text, ua text, today text, sub text)") print('ua_d 테이블 생성') try: curs.execute('select user, ip, today from login') lo_d = curs.fetchall() for m_lo in lo_d: curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, '', ?, '')", [m_lo[0], m_lo[1], m_lo[2]]) curs.execute("drop table login") print('login 테이블 삭제') except: pass try: curs.execute('select title, cat from cat') lo_d = curs.fetchall() for m_lo in lo_d: curs.execute("insert into back (title, link, type) values (?, ?, 'cat')", [m_lo[0], m_lo[1]]) curs.execute("drop table cat") print('cat 테이블 삭제') except: pass conn.commit() except: pass @route('/setup', method=['GET', 'POST']) def setup(): try: curs.execute("select title from data limit 1") except: try: curs.execute("create table data(title text, data text, acl text)") except: pass try: curs.execute("create table history(id text, title text, data text, date text, ip text, send text, leng text)") except: pass try: curs.execute("create table rd(title text, sub text, date text)") except: pass try: curs.execute("create table user(id text, pw text, acl text)") except: pass try: curs.execute("create table ban(block text, end text, why text, band text)") except: pass try: curs.execute("create table topic(id text, title text, sub text, data text, date text, ip text, block text, top text)") except: pass try: curs.execute("create table stop(title text, sub text, close text)") except: pass try: curs.execute("create table rb(block text, end text, today text, blocker text, why text)") except: pass try: curs.execute("create table back(title text, link text, type text)") except: pass try: curs.execute("create table hidhi(title text, re text)") except: pass try: curs.execute("create table agreedis(title text, sub text)") except: pass try: curs.execute("create table custom(user text, css text)") except: pass try: curs.execute("create table other(name text, data text)") except: pass try: curs.execute("create table alist(name text, acl text)") curs.execute("insert into alist (name, acl) values ('소유자', 'owner')") except: pass try: curs.execute("create table re_admin(who text, what text, time text)") except: pass try: curs.execute("create table move(origin text, new text, date text, who text, send text)") except: pass try: curs.execute("create table alarm(name text, data text, date text)") except: pass try: curs.execute("create table ua_d(name text, ip text, ua text, today text, sub text)") except: pass conn.commit() return(redirect('/')) @route('/del_alarm') def del_alarm(): curs.execute("delete from alarm where name = ?", [ip_check()]) conn.commit() return(redirect('/alarm')) @route('/alarm') def alarm(): ip = ip_check() if(re.search('(?:\.|:)', ip)): return(redirect('/login')) da = '' return( html_minify( template('index', imp = ['알림', wiki_set(1), custom(), other2([0, 0])], data = da, menu = [['user', '사용자']] ) ) ) @route('/edit_set', method=['POST', 'GET']) @route('/edit_set/', method=['POST', 'GET']) def edit_set(num = 0): if(num == 0): return( html_minify( template('index', imp = ['설정 편집', wiki_set(1), custom(), other2([0, 0])], data = '', menu = [['manager', '관리자']] ) ) ) elif(num == 1): if(admin_check(None, 'edit_set') == 1): if(request.method == 'POST'): curs.execute("update other set data = ? where name = ?", [request.forms.name, 'name']) curs.execute("update other set data = ? where name = 'frontpage'", [request.forms.frontpage]) curs.execute("update other set data = ? where name = 'license'", [request.forms.license]) curs.execute("update other set data = ? where name = 'upload'", [request.forms.upload]) curs.execute("update other set data = ? where name = 'skin'", [request.forms.skin]) curs.execute("update other set data = ? where name = 'edit'", [request.forms.edit]) curs.execute("update other set data = ? where name = 'reg'", [request.forms.reg]) conn.commit() return(redirect('/edit_set/1')) else: i_list = ['name', 'frontpage', 'license', 'upload', 'skin', 'edit', 'reg'] n_list = ['무명위키', '위키:대문', 'CC 0', '2', '', 'normal', ''] 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[5] == 'login'): div += '' div += '' div += '' elif(d_list[5] == 'admin'): div += '' div += '' div += '' else: div += '' div += '' div += '' if(d_list[6]): ch_1 = 'checked="checked"' else: ch_1 = '' return( html_minify( template('index', imp = ['기본 설정', wiki_set(1), custom(), other2([0, 0])], data = '
\ 위키 이름 (기본 : 무명위키) \
\
\ \
\
\ 시작 페이지 (기본 : 위키:대문) \
\
\ \
\
\ 라이선스 (기본 : CC 0) \
\
\ \
\
\ 파일 용량 한도 (기본 : 2) \
\
\ \
\
\ 스킨 (기본 : acme) (재시작 필요) \
\
\ \
\
\ 기본 ACL 설정 (기본 : 일반) \
\
\ \
\
\ 가입불가 \
\
\ \
', menu = [['edit_set', '설정 편집']] ) ) ) elif(num == 2): if(admin_check(None, 'edit_set') == 1): if(request.method == 'POST'): curs.execute("update other set data = ? where name = ?", [request.forms.contract, 'contract']) conn.commit() return(redirect('/edit_set/2')) else: i_list = ['contract'] 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(1), custom(), other2([0, 0])], data = '
\ 가입 약관 \
\
\ \
\
\ \
', menu = [['edit_set', '설정 편집']] ) ) ) else: return(re_error('/ban')) @route('/not_close_topic') def not_close_topic(): div = '' return( html_minify( template('index', imp = ['열린 토론 목록', wiki_set(1), custom(), other2([0, 0])], data = div, menu = [['manager', '관리자']] ) ) ) @route('/image/') def static(name = None): if(os.path.exists(os.path.join('image', name))): return(static_file(name, root = 'image')) else: return(redirect('/')) @route('/acl_list') def acl_list(): div = '' return( html_minify( template('index', imp = ['ACL 문서 목록', wiki_set(1), custom(), other2([0, 0])], data = div, menu = [['other', '기타']] ) ) ) @route('/list_acl') def list_acl(): div = '
(생성)' return( html_minify( template('index', imp = ['ACL 목록', wiki_set(1), custom(), other2([0, 0])], data = re.sub('^
', '', div), menu = [['manager', '관리자']] ) ) ) @route('/admin_plus/', method=['POST', 'GET']) def admin_plus(name = None): if(admin_check(None, 'admin_plus (' + name + ')') == 1): if(request.method == 'POST'): curs.execute("delete from alist where name = ?", [name]) if(request.forms.ban): curs.execute("insert into alist (name, acl) values (?, 'ban')", [name]) if(request.forms.mdel): curs.execute("insert into alist (name, acl) values (?, 'mdel')", [name]) if(request.forms.toron): curs.execute("insert into alist (name, acl) values (?, 'toron')", [name]) if(request.forms.check): curs.execute("insert into alist (name, acl) values (?, 'check')", [name]) if(request.forms.acl): curs.execute("insert into alist (name, acl) values (?, 'acl')", [name]) if(request.forms.hidel): curs.execute("insert into alist (name, acl) values (?, 'hidel')", [name]) if(request.forms.owner): curs.execute("insert into alist (name, acl) values (?, 'owner')", [name]) conn.commit() return(redirect('/admin_plus/' + url_pas(name))) else: curs.execute('select acl from alist where name = ?', [name]) test = curs.fetchall() data = '
    ' exist_list = ['', '', '', '', '', '', ''] for go in test: if(go[0] == 'ban'): exist_list[0] = 'checked="checked"' elif(go[0] == 'mdel'): exist_list[1] = 'checked="checked"' elif(go[0] == 'toron'): exist_list[2] = 'checked="checked"' elif(go[0] == 'check'): exist_list[3] = 'checked="checked"' elif(go[0] == 'acl'): exist_list[4] = 'checked="checked"' elif(go[0] == 'hidel'): exist_list[5] = 'checked="checked"' elif(go[0] == 'owner'): exist_list[6] = 'checked="checked"' data += '
  • 차단
  • ' data += '
  • 많은 문서 삭제
  • ' data += '
  • 토론 관리
  • ' data += '
  • 사용자 검사
  • ' data += '
  • 문서 ACL
  • ' data += '
  • 역사 숨김
  • ' data += '
  • 소유자
' return( html_minify( template('index', imp = ['관리 그룹 추가', wiki_set(1), custom(), other2([0, 0])], data = '
' \ + data + \ '
\ \
\
', menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/3')) @route('/admin_list') def admin_list(): i = 1 div = '
    ' curs.execute("select id, acl from user where not acl = 'user'") user_data = curs.fetchall() for data in user_data: name = ip_pas(data[0]) + ' (' + data[1] + ')' div += '
  • ' + str(i) + '. ' + name + '
  • ' i += 1 div += '
' return( html_minify( template('index', imp = ['관리자 목록', wiki_set(1), custom(), other2([0, 0])], data = div, menu = [['other', '기타']] ) ) ) @route('/record/') @route('/record//n/') @route('/recent_changes') def recent_changes(name = None, num = 1): ydmin = admin_check(1, None) zdmin = admin_check(6, None) ban = '' send = '
' div = ' \ \ \ \ \ \ ' if(name): if(num * 50 <= 0): v = 50 else: v = num * 50 i = v - 50 div = '(토론 기록)

' + div curs.execute("select id, title, date, ip, send, leng from history where ip = ? order by date desc limit ?, ?", [name, str(i), str(v)]) else: curs.execute("select id, title, date, ip, send, leng from history where not date = 'Dump' order by date desc limit 50") rows = curs.fetchall() for data in rows: send = '
' if(data[4]): if(not re.search("^(?: *)$", data[4])): send = data[4] title = html.escape(data[1]) if(re.search("\+", data[5])): leng = '' + data[5] + '' elif(re.search("\-", data[5])): leng = '' + data[5] + '' else: leng = '' + data[5] + '' if(ydmin == 1): curs.execute("select * from ban where block = ?", [data[3]]) row = curs.fetchall() if(row): ban = ' (해제)' else: ban = ' (차단)' ip = ip_pas(data[3]) if((int(data[0]) - 1) == 0): revert = '' else: revert = '(비교)(되돌리기)' style = '' curs.execute("select * from hidhi where title = ? and re = ?", [data[1], data[0]]) row = curs.fetchall() if(zdmin == 1): if(row): ip += ' (숨김)' hidden = ' (공개)' else: hidden = ' (숨김)' else: if(row): ip = '숨김' hidden = '' send = '숨김' ban = '' style = 'display:none;' else: hidden = '' div += ' \ \ \ \ \ \ \ ' else: div += ' \
문서명기여자시간
\ ' + title + ' (' + data[0] + '판) ' + revert + ' (' + leng + ') \ ' + ip + ban + hidden + '' + data[2] + '
' + send + '
' if(name): curs.execute("select end, why from ban where block = ?", [name]) ban_it = curs.fetchall() if(ban_it): sub = '(차단)' else: sub = 0 title = '기여 기록' menu = [['other', '기타'], ['user', '사용자']] div += '
(이전) (이후)' else: sub = 0 menu = 0 title = '최근 변경내역' return( html_minify( template('index', imp = [title, wiki_set(1), custom(), other2([sub, 0])], data = div, menu = menu ) ) ) @route('/history//r//hidden') def history_hidden(name = None, num = None): if(admin_check(6, 'history_hidden (' + name + '#' + str(num) + ')') == 1): curs.execute("select * from hidhi where title = ? and re = ?", [name, str(num)]) exist = curs.fetchall() if(exist): curs.execute("delete from hidhi where title = ? and re = ?", [name, str(num)]) else: curs.execute("insert into hidhi (title, re) values (?, ?)", [name, str(num)]) conn.commit() return(redirect('/history/' + url_pas(name))) @route('/user_log') @route('/user_log/n/') def user_log(num = 1): if(num * 50 <= 0): i = 50 else: i = num * 50 j = i - 50 list_data = '
    ' ydmin = admin_check(1, None) curs.execute("select id from user limit ?, ?", [str(j), str(i)]) user_list = curs.fetchall() for data in user_list: if(ydmin == 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(data[0]) list_data += '
  • ' + str(j + 1) + '. ' + ip + ban_button + '
  • ' j += 1 else: list_data += '

(이전) (이후)' return( html_minify( template('index', imp = ['사용자 가입 기록', wiki_set(1), custom(), other2([0, 0])], data = list_data, menu = [['other', '기타']] ) ) ) @route('/admin_log') @route('/admin_log/n/') def user_log(num = 1): if(num * 50 <= 0): i = 50 else: i = num * 50 j = i - 50 list_data = '
    ' curs.execute("select who, what, time from re_admin order by time desc limit ?, ?", [str(j), str(i)]) get_list = curs.fetchall() for data in get_list: ip = ip_pas(data[0]) list_data += '
  • ' + str(j + 1) + '. ' + ip + ' / ' + data[1] + ' / ' + data[2] + '
  • ' j += 1 else: list_data += '

\ 주의 : 권한 사용 안하고 열람만 해도 기록되는 경우도 있습니다. \
\
\ (이전) (이후)' return( html_minify( template('index', imp = ['관리자 권한 기록', wiki_set(1), custom(), other2([0, 0])], data = list_data, menu = [['other', '기타']] ) ) ) @route('/give_log') @route('/give_log/n/') def give_log(num = 1): if(num * 50 <= 0): i = 50 else: i = num * 50 j = i - 50 list_data = '
    ' back = '' curs.execute("select name, acl from alist order by name asc limit ?, ?", [str(j), str(i)]) get_list = curs.fetchall() for data in get_list: if(back != data[0]): back = data[0] j += 1 list_data += '
  • ' + str(j) + '. ' + data[0] + ' (' + data[1] + ')
  • ' else: list_data += '

(이전) (이후)' return( html_minify( template('index', imp = ['권한 목록', wiki_set(1), custom(), other2([0, 0])], data = list_data, menu = [['other', '기타']] ) ) ) @route('/indexing') def indexing(): if(admin_check(None, 'indexing') == 1): 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 + ')' curs.execute(sql) conn.commit() return(redirect('/')) else: return(re_error('/error/3')) @route('/xref/') @route('/xref//n/') def xref(name = None, num = 1): if(num * 50 <= 0): v = 50 else: v = num * 50 i = v - 50 div = '
    ' curs.execute("delete from back where title = ? and link = ''", [name]) conn.commit() curs.execute("select link, type from back where title = ? order by link asc limit ?, ?", [name, str(i), str(v)]) rows = curs.fetchall() for data in rows: div += '
  • ' + data[0] + '' if(data[1]): div += ' (' + data[1] + ')' div += '
  • ' else: div += '

(이전) (이후)' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (역링크)', 0])], data = div, menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/recent_discuss') @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") rows = curs.fetchall() for data in rows: 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 += ' \ \ \ ' else: div += ' \
토론명시간
\ ' + title + ' (' + sub + ') \ ' + data[2] + '
' return( html_minify( template('index', imp = ['최근 토론내역', wiki_set(1), custom(), other2([m_sub, 0])], data = div, menu = 0 ) ) ) @route('/block_log') @route('/block_log/n/') def block_log(num = 1): if(num * 50 <= 0): v = 50 else: v = num * 50 i = v - 50 div = ' \ \ \ \ \ \ \ \ \ \ ' curs.execute("select why, block, blocker, end, today from rb order by today desc limit ?, ?", [str(i), str(v)]) rows = curs.fetchall() for data in rows: why = html.escape(data[0]) b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data[1]) if(b): ip = data[1] + ' (대역)' else: ip = ip_pas(data[1]) if(data[3] != ''): end = data[3] else: end = '무기한' div += ' \ \ \ \ \ \ \ \ ' else: div += ' \
차단자관리자기간
이유시간
' + ip + '' + ip_pas(data[2]) + '' + end + '
' + why + '' + data[4] + '
\
\ (이전) (이후)' return( html_minify( template('index', imp = ['차단 기록', wiki_set(1), custom(), other2([0, 0])], data = div, menu = [['other', '기타']] ) ) ) @route('/history/', method=['POST', 'GET']) @route('/history//n/', method=['POST', 'GET']) def history_view(name = None, num = 1): if(request.method == 'POST'): return(redirect('/w/' + url_pas(name) + '/r/' + request.forms.b + '/diff/' + request.forms.a)) else: select = '' if(num * 50 <= 0): i = 50 else: i = num * 50 j = i - 50 admin1 = admin_check(1, None) admin2 = admin_check(6, None) div = ' \ \ \ \ \ \ ' curs.execute("select send, leng, ip, date, title, id from history where title = ? order by id + 0 desc limit ?, ?", [name, str(j), str(i)]) all_data = curs.fetchall() for data in all_data: select += '' if(data[0]): send = data[0] else: send = '
' if(re.search("^\+", data[1])): leng = '' + data[1] + '' elif(re.search("^\-", data[1])): leng = '' + data[1] + '' else: leng = '' + data[1] + '' ip = ip_pas(data[2]) curs.execute("select block from ban where block = ?", [data[2]]) ban_it = curs.fetchall() if(ban_it): if(admin1 == 1): ban = ' (해제)' else: ban = ' (X)' else: if(admin1 == 1): ban = ' (차단)' else: ban = '' curs.execute("select * from hidhi where title = ? and re = ?", [name, data[5]]) hid_it = curs.fetchall() if(hid_it): if(admin2): hidden = ' (공개)' hid = 0 else: hid = 1 else: if(admin2): hidden = ' (숨김)' hid = 0 else: hidden = '' hid = 0 if(hid == 1): div += ' \ \ ' else: div += ' \ \ \ \ \ \ \ ' else: div += ' \
기여자시간
숨김
\ ' + data[5] + '판 (보기) \ (원본) \ (되돌리기) (' + leng + ') \ ' + ip + ban + hidden + '' + data[3] + '
' + send + '
\
\
(이전) (이후)' div = '
\ \ \ \
' + div return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (역사)', 0])], data = div, menu = [['w/' + url_pas(name), '문서'], ['move_data/' + url_pas(name), '이동 기록']] ) ) ) @route('/search', method=['POST']) def search(): return(redirect('/search/' + url_pas(request.forms.search))) @route('/goto', method=['POST']) def goto(): curs.execute("select title from data where title = ?", [request.forms.search]) data = curs.fetchall() if(data): return(redirect('/w/' + url_pas(request.forms.search))) else: return(redirect('/search/' + url_pas(request.forms.search))) @route('/search/') @route('/search//n/') def deep_search(name = None, num = 1): if(num * 50 <= 0): v = num * 50 else: v = 50 i = v - 50 div = '
    ' div_plus = '' end = '' curs.execute("select title from data where title like ?", ['%' + name + '%']) title_list = curs.fetchall() curs.execute("select title from data where data like ?", ['%' + name + '%']) data_list = curs.fetchall() curs.execute("select title from data where title = ?", [name]) exist = curs.fetchall() if(exist): div = '
    • 문서로 바로가기


    • ' else: div = '
      • 문서가 없습니다. 바로가기


      • ' if(title_list): no = 0 if(data_list): all_list = title_list + data_list else: all_list = title_list else: if(data_list): no = 1 all_list = data_list else: all_list = '' if(all_list != ''): for data in all_list: try: var_re = re.search(name, data[0]) except: var_re = re.search('\\' + name, data[0]) if(var_re): if(no == 0): div += '
      • ' + data[0] + ' (제목)
      • ' else: div_plus += '
      • ' + data[0] + ' (내용)
      • ' else: no = 1 div_plus += '
      • ' + data[0] + ' (내용)
      • ' else: div += '
      • 검색 결과 없음
      • ' div += div_plus + end div += '

      (이전) (이후)' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (검색)', 0])], data = div, menu = 0 ) ) ) @route('/raw/') @route('/raw//r/') @route('/topic//sub//raw/') def raw_view(name = None, sub_t = None, num = None): v_name = name sub = ' (원본)' if(not sub_t and num): curs.execute("select title from hidhi where title = ? and re = ?", [name, str(num)]) hid = curs.fetchall() if(hid and admin_check(6, None) != 1): return(re_error('/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(1), custom(), other2([sub, 0])], data = p_data, menu = menu ) ) ) else: return(redirect('/w/' + url_pas(name))) @route('/revert//r/', method=['POST', 'GET']) def revert(name = None, num = None): ip = ip_check() can = acl_check(name) today = get_time() if(request.method == 'POST'): curs.execute("select title from hidhi where title = ? and re = ?", [name, str(num)]) hid = curs.fetchall() if(hid and admin_check(6, None) != 1): return(re_error('/error/3')) if(can == 1): return(re_error('/ban')) else: curs.execute("delete from back where link = ?", [name]) conn.commit() curs.execute("select data from history where title = ? and id = ?", [name, str(num)]) rows = curs.fetchall() if(rows): curs.execute("select data from data where title = ?", [name]) row = curs.fetchall() if(row): leng = leng_check(len(row[0][0]), len(rows[0][0])) curs.execute("update data set data = ? where title = ?", [rows[0][0], name]) else: leng = '+' + str(len(rows[0][0])) curs.execute("insert into data (title, data, acl) values (?, ?, '')", [name, rows[0][0]]) history_plus( name, rows[0][0], today, ip, request.forms.send + ' (' + str(num) + '판)', leng ) namumark(name, rows[0][0], 1, 0, 0) conn.commit() return(redirect('/w/' + url_pas(name))) else: curs.execute("select title from hidhi where title = ? and re = ?", [name, str(num)]) hid = curs.fetchall() if(hid and admin_check(6, None) != 1): return(re_error('/error/3')) if(can == 1): return(re_error('/ban')) else: curs.execute("select title from history where title = ? and id = ?", [name, str(num)]) rows = curs.fetchall() if(rows): l = custom() if(l[2] == 0): plus = '비 로그인 상태입니다. 비 로그인으로 작업 시 아이피가 역사에 기록됩니다.

      ' else: plus = '' return( html_minify( template('index', imp = [name, wiki_set(1), l, other2([' (되돌리기)', 0])], data = plus + ' \
      \ \
      \
      \ \
      ', menu = [['history/' + url_pas(name), '역사'], ['recent_changes', '최근 변경']] ) ) ) else: return(redirect('/w/' + url_pas(name))) @route('/m_del', method=['POST', 'GET']) def m_del(): today = get_time() ip = ip_check() if(admin_check(2, 'm_del') == 1): if(request.method == 'POST'): data = request.forms.content + '\r\n' m = re.findall('(.*)\r\n', data) for g in m: curs.execute("select data from data where title = ?", [g]) rows = curs.fetchall() if(rows): curs.execute("delete from back where title = ?", [g]) leng = '-' + str(len(rows[0][0])) curs.execute("delete from data where title = ?", [g]) history_plus( g, '', today, ip, request.forms.send + ' (대량 삭제)', leng ) data = re.sub('(.*)\r\n', '', data, 1) conn.commit() return(redirect('/')) else: return( html_minify( template('index', imp = ['많은 문서 삭제', wiki_set(1), custom(), other2([0, 0])], data = ' \ 문서명 A \
      \ 문서명 B \
      \ 문서명 C \
      \
      \ 이런 식으로 적으세요. \
      \
      \
      \
      \ \
      \
      \ \
      \
      \
      \ \
      \
      ', menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/3')) @route('/edit/', method=['POST', 'GET']) @route('/edit//section/', method=['POST', 'GET']) def edit(name = None, num = None): ip = ip_check() can = acl_check(name) if(request.method == 'POST'): if(can == 1): return(re_error('/ban')) if(len(request.forms.send) > 500): return(re_error('/error/15')) if(request.forms.otent == request.forms.content): return(re_error('/error/18')) today = get_time() content = savemark(request.forms.content) curs.execute("delete from back where link = ?", [name]) curs.execute("select data from data where title = ?", [name]) rows = curs.fetchall() if(rows): leng = leng_check(len(request.forms.otent), len(content)) if(num): content = rows[0][0].replace(request.forms.otent, content) curs.execute("update data set data = ? where title = ?", [content, name]) else: leng = '+' + str(len(content)) curs.execute("insert into data (title, data, acl) values (?, ?, '')", [name, content]) history_plus( name, content, today, ip, send_p(request.forms.send), leng ) namumark(name, content, 1, 0, 0) include_check(name, content) conn.commit() return(redirect('/w/' + url_pas(name))) else: if(can == 1): return(re_error('/ban')) curs.execute("select data from data where title = ?", [name]) rows = curs.fetchall() if(rows): if(num): i = 0 j = 0 data = rows[0][0] + '\r\n' while(1): m = re.search("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", data) if(m): if(i == num - 1): g = m.groups() data = re.sub("\r\n$", "", g[0]) break else: data = re.sub("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", "", data, 1) i += 1 else: j = 1 break if(j == 0): data = re.sub("\r\n$", "", data) else: data = rows[0][0] else: data = '' if(num): action = '/section/' + str(num) else: action = '' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (수정)', 0])], data = '
      \ \ \
      \
      \ \
      \
      \
      \ \ \
      \
      ', menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/preview/', method=['POST']) @route('/preview//section/', method=['POST']) def preview(name = None, num = None): ip = ip_check() can = acl_check(name) if(can == 1): return(re_error('/ban')) newdata = request.forms.content newdata = re.sub('^#(?:redirect|넘겨주기) (?P[^\n]*)', ' * [[\g]] 문서로 넘겨주기', newdata) enddata = namumark(name, newdata, 0, 0, 0) if(num): action = '/section/' + str(num) else: action = '' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (미리보기)', 0])], data = '
      \ \ \
      \
      \ \
      \
      \
      \ \ \
      \
      \
      ' + enddata, menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/delete/', method=['POST', 'GET']) def delete(name = None): ip = ip_check() can = acl_check(name) if(request.method == 'POST'): curs.execute("select data from data where title = ?", [name]) rows = curs.fetchall() if(rows): if(can == 1): return(re_error('/ban')) today = get_time() leng = '-' + str(len(rows[0][0])) history_plus(name, '', today, ip, request.forms.send + ' (삭제)', leng) curs.execute("delete from back where link = ?", [name]) curs.execute("delete from data where title = ?", [name]) conn.commit() return(redirect('/w/' + url_pas(name))) else: curs.execute("select title from data where title = ?", [name]) rows = curs.fetchall() if(rows): if(can == 1): return(re_error('/ban')) else: l = custom() if(l[2] == 0): plus = '비 로그인 상태입니다. 비 로그인으로 작업 시 아이피가 역사에 기록됩니다.

      ' else: plus = '' return( html_minify( template('index', imp = [name, wiki_set(1), l, other2([' (삭제)', 0])], data = '
      \ ' + plus + ' \ \
      \
      \ \
      ', menu = [['w/' + url_pas(name), '문서']] ) ) ) else: return(redirect('/w/' + url_pas(name))) @route('/move_data/') @route('/move_data//') def move_data(name = None, n = 1): if(n > 0): i = n else: i = 1 j = i * 50 da = '
        ' curs.execute("select origin, new, date, who, send from move where origin = ? or new = ? limit ?, ?", [name, name, j - 50, j]) for d in curs.fetchall(): if(d[4] == ''): sn = '(없음)' else: sn = d[4] da += '
      • ' + d[0] + ' >> ' + d[1] + ' / ' + d[2] + ' / ' + d[3] + ' / ' + sn + '
      • ' da += '

      (이전) (이후)' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (이동)', 0])], data = da, menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/move/', method=['POST', 'GET']) def move(name = None): ip = ip_check() can = acl_check(name) today = get_time() if(can == 1): return(re_error('/ban')) if(request.method == 'POST'): curs.execute("select data from data where title = ?", [name]) rows = curs.fetchall() leng = '0' curs.execute("select title from history where title = ?", [request.forms.title]) row = curs.fetchall() if(row): return(re_error('/error/19')) if(rows): curs.execute("update data set title = ? where title = ?", [request.forms.title, name]) curs.execute("update back set link = ? where link = ?", [request.forms.title, name]) d = rows[0][0] else: d = '' history_plus( name, d, today, ip, request.forms.send + ' (' + name + ' - ' + request.forms.title + ' 이동)', leng ) curs.execute('insert into move (origin, new, date, who, send) values (?, ?, ?, ?, ?)', [name, request.forms.title, today, ip, request.forms.send]) curs.execute("update history set title = ? where title = ?", [request.forms.title, name]) conn.commit() return(redirect('/w/' + url_pas(request.forms.title))) else: l = custom() if(l[2] == 0): plus = '비 로그인 상태입니다. 비 로그인으로 작업 시 아이피가 역사에 기록됩니다.

      ' else: plus = '' return( html_minify( template('index', imp = [name, wiki_set(1), l, other2([' (이동)', 0])], data = '
      \ ' + plus + ' \ \
      \
      \ \
      \
      \ \
      ', menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/other') def other(): return( html_minify( template('index', imp = ['기타 메뉴', wiki_set(1), custom(), other2([0, 0])], data = namumark('', '[목차(없음)]\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:not_close_topic|열린 토론 목록]]\r\n' + \ '== 기타 ==\r\n' + \ ' * [[wiki:title_index|모든 문서]]\r\n' + \ ' * [[wiki:acl_list|ACL 문서]]\r\n' + \ ' * [[wiki:admin_list|관리자 목록]]\r\n' + \ ' * [[wiki:give_log|권한 목록]]\r\n' + \ ' * [[wiki:upload|파일 올리기]]\r\n' + \ '== 관리자 ==\r\n' + \ ' * [[wiki:manager/1|관리자 메뉴]]\r\n' + \ '== 버전 ==\r\n' + \ '이 오픈나무는 [[https://github.com/2DU/openNAMU/blob/SQLite/version.md|' + r_ver + p_ver + ']]판 입니다.', 0, 0, 0), menu = 0 ) ) ) @route('/manager', method=['POST', 'GET']) @route('/manager/', method=['POST', 'GET']) def manager(num = 1): if(num == 1): return( html_minify( template('index', imp = ['관리자 메뉴', wiki_set(1), custom(), other2([0, 0])], data = namumark('', '[목차(없음)]\r\n' + \ '== 목록 ==\r\n' + \ ' * [[wiki:manager/2|문서 ACL]]\r\n' + \ ' * [[wiki:manager/3|사용자 검사]]\r\n' + \ ' * [[wiki:manager/10|사용자 비교]]\r\n' + \ ' * [[wiki:manager/4|사용자 차단]]\r\n' + \ ' * [[wiki:manager/5|권한 주기]]\r\n' + \ ' * [[wiki:m_del|여러 문서 삭제]]\r\n' + \ '== 소유자 ==\r\n' + \ ' * [[wiki:indexing|인덱싱]]\r\n' + \ ' * [[wiki:manager/8|관리 그룹 생성]]\r\n' + \ ' * [[wiki:edit_set|설정 편집]]\r\n' + \ ' * [[wiki:manager/9|JSON 출력]]\r\n' + \ ' * [[wiki:json_in|JSON 입력]]\r\n' + \ '== 기타 ==\r\n' + \ ' * 이 메뉴에 없는 기능은 해당 문서의 역사나 토론에서 바로 사용 가능함', 0, 0, 0), menu = [['other', '기타']] ) ) ) elif(num == 2): if(request.method == 'POST'): return(redirect('/acl/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['ACL 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 3): if(request.method == 'POST'): return(redirect('/check/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['검사 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 4): if(request.method == 'POST'): return(redirect('/ban/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['차단 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 5): if(request.method == 'POST'): return(redirect('/admin/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['권한 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 6): if(request.method == 'POST'): return(redirect('/record/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['기록 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['other', '기타']] ) ) ) elif(num == 8): if(request.method == 'POST'): return(redirect('/admin_plus/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['그룹 생성 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 9): if(request.method == 'POST'): return(redirect('/json_out/' + url_pas(request.forms.name))) else: return( html_minify( template('index', imp = ['문서 출력 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) elif(num == 10): if(request.method == 'POST'): return(redirect('/check/' + url_pas(request.forms.name) + '/' + url_pas(request.forms.name2))) else: return( html_minify( template('index', imp = ['검사 이동', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) else: return(redirect('/')) @route('/json_out/') def json_out(name = None): if(admin_check(None, 'json_out') == 1): curs.execute('select data from data where title = ?', [name]) get_d = curs.fetchall() if(get_d): da = get_d[0][0] else: da = '' curs.execute('select ip from history where title = ? order by ip asc', [name]) get_h = curs.fetchall() var_n = '' hi_d = '' for hi in get_h: if(hi[0] != var_n): var_n = hi[0] hi_d += json.dumps(hi[0]) + ', ' else: hi_d = re.sub(', $', '', hi_d) if(hi_d == ''): return(redirect('/w/' + url_pas(name))) json_f = '{ "title" : ' + json.dumps(name) + ', "data" : ' + json.dumps(da) + ', "history" : [' + hi_d + '] }' return(json_f) else: return(re_error('/error/3')) @route('/json_in', method=['POST', 'GET']) def json_in(): if(admin_check(None, 'json_in') == 1): if(request.method == 'POST'): data = json.loads(request.forms.data) title = data["title"] curs.execute('select title from history where title = ?', [title]) get_d = curs.fetchall() if(get_d): return(redirect('/w/' + url_pas(title))) curs.execute('insert into data (title, data, acl) values (?, ?, "")', [title, data["data"]]) i = 0 date = get_time() for hi in data["history"]: i += 1 if(i == 1): curs.execute('insert into history (id, title, data, date, ip, send, leng) values (?, ?, ?, ?, ?, "", ?)', [i, title, data["data"], date, hi, '+' + len(data["data"])]) else: curs.execute('insert into history (id, title, data, date, ip, send, leng) values (?, ?, "", ?, ?, "", "0")', [i, title, date, hi]) conn.commit() return(redirect('/w/' + url_pas(title))) else: return( html_minify( template('index', imp = ['문서 JSON 입력', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/3')) @route('/title_index') @route('/title_index//') def title_index(num = 1000, page = 1): if(page > 0): v_page = page * num else: v_page = 1 * num if(num != 0): i = [v_page - num + 1] else: i = [1, 0, 0, 0, 0, 0] data = '
        (전체) (500) (5000개) (10000개) (50000개)

        ' if(num == 0): curs.execute("select title from data order by title asc") else: curs.execute("select title from data order by title asc limit ?, ?", [str(v_page - num), str(num)]) title_list = curs.fetchall() for list_data in title_list: data += '
      • ' + str(i[0]) + '. ' + list_data[0] + '
      • ' if(num == 0): if(re.search('^분류:', list_data[0])): i[1] += 1 elif(re.search('^사용자:', list_data[0])): i[2] += 1 elif(re.search('^틀:', list_data[0])): i[3] += 1 elif(re.search('^파일:', list_data[0])): i[4] += 1 else: i[5] += 1 i[0] += 1 if(num == 0): if(title_list): data += '

      • 이 위키에는 총 ' + str(i[0]) + '개의 문서가 있습니다.


      • \
      • 틀 문서는 총 ' + str(i[3]) + '개의 문서가 있습니다.
      • \
      • 분류 문서는 총 ' + str(i[1]) + '개의 문서가 있습니다.
      • \
      • 사용자 문서는 총 ' + str(i[2]) + '개의 문서가 있습니다.
      • \
      • 파일 문서는 총 ' + str(i[4]) + '개의 문서가 있습니다.
      • \
      • 나머지 문서는 총 ' + str(i[5]) + '개의 문서가 있습니다.
      • ' else: data += '

      (이전) (이후)' return( html_minify( template('index', imp = ['모든 문서', wiki_set(1), custom(), other2([' (' + str(num) + ')', 0])], data = data, menu = [['other', '기타']] ) ) ) @route('/topic//sub//b/') def topic_block(name = None, sub = None, num = None): if(admin_check(3, 'blind (' + name + ' - ' + sub + '#' + str(num) + ')') == 1): 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)]) conn.commit() rd_plus( name, sub, get_time() ) return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))) else: return(re_error('/error/3')) @route('/topic//sub//notice/') def topic_top(name = None, sub = None, num = None): if(admin_check(3, 'notice (' + name + ' - ' + sub + '#' + str(num) + ')') == 1): curs.execute("select * from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)]) topic_data = curs.fetchall() if(topic_data): 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)]) conn.commit() rd_plus( name, sub, get_time() ) return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))) else: return(re_error('/error/3')) @route('/topic//sub//tool/agree') def topic_agree(name = None, sub = None): if(admin_check(3, 'agree (' + name + ' - ' + sub + ')') == 1): ip = ip_check() 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): time = get_time() curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub]) agree = curs.fetchall() if(agree): 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]) conn.commit() rd_plus( name, sub, time ) return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))) else: return(re_error('/error/3')) @route('/topic//sub//tool/') def topic_stop(name = None, sub = None, tool = None): if(tool == 'close'): close = 'O' n_close = '' data = '토론 닫음' n_data = '토론 다시 열기' elif(tool == 'stop'): close = '' n_close = 'O' data = '토론 정지' n_data = '토론 재 시작' else: return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))) if(admin_check(3, 'topic stop and end (' + name + ' - ' + sub + ')') == 1): ip = ip_check() 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): time = get_time() curs.execute("select title from stop where title = ? and sub = ? and close = ?", [name, sub, close]) stop = curs.fetchall() if(stop): curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, n_data, time, ip]) curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, close]) 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, data, time, ip]) curs.execute("insert into stop (title, sub, close) values (?, ?, ?)", [name, sub, close]) curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, n_close]) conn.commit() rd_plus( name, sub, time ) return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))) else: return(re_error('/error/3')) @route('/topic//sub//admin/') def topic_admin(name = None, sub = None, num = None): curs.execute("select block, ip 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))) is_ban = '
    • ' if(data[0][0] == 'O'): is_ban += '가림 해제' else: is_ban += '가림' is_ban += '
    • ' curs.execute("select id from topic where title = ? and sub = ? and id = ? and top = 'O'", [name, sub, str(num)]) row = curs.fetchall() is_ban += '
    • ' if(row): is_ban += '공지 해제' else: is_ban += '공지' is_ban += '
    • ' curs.execute("select end from ban where block = ?", [data[0][1]]) ban_it = curs.fetchall() ban = '
    • ' if(ban_it): ban += '차단 해제' else: ban += '차단' ban += '
    • ' + is_ban return( html_minify( template('index', imp = ['토론 관리', wiki_set(1), custom(), other2([' (' + str(num) + '번)', 0])], data = '
        ' + ban + '
      ', menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num), '토론']] ) ) ) @route('/topic//sub/', method=['POST', 'GET']) def topic(name = None, sub = None): ban = topic_check(name, sub) admin = admin_check(3, None) if(request.method == 'POST'): ip = ip_check() today = get_time() curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub]) rows = curs.fetchall() if(rows): num = int(rows[0][0]) + 1 else: num = 1 m = re.search('^사용자:([^/]+)', name) if(m): d = m.groups() curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [d[0], ip + '님이 사용자 토론을 시작했습니다.', today]) if(ban == 1 and admin != 1): return(re_error('/ban')) rd_plus(name, sub, today) data = re.sub("\[\[(분류:(?:(?:(?!\]\]).)*))\]\]", "[br]", request.forms.content) m = re.findall("(?:#([0-9]+))", data) for da in m: curs.execute("select ip from topic where title = ? and sub = ? and id = ?", [name, sub, da]) row = curs.fetchall() if(row): if(not re.search('(\.|:)', row[0][0])): curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [row[0][0], ip + '님이 토론에서 언급 했습니다.', today]) data = re.sub("(?P#(?:[0-9]+))", '[[\g]]', data) data = savemark(data) 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: s = '' div = '' curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, sub]) cd = curs.fetchall() curs.execute("select title from stop where title = ? and sub = ? and close = ''", [name, sub]) sd = curs.fetchall() if(admin == 1): if(cd): div += '(열기) ' else: div += '(닫기) ' if(sd): div += '(재개) ' else: div += '(정지) ' curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub]) if(curs.fetchall()): div += '(합의)' else: div += '(취소)' div += '

      ' if((sd or cd) and admin != 1): s = 'display: none;' curs.execute("select data, id, date, ip, block, top from topic where title = ? and sub = ? order by id + 0 asc", [name, sub]) t1 = 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]) t2 = curs.fetchall() for d in t2: a = '' curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['notice (' + name + ' - ' + sub + '#' + d[1] + ')']) m = curs.fetchall() if(m): a += ' @' + m[0][0] div += ' \ \ \ \ \ \ \ \ \
      \ #' + d[1] + ' ' + ip_pas(d[3]) + a + ' ' + d[2] + ' \
      ' + namumark('', d[0], 0, 0, 0) + '
      \
      ' i = 1 for d in t1: if(i == 1): start = d[3] p = d[0] if(d[4] == 'O'): bd = '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(i) + ')']) b = curs.fetchall() if(b): p = '[[사용자:' + b[0][0] + ']]님이 가림' else: p = '관리자가 가림' else: bd = '' p = namumark('', p, 0, 0, 0) ip = ip_pas(d[3]) curs.execute('select acl from user where id = ?', [d[3]]) user_acl = curs.fetchall() if(user_acl and user_acl[0][0] != 'user'): ip += ' ' if(admin == 1 or bd == ''): ip += ' (원본)' if(admin == 1): ip += ' (관리)' curs.execute("select end from ban where block = ?", [d[3]]) if(curs.fetchall()): ip += ' ' if(d[5] == '1'): c = '_blue' elif(d[3] == start): c = '_green' else: c = '' if(p == ''): p = '
      ' div += ' \ \ \ \ \ \ \ \ \
      \ #' + str(i) + ' ' + ip + ' ' + d[2] + ' \
      ' + p + '
      \
      ' i += 1 l = custom() if(ban != 1): data = ' \ \ \
      \
      \ \
      \
      \ \
      ' if(l[2] == 0 and s == ''): data += '비 로그인 상태입니다. 비 로그인으로 작업 시 아이피가 토론에 기록됩니다.' else: data = '' return( html_minify( template('index', imp = [name, wiki_set(1), l, other2([' (토론)', 0])], data = '

      ' + sub + '

      \
      \ ' + div + ' \ ' + data, menu = [['topic/' + url_pas(name), '목록']] ) ) ) @route('/topic/', method=['POST', 'GET']) @route('/topic//', method=['GET']) def close_topic_list(name = None, tool = None): div = '' i = 0 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.forms.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.forms.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 = '
      \ (닫힘) (합의) \
      \
      \ \
      \
      \ ' rows = curs.fetchall() for data in rows: curs.execute("select data, date, ip, block from topic where title = ? and sub = ? and id = '1'", [name, data[0]]) row = curs.fetchall() if(row): 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 += '

      ' + str((i + 1)) + '. ' + data[0] + '

      ' i += 1 return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (' + sub + ')', 0])], data = '
      \ ' + div + plus + ' \
      ', menu = menu ) ) ) @route('/login', method=['POST', 'GET']) def login(): session = request.environ.get('beaker.session') agent = request.environ.get('HTTP_USER_AGENT') ip = ip_check() ban = ban_check() if(request.method == 'POST'): if(ban == 1): return(re_error('/ban')) curs.execute("select pw from user where id = ?", [request.forms.id]) user = curs.fetchall() if(user): if(session.get('Now') == 1): return(re_error('/error/11')) if(bcrypt.checkpw(bytes(request.forms.pw, 'utf-8'), bytes(user[0][0], 'utf-8'))): session['Now'] = 1 session['DREAMER'] = request.forms.id curs.execute("select css from custom where user = ?", [request.forms.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.forms.id, ip, agent, get_time()]) conn.commit() return(redirect('/user')) else: return(re_error('/error/10')) else: return(re_error('/error/5')) else: if(ban == 1): return(re_error('/ban')) if(session.get('Now') == 1): return(re_error('/error/11')) return( html_minify( template('index', imp = ['로그인', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      \
      \ \
      \
      \ 주의 : 만약 HTTPS 연결이 아닌 경우 데이터가 유출될 가능성이 있습니다. 이에 대해 책임지지 않습니다. \
      ', menu = [['user', '사용자']] ) ) ) @route('/change', method=['POST', 'GET']) def change_password(): ip = ip_check() ban = ban_check() if(request.method == 'POST'): if(request.forms.pw2 == request.forms.pw3): if(ban == 1): return(re_error('/ban')) curs.execute("select pw from user where id = ?", [request.forms.id]) user = curs.fetchall() if(user): if(re.search('(\.|:)', ip)): return(redirect('/login')) if(bcrypt.checkpw(bytes(request.forms.pw, 'utf-8'), bytes(user[0][0], 'utf-8'))): hashed = bcrypt.hashpw(bytes(request.forms.pw2, 'utf-8'), bcrypt.gensalt()) curs.execute("update user set pw = ? where id = ?", [hashed.decode(), request.forms.id]) conn.commit() return(redirect('/user')) else: return(re_error('/error/10')) else: return(re_error('/error/5')) else: return(re_error('/error/20')) else: if(ban == 1): return(re_error('/ban')) if(re.search('(\.|:)', ip)): return(redirect('/login')) return( html_minify( template('index', imp = ['비밀번호 변경', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      \
      \ \
      \
      \ \
      \
      \ \
      \
      \ 주의 : 만약 HTTPS 연결이 아닌 경우 데이터가 유출될 가능성이 있습니다. 이에 대해 책임지지 않습니다. \
      ', menu = [['user', '사용자']] ) ) ) @route('/check/') @route('/check//') def user_check(name = None, name2 = None): curs.execute("select acl from user where id = ? or id = ?", [name, name2]) user = curs.fetchall() if(user and user[0][0] != 'user'): if(admin_check(None, None) != 1): return(re_error('/error/4')) if(admin_check(4, 'check (' + name + ')') == 1): if(name2): if(re.search('(?:\.|:)', name)): if(re.search('(?:\.|:)', name2)): curs.execute("select name, ip, ua, today from ua_d where ip = ? or ip = ? order by today desc", [name, name2]) else: curs.execute("select name, ip, ua, today from ua_d where ip = ? or name = ? order by today desc", [name, name2]) else: if(re.search('(?:\.|:)', name2)): curs.execute("select name, ip, ua, today from ua_d where name = ? or ip = ? order by today desc", [name, name2]) else: curs.execute("select name, ip, ua, today from ua_d where name = ? or name = ? order by today desc", [name, name2]) 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]) row = curs.fetchall() if(row): c = ' \ \ \ \ \ \ ' for data in row: if(data[2]): ua = data[2] else: ua = '
      ' c += ' \ \ \ \ \ ' else: c += ' \
      이름아이피언제
      ' + ip_pas(data[0]) + '' + ip_pas(data[1]) + '' + data[3] + '
      ' + ua + '
      ' else: c = '' return( html_minify( template('index', imp = ['다중 검사', wiki_set(1), custom(), other2([0, 0])], data = c, menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/3')) @route('/register', method=['POST', 'GET']) def register(): ip = ip_check() ban = ban_check() if(ban == 1): return(re_error('/ban')) if(not admin_check(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('/ban')) if(request.method == 'POST'): if(request.forms.pw == request.forms.pw2): if(re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.forms.id)): return(re_error('/error/8')) if(len(request.forms.id) > 32): return(re_error('/error/7')) curs.execute("select id from user where id = ?", [request.forms.id]) rows = curs.fetchall() if(rows): return(re_error('/error/6')) hashed = bcrypt.hashpw(bytes(request.forms.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) values (?, ?, '소유자')", [request.forms.id, hashed.decode()]) else: curs.execute("insert into user (id, pw, acl) values (?, ?, 'user')", [request.forms.id, hashed.decode()]) conn.commit() return(redirect('/login')) else: return(re_error('/error/20')) else: p = '' curs.execute('select data from other where name = "contract"') d = curs.fetchall() if(d): if(d[0][0] != ''): p = d[0][0] + '

      ' return( html_minify( template('index', imp = ['회원가입', wiki_set(1), custom(), other2([0, 0])], data = '
      \ ' + p + ' \ \
      \
      \ \
      \
      \ \
      \
      \ \
      \
      \ 주의 : 만약 HTTPS 연결이 아닌 경우 데이터가 유출될 가능성이 있습니다. 이에 대해 책임지지 않습니다. \
      ', menu = [['user', '사용자']] ) ) ) @route('/logout') def logout(): session = request.environ.get('beaker.session') session['Now'] = 0 session.pop('DREAMER', None) return(redirect('/user')) @route('/ban/', method=['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(None, None) != 1): return(re_error('/error/4')) if(request.method == 'POST'): if(admin_check(1, 'ban (' + name + ')') == 1): ip = ip_check() if(request.forms.year == '09'): end = '' else: end = request.forms.year + '-' + request.forms.month + '-' + request.forms.day curs.execute("select block from ban where block = ?", [name]) row = curs.fetchall() if(row): rb_plus(name, '해제', get_time(), ip, '') curs.execute("delete from ban where block = ?", [name]) else: b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name) if(b): band_d = 'O' else: band_d = '' rb_plus(name, end, get_time(), ip, request.forms.why) curs.execute("insert into ban (block, end, why, band) values (?, ?, ?, ?)", [name, end, request.forms.why, band_d]) conn.commit() return(redirect('/ban/' + url_pas(name))) else: return(re_error('/error/3')) else: if(admin_check(1, None) == 1): curs.execute("select * from ban where block = ?", [name]) row = curs.fetchall() if(row): now = '차단 해제' data = '' else: b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name) if(b): now = '대역 차단' else: now = '차단' year_n = int("%04d" % (time.localtime().tm_year)) year = '' for i in range(year_n, year_n + 51): if(i == year_n): year += '' else: year += '' month = '' for i in range(2, 13): month += '' day = '' for i in range(2, 32): day += '' data = ' \ \ \
      \
      \ \
      \
      ' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (' + now + ')', 0])], data = '
      \ ' + data + ' \ \
      ', menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/3')) @route('/user_acl/', method=['POST', 'GET']) def acl(name = None): ip = ip_check() if(ip != name or re.search("(\.|:)", name)): return(redirect('/login')) if(request.method == 'POST'): curs.execute("select acl from data where title = ?", ['사용자:' + name]) acl_d = curs.fetchall() if(acl_d): if(request.forms.select == 'all'): curs.execute("update data set acl = 'all' where title = ?", ['사용자:' + name]) elif(request.forms.select == 'user'): curs.execute("update data set acl = 'user' where title = ?", ['사용자:' + name]) else: curs.execute("update data set acl = '' where title = ?", ['사용자:' + name]) conn.commit() return(redirect('/w/' + url_pas('사용자:' + name))) curs.execute("select acl from data where title = ?", ['사용자:' + name]) acl_d = curs.fetchall() if(acl_d): if(acl_d[0][0] == 'all'): now = '모두' elif(acl_d[0][0] == 'user'): now = '사용자' else: now = '일반' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (SET)', 0])], data = '현재 ACL : ' + now + ' \
      \
      \
      \ \
      \
      \ \
      ', menu = [['user', '사용자']] ) ) ) else: return(redirect('/w/' + url_pas(name))) @route('/acl/', method=['POST', 'GET']) def acl(name = None): if(request.method == 'POST'): if(admin_check(5, 'acl (' + name + ')') == 1): curs.execute("select acl from data where title = ?", [name]) row = curs.fetchall() if(row): if(request.forms.select == 'admin'): curs.execute("update data set acl = 'admin' where title = ?", [name]) elif(request.forms.select == 'user'): curs.execute("update data set acl = 'user' where title = ?", [name]) else: curs.execute("update data set acl = '' where title = ?", [name]) conn.commit() return(redirect('/w/' + url_pas(name))) else: return(re_error('/error/3')) else: if(admin_check(5, None) == 1): curs.execute("select acl from data where title = ?", [name]) row = curs.fetchall() if(row): if(row[0][0] == 'admin'): now = '관리자' elif(row[0][0] == 'user'): now = '사용자' else: now = '일반' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (ACL)', 0])], data = '현재 ACL : ' + now + ' \
      \
      \
      \ \
      \
      \ \
      ', menu = [['w/' + url_pas(name), '문서'], ['manager', '관리자']] ) ) ) else: return(redirect('/w/' + url_pas(name)) ) else: return(re_error('/error/3')) @route('/admin/', method=['POST', 'GET']) def user_admin(name = None): if(request.method == 'POST'): if(admin_check(None, 'admin (' + name + ')') == 1): if(request.forms.select == 'X'): curs.execute("update user set acl = 'user' where id = ?", [name]) else: curs.execute("update user set acl = ? where id = ?", [request.forms.select, name]) conn.commit() return(redirect('/admin/' + url_pas(name))) else: return(re_error('/error/3')) else: if(admin_check(None, None) == 1): curs.execute("select acl from user where id = ?", [name]) user = curs.fetchall() if(user): div = '' curs.execute('select name from alist order by name asc') get_alist = curs.fetchall() if(get_alist): i = 0 name_rem = '' for data in get_alist: if(name_rem != data[0]): name_rem = data[0] if(user[0][0] == data[0]): div += '' else: div += '' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (권한 부여)', 0])], data = '
      \ \
      \
      \ \
      ', menu = [['manager', '관리자']] ) ) ) else: return(re_error('/error/5')) else: return(re_error('/error/3')) @route('/w//r//diff/') def diff_data(name = None, a = None, b = None): curs.execute("select data from history where id = ? and title = ?", [str(a), name]) a_raw_data = curs.fetchall() if(a_raw_data): curs.execute("select data from history where id = ? and title = ?", [str(b), name]) b_raw_data = curs.fetchall() if(b_raw_data): a_data = html.escape(a_raw_data[0][0]) b_data = html.escape(b_raw_data[0][0]) if(a_data == b_data): result = '내용이 같습니다.' else: diff_data = difflib.SequenceMatcher(None, a_data, b_data) result_1 = diff(diff_data, 1) result_2 = diff(diff_data, 0) if(a_data == result_1): result = '
      ' + result_2 + '
      ' elif(b_data == result_2): result = '
      ' + result_1 + '
      ' else: result = '
      ' + result_1 + '
      ' + result_2 + '
      ' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (비교)', 0])], data = result, menu = [['history/' + url_pas(name), '역사']] ) ) ) return(redirect('/history/' + url_pas(name))) @route('/down/') def down(name = None): curs.execute("select title from data where title like ?", ['%' + name + '/%']) under = curs.fetchall() div = '
        ' i = 0 for data in under: div += '
      • ' + str(i + 1) + '. ' + data[0] + '
      • ' i += 1 div += '
      ' return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([' (하위)', 0])], data = div, menu = [['w/' + url_pas(name), '문서']] ) ) ) @route('/w/') @route('/w//r/') @route('/w//from/') def read_view(name = None, num = None, redirect = None): data_none = 0 sub = '' acl = '' div = '' topic = 0 if(not num): session = request.environ.get('beaker.session') if(session.get('View_List')): m = re.findall('([^\n]+)\n', session.get('View_List')) if(m[-1] != name): session['View_List'] += name + '\n' if(len(m) > 50): session['View_List'] = re.sub('([^\n]+)\n', '', session.get('View_List'), 1) else: session['View_List'] = name + '\n' curs.execute("select sub from rd where title = ? order by date desc", [name]) rows = curs.fetchall() for data in rows: curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]]) row = curs.fetchall() if(not row): topic = 1 break curs.execute("select title from data where title like ?", ['%' + name + '/%']) under = curs.fetchall() if(under): down = 1 else: down = 0 m = re.search("^(.*)\/(.*)$", name) if(m): uppage = m.groups()[0] else: uppage = 0 if(admin_check(5, None) == 1): admin_memu = 1 else: admin_memu = 0 if(re.search("^분류:", name)): curs.execute("delete from back where title = ? and type='cat' and link = ''", [name]) conn.commit() curs.execute("select link from back where title = ? and type='cat' order by link asc", [name]) rows = curs.fetchall() if(rows): div = '[목차(없음)]\r\n== 분류 ==\r\n' u_div = '' i = 0 for data in rows: if(re.search('^분류:', data[0])): if(u_div == ''): u_div = '=== 하위 분류 ===\r\n' u_div += ' * [[:' + data[0] + ']]\r\n' else: div += ' * [[' + data[0] + ']]\r\n' div += u_div if(num): curs.execute("select title from hidhi where title = ? and re = ?", [name, str(num)]) hid = curs.fetchall() if(hid and admin_check(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 acl, data from data where title = ?", [name]) rows = curs.fetchall() if(rows): if(not num): if(rows[0][0] == 'admin'): acl = ' (관리자)' elif(rows[0][0] == 'user'): acl = ' (사용자)' elsedata = rows[0][1] else: data_none = 1 response.status = 404 elsedata = '' 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: acl = '' if(rows): if(rows[0][0] == 'all'): acl += ' (모두)' elif(rows[0][0] == 'user'): acl += ' (사용자)' curs.execute("select block from ban where block = ?", [g[0]]) user = curs.fetchall() if(user): sub = ' (차단)' if(redirect): elsedata = re.sub("^#(?:redirect|넘겨주기) (?P[^\n]*)", " * [[\g]] 문서로 넘겨주기", elsedata) enddata = namumark(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(redirect): 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 return( html_minify( template('index', imp = [name, wiki_set(1), custom(), other2([sub + acl, r_date])], data = enddata + namumark(name, div, 0, 0, 0), menu = menu ) ) ) @route('/user//topic') @route('/user//topic/') def user_topic_list(name = None, num = 1): if(num * 50 <= 0): v = 50 else: v = num * 50 i = v - 50 ydmin = admin_check(1, None) div = ' \ \ \ \ \ \ ' div = '(기여 기록)

      ' + div curs.execute("select title, id, sub, ip, date from topic where ip = ? order by date desc limit ?, ?", [name, str(i), str(v)]) rows = curs.fetchall() if(rows): for data in rows: title = html.escape(data[0]) sub = html.escape(data[2]) if(ydmin == 1): curs.execute("select * from ban where block = ?", [data[3]]) row = curs.fetchall() if(row): ban = ' (해제)' else: ban = ' (차단)' else: ban = '' ip = ip_pas(data[3]) div += ' \ \ \ \ ' else: div += ' \
      토론명작성자시간
      \ ' + title + '#' + data[1] + ' (' + sub + ') \ ' + ip + ban + '' + data[4] + '
      ' else: div = '' div += '
      (이전) (이후)' curs.execute("select end, why from ban where block = ?", [name]) ban_it = curs.fetchall() if(ban_it): sub = ' (차단)' else: sub = 0 return( html_minify( template('index', imp = ['토론 기록', wiki_set(1), custom(), other2([sub, 0])], data = div, menu = [['other', '기타'], ['user', '사용자']] ) ) ) @route('/upload', method=['GET', 'POST']) def upload(): if(ban_check() == 1): return(re_error('/ban')) if(request.method == 'POST'): data = request.files.f_data if(data): if(int(wiki_set(3)) * 1024 * 1024 < request.content_length): return re_error('/error/17') value = os.path.splitext(data.filename)[1] if(not value in ['.jpeg', '.jpg', '.gif', '.png', '.webp', '.JPEG', '.JPG', '.GIF', '.PNG', '.WEBP']): return re_error('/error/14') if(request.forms.get('f_name')): name = request.forms.get('f_name') + value else: name = data.filename piece = os.path.splitext(name) e_data = sha224(piece[0]) + piece[1] ip = ip_check() if(request.forms.get('f_lice')): lice = request.forms.get('f_lice') else: if(re.search('(?:\.|:)', ip)): lice = ip + ' 올림' else: lice = '[[사용자:' + ip + ']] 올림' if(os.path.exists(os.path.join('image', e_data))): return(re_error('/error/16')) data.save(os.path.join('image', e_data)) curs.execute("select title from data where title = ?", ['파일:' + name]) exist = curs.fetchall() if(exist): curs.execute("delete from data where title = ?", ['파일:' + name]) curs.execute("insert into data (title, data, acl) values (?, ?, 'admin')", ['파일:' + name, '[[파일:' + name + ']][br][br]{{{[[파일:' + name + ']]}}}[br][br]' + lice]) conn.commit() history_plus( '파일:' + name, '[[파일:' + name + ']][br][br]{{{[[파일:' + name + ']]}}}[br][br]' + lice, get_time(), ip, '(파일 올림)', '0' ) return(redirect('/w/파일:' + name)) else: return(re_error('/error/9')) else: return( html_minify( template('index', imp = ['파일 올리기', wiki_set(1), custom(), other2([0, 0])], data = '
      \ \
      \
      \ \
      \
      \ \
      \
      \ 한글이 되지 않을 때도 있습니다. \
      \
      \ \
      ', menu = [['other', '기타']] ) ) ) @route('/user') def user_info(): ip = ip_check() raw_ip = ip curs.execute("select acl from user where id = ?", [ip]) rows = curs.fetchall() if(ban_check() == 0): if(rows): if(rows[0][0] != 'user'): acl = rows[0][0] else: acl = '사용자' else: acl = '일반' else: acl = '차단' ip = ip_pas(ip) l = custom() if(l[2] != 0): plus = ' * [[wiki:logout|로그아웃]]\r\n * [[wiki:change|비밀번호 변경]]' else: plus = ' * [[wiki:login|로그인]]' return( html_minify( template('index', imp = ['사용자 메뉴', wiki_set(1), l, other2([0, 0])], data = ip + '

      ' + namumark('', '권한 상태 : ' + acl + '\r\n' + \ '[목차(없음)]\r\n' + \ '== 로그인 ==\r\n' + \ plus + '\r\n' + \ ' * [[wiki:register|회원가입]]\r\n' + \ '== 사용자 ==\r\n' + \ ' * [[wiki:user_acl/' + url_pas(raw_ip) + '|사용자 문서 ACL]]\r\n' + \ ' * [[wiki:custom_css|사용자 CSS]]\r\n' + \ ' * [[wiki:custom_js|사용자 JS]]\r\n' + \ '== 기타 ==\r\n' + \ ' * [[wiki:alarm|알림]]\r\n' + \ ' * [[wiki:view_log|지나온 문서]]\r\n' + \ ' * [[wiki:count|기여 횟수]]\r\n', 0, 0, 0), menu = 0 ) ) ) @route('/view_log') def view_log(): session = request.environ.get('beaker.session') data = '
        ' if(session.get('View_List')): data += '
      • 최근 50개


      • ' m = re.findall('([^\n]+)\n', session.get('View_List')) for d in m: data += '
      • ' + d + '
      • ' else: data += '
      • 기록 없음
      • ' data += '
      ' return( html_minify( template('index', imp = ['지나온 문서', wiki_set(1), custom(), other2([0, 0])], data = data, menu = [['user', '사용자']] ) ) ) @route('/custom_css', method=['GET', 'POST']) def custom_css_view(): session = request.environ.get('beaker.session') ip = ip_check() if(request.method == 'POST'): if(not re.search('(\.|:)', ip)): curs.execute("select * from custom where user = ?", [ip]) css_data = curs.fetchall() if(css_data): curs.execute("update custom set css = ? where user = ?", [request.forms.content, ip]) else: curs.execute("insert into custom (user, css) values (?, ?)", [ip, request.forms.content]) conn.commit() session['Daydream'] = request.forms.content return(redirect('/user')) else: if(not re.search('(\.|:)', ip)): start = '' curs.execute("select css from custom where user = ?", [ip]) css_data = curs.fetchall() if(css_data): data = css_data[0][0] else: data = '' else: start = '비 로그인의 경우에는 로그인하면 날아갑니다.

      ' try: data = session['Daydream'] except: data = '' return( html_minify( template('index', imp = ['사용자 CSS', wiki_set(1), custom(), other2([0, 0])], data = start + ' \
      \ \
      \
      \
      \ \
      \
      ', menu = [['user', '사용자']] ) ) ) @route('/custom_js', method=['GET', 'POST']) def custom_js_view(): session = request.environ.get('beaker.session') ip = ip_check() if(request.method == 'POST'): if(not re.search('(\.|:)', ip)): curs.execute("select * from custom where user = ?", [ip + ' (js)']) js_data = curs.fetchall() if(js_data): curs.execute("update custom set css = ? where user = ?", [request.forms.content, ip + ' (js)']) else: curs.execute("insert into custom (user, css) values (?, ?)", [ip + ' (js)', request.forms.content]) conn.commit() session['AQUARIUM'] = request.forms.content return(redirect('/user')) else: if(not re.search('(\.|:)', ip)): start = '' curs.execute("select css from custom where user = ?", [ip + ' (js)']) js_data = curs.fetchall() if(js_data): data = js_data[0][0] else: data = '' else: start = '비 로그인의 경우에는 로그인하면 날아갑니다.

      ' try: data = session['AQUARIUM'] except: data = '' return( html_minify( template('index', imp = ['사용자 JS', wiki_set(1), custom(), other2([0, 0])], data = start + ' \
      \ \
      \
      \
      \ \
      \
      ', menu = [['user', '사용자']] ) ) ) @route('/count') @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( template('index', imp = ['기여 횟수', wiki_set(1), custom(), other2([0, 0])], data = namumark("", "||<-2><:> " + that + " ||\r\n||<:> 기여 횟수 ||<:> " + str(data) + "||\r\n||<:> 토론 횟수 ||<:> " + str(t_data) + "||", 0, 0, 0), menu = [['user', '사용자']] ) ) ) @route('/random') def random(): curs.execute("select title from data order by random() limit 1") rows = curs.fetchall() if(rows): return(redirect('/w/' + url_pas(rows[0][0]))) else: return(redirect('/')) @route('/views/') def views(name = None): if(re.search('\/', name)): m = re.search('^(.*)\/(.*)$', name) if(m): n = m.groups() plus = '/' + n[0] rename = n[1] else: plus = '' rename = name else: plus = '' rename = name return( static_file(rename, root = './views' + plus ) ) @error(404) def error_404(error): try: curs.execute("select title from data limit 1") return(redirect('/w/' + url_pas(wiki_set(2)))) except: return(redirect('/setup')) @error(500) def error_500(error): try: curs.execute("select title from data limit 1") return(error) except: return(redirect('/setup')) run( app = app, server = 'tornado', host = '0.0.0.0', port = int(set_data['port']) )