Procházet zdrojové kódy

Merge pull request #450 from 2DU/master

Master
Surplus_Up (2DU) před 8 roky
rodič
revize
ced0063864
5 změnil soubory, kde provedl 159 přidání a 72 odebrání
  1. 1 1
      .gitignore
  2. 20 10
      ISSUE_TEMPLATE.md
  3. 101 49
      app.py
  4. 1 1
      requirements.txt
  5. 36 11
      set_mark/start.py

+ 1 - 1
.gitignore

@@ -15,4 +15,4 @@ views/liberty
 views/yousoro
 views/super_lite
 views/buma
-views/senkawa_memories
+views/before_namu

+ 20 - 10
ISSUE_TEMPLATE.md

@@ -1,20 +1,30 @@
 ## 설명
-[해당 이슈 자체에 대한 자세한 설명을 작성해주세요]
+<!-- 해당 이슈에 대한 자세한 설명을 작성해주세요.
+
+예시: 로그아웃 직후 로그인 시 로그인이 되지 않습니다. -->
 
 ## 과정
-[해당 이슈를 발생시킬 과정을 간략하게 나열해주세요]
+<!-- 해당 이슈를 발생한 당시의 행동을 최대한 자세하게 나열해주세요.
+
+예시:
+1. 로그인 버튼을 눌러 로그인을 합니다.
+2. 로그아웃 버튼을 눌러 로그아웃을 합니다.
+3. 다시 로그인 버튼을 눌러 로그인을 합니다. -->
+
+## 정상 동작 시의 결과
+<!-- 이 과정을 통해 얻어야할 결과가 무엇인가요? 
 
-## 예상 결과
-[이 과정에서 얻어야할 결과가 무엇인가요?]
+예시: 로그인이 되어야 합니다. -->
 
 ## 현재 결과
-[이 과정에서 겪은 이슈를 설명해주세요]
+<!-- 이 과정을 통해 얻은 결과를 설명해주세요.
 
-## Fix 요청
-[의무 사항은 아니지만 버그 수정 또는 버그 제안]
+예시: 로그인이 되지 않습니다. -->
 
-* "OO을 입니다." 의 텍스트 문구를 "OO는 입니다." 로 변경해주세요. (Example)
+## 스크린샷
+<!-- 오류가 발생한 스크린샷을 최소 한장 이상 첨부해주세요. -->
 
-## 문제되는 이슈의 스크린샷 또는 코드
-[관련이 있는 스크린샷] or [관련 코드]
+## 수정 되어야 할 부분
+<!-- 만약 수정되어야 할 부분이나 해결 방법을 아신다면 기재해주세요.
 
+예시: 만약 로그아웃 페이지에서 로그인을 할 경우 대문 페이지로 이동시켜면 될 것 같습니다. -->

+ 101 - 49
app.py

@@ -7,7 +7,10 @@ from tornado.wsgi import WSGIContainer
 from tornado.httpserver import HTTPServer
 from tornado.ioloop import IOLoop
 
+import urllib.request
+
 import platform
+import zipfile
 import bcrypt
 import difflib
 import shutil
@@ -17,7 +20,7 @@ import random
 import sys
 
 # 버전 표기
-r_ver = 'v3.0.3'
+r_ver = 'v3.0.4-Beta-03'
 print('Version : ' + r_ver)
 
 # 나머지 불러오기
@@ -84,6 +87,7 @@ curs.execute("create table if not exists filter(name text, regex text, sub text)
 curs.execute("create table if not exists scan(user text, title text)")
 curs.execute("create table if not exists acl(title text, dec text, dis text, why text)")
 curs.execute("create table if not exists inter(title text, link text)")
+curs.execute("create table if not exists html_filter(html text)")
 
 # owner 존재 확인
 curs.execute("select name from alist where acl = 'owner'")
@@ -317,61 +321,93 @@ def alarm():
         menu = [['user', lang_data['user']]]
     ))
 
-@app.route('/inter_wiki')
-def inter_wiki():
+@app.route('/<regex("inter_wiki|html_filter"):tools>')
+def inter_wiki(tools = None):
     div = ''
     admin = admin_check(conn, None, None)
 
-    curs.execute('select title, link from inter')
+    if tools == 'inter_wiki':
+        del_link = 'del_inter_wiki'
+        plus_link = 'plus_inter_wiki'
+        title = '인터위키 ' + lang_data['list']
+        div = ''
+
+        curs.execute('select title, link from inter')
+    else:
+        del_link = 'del_html_filter'
+        plus_link = 'plus_html_filter'
+        title = 'HTML 필터 ' + lang_data['list']
+        div = '<ul><li>span</li><li>div</li><li>iframe</li></ul>'
+
+        curs.execute('select html from html_filter')
+
     db_data = curs.fetchall()
     if db_data:
-        div = '<ul>'
+        div += '<ul>'
 
         for data in db_data:
-            div += '<li>' + data[0] + ' : ' + data[1]
+            if tools == 'inter_wiki':
+                div += '<li>' + data[0] + ' : <a id="out_link" href="' + data[1] + '">' + data[1] + '</a>'
+            else:
+                div += '<li>' + data[0]
 
             if admin == 1:
-                div += ' <a href="/del_inter/' + url_pas(data[0]) + '">(' + lang_data['delete'] + ')</a>'
+                div += ' <a href="/' + del_link + '/' + url_pas(data[0]) + '">(' + lang_data['delete'] + ')</a>'
 
             div += '</li>'
 
         div += '</ul>'
 
         if admin == 1:
-            div += '<hr><a href="/plus_inter">(추가)</a>'
+            div += '<hr><a href="/' + plus_link + '">(' + lang_data['plus'] + ')</a>'
     else:
         if admin == 1:
-            div += '<a href="/plus_inter">(추가)</a>'
+            div += '<a href="/' + plus_link + '">(' + lang_data['plus'] + ')</a>'
 
     return html_minify(render_template(skin_check(conn), 
-        imp = ['인터위키 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
+        imp = [title, wiki_set(conn, 1), custom(conn), other2([0, 0])],
         data = div,
         menu = [['other', '기타']]
     ))
 
-@app.route('/del_inter/<name>')
-def del_inter(name = None):
+@app.route('/<regex("del_(inter_wiki|html_filter)"):tools>/<name>')
+def del_inter(tools = None, name = None):
     if admin_check(conn, None, None) == 1:
-        curs.execute("delete from inter where title = ?", [name])
+        if tools == 'del_inter_wiki':
+            curs.execute("delete from inter where title = ?", [name])
+        else:
+            curs.execute("delete from html_filter where html = ?", [name])
+        
         conn.commit()
 
-        return redirect('/inter_wiki')
+        return redirect('/' + re.sub('^del_', '', tools))
     else:
         return re_error(conn, '/error/3')
 
-@app.route('/plus_inter', methods=['POST', 'GET'])
-def plus_inter():
+@app.route('/<regex("plus_(inter_wiki|html_filter)"):tools>', methods=['POST', 'GET'])
+def plus_inter(tools = None):
     if request.method == 'POST':
-        curs.execute('insert into inter (title, link) values (?, ?)', [request.form.get('title', None), request.form.get('link', None)])
+        if tools == 'plus_inter_wiki':
+            curs.execute('insert into inter (title, link) values (?, ?)', [request.form.get('title', None), request.form.get('link', None)])
+        else:
+            curs.execute('insert into html_filter (html) values (?)', [request.form.get('title', None)])
+        
         conn.commit()
         
         admin_check(conn, None, 'inter_wiki_plus')
     
-        return redirect('/inter_wiki')
+        return redirect('/' + re.sub('^plus_', '', tools))
     else:
+        if tools == 'plus_inter_wiki':
+            title = '인터위키 ' + lang_data['plus']
+            form_data = '<input placeholder="이름" type="text" name="title"><hr><input placeholder="링크" type="text" name="link">'
+        else:
+            title = 'HTML 필터 ' + lang_data['plus']
+            form_data = '<input placeholder="HTML" type="text" name="title">'
+
         return html_minify(render_template(skin_check(conn), 
-            imp = ['인터위키 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data = '<form method="post"><input placeholder="이름" type="text" name="title"><hr><input placeholder="링크" type="text" name="link"><hr><button type="submit">추가</button></form>',
+            imp = [title, wiki_set(conn, 1), custom(conn), other2([0, 0])],
+            data = '<form method="post">' + form_data + '<hr><button type="submit">' + lang_data['plus'] + '</button></form>',
             menu = [['other', '기타']]
         ))
 
@@ -464,7 +500,7 @@ def edit_set(num = 0):
 
             return html_minify(render_template(skin_check(conn), 
                 imp = ['기본 설정', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-                data = '<form method="post"><span>이름</span><br><br><input placeholder="이름" type="text" name="name" value="' + html.escape(d_list[0]) + '"><hr><span>로고 (HTML)</span><br><br><input placeholder="로고" type="text" name="logo" value="' + html.escape(d_list[1]) + '"><hr><span>대문</span><br><br><input placeholder="대문" type="text" name="frontpage" value="' + html.escape(d_list[2]) + '"><hr><span>라이선스 (HTML)</span><br><br><input placeholder="라이선스" type="text" name="license" value="' + html.escape(d_list[3]) + '"><hr><span>파일 크기 [메가]</span><br><br><input placeholder="파일 크기" type="text" name="upload" value="' + html.escape(d_list[4]) + '"><hr><span>백업 간격 [시간] (끄기 : 0) {재시작 필요}</span><br><br><input placeholder="백업 간격" type="text" name="back_up" value="' + html.escape(d_list[9]) + '"><hr><span>스킨</span><br><br><select name="skin">' + div2 + '</select><hr><span>전역 ACL</span><br><br><select name="edit">' + div + '</select><hr><input type="checkbox" name="reg" ' + ch_1 + '> 가입불가<hr><input type="checkbox" name="ip_view" ' + ch_2 + '> 아이피 비공개<hr><button id="save" type="submit">저장</button></form>',
+                data = '<form method="post"><span>이름</span><br><br><input placeholder="이름" type="text" name="name" value="' + html.escape(d_list[0]) + '"><hr><span>로고 (HTML)</span><br><br><input placeholder="로고" type="text" name="logo" value="' + html.escape(d_list[1]) + '"><hr><span>대문</span><br><br><input placeholder="대문" type="text" name="frontpage" value="' + html.escape(d_list[2]) + '"><hr><span>라이선스 (HTML)</span><br><br><input placeholder="라이선스" type="text" name="license" value="' + html.escape(d_list[3]) + '"><hr><span>파일 크기 [메가]</span><br><br><input placeholder="파일 크기" type="text" name="upload" value="' + html.escape(d_list[4]) + '"><hr><span>백업 간격 [시간] (끄기 : 0) {재시작 필요}</span><br><br><input placeholder="백업 간격" type="text" name="back_up" value="' + html.escape(d_list[9]) + '"><hr><span>스킨</span><br><br><select name="skin">' + div2 + '</select><hr><span>전역 ACL</span><br><br><select name="edit">' + div + '</select><hr><input type="checkbox" name="reg" ' + ch_1 + '> 가입불가<hr><input type="checkbox" name="ip_view" ' + ch_2 + '> 아이피 비공개<hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
                 menu = [['edit_set', '설정']]
             ))
     elif num == 2:
@@ -499,7 +535,7 @@ def edit_set(num = 0):
 
             return html_minify(render_template(skin_check(conn), 
                 imp = ['문구 관련', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-                data = '<form method="post"><span>가입 약관</span><br><br><input placeholder="가입 약관" type="text" name="contract" value="' + html.escape(d_list[0]) + '"><hr><span>비 ' + lang_data['login'] + ' 경고</span><br><br><input placeholder="비 ' + lang_data['login'] + ' 경고" type="text" name="no_login_warring" value="' + html.escape(d_list[1]) + '"><hr><button id="save" type="submit">저장</button></form>',
+                data = '<form method="post"><span>가입 약관</span><br><br><input placeholder="가입 약관" type="text" name="contract" value="' + html.escape(d_list[0]) + '"><hr><span>비 ' + lang_data['login'] + ' 경고</span><br><br><input placeholder="비 ' + lang_data['login'] + ' 경고" type="text" name="no_login_warring" value="' + html.escape(d_list[1]) + '"><hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
                 menu = [['edit_set', '설정']]
             ))
     elif num == 3:
@@ -525,7 +561,7 @@ def edit_set(num = 0):
 
             return html_minify(render_template(skin_check(conn), 
                 imp = ['전역 HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-                data =  '<span>&lt;style&gt;CSS&lt;/style&gt;<br>&lt;script&gt;JS&lt;/script&gt;</span><hr><form method="post"><textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr><button id="save" type="submit">저장</button></form>',
+                data =  '<span>&lt;style&gt;CSS&lt;/style&gt;<br>&lt;script&gt;JS&lt;/script&gt;</span><hr><form method="post"><textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
                 menu = [['edit_set', '설정']]
             ))
     elif num == 4:
@@ -562,7 +598,7 @@ def edit_set(num = 0):
 
             return html_minify(render_template(skin_check(conn), 
                 imp = ['robots.txt', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-                data =  '<a href="/robots.txt">(보기)</a><hr><form method="post"><textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr><button id="save" type="submit">저장</button></form>',
+                data =  '<a href="/robots.txt">(보기)</a><hr><form method="post"><textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
                 menu = [['edit_set', '설정']]
             ))
     elif num == 5:
@@ -597,7 +633,7 @@ def edit_set(num = 0):
 
             return html_minify(render_template(skin_check(conn), 
                 imp = ['구글 관련', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-                data = '<form method="post"><span>리캡차 (HTML)</span><br><br><input placeholder="리캡차 (HTML)" type="text" name="recaptcha" value="' + html.escape(d_list[0]) + '"><hr><span>리캡차 (비밀키)</span><br><br><input placeholder="리캡차 (비밀키)" type="text" name="sec_re" value="' + html.escape(d_list[1]) + '"><hr><button id="save" type="submit">저장</button></form>',
+                data = '<form method="post"><span>리캡차 (HTML)</span><br><br><input placeholder="리캡차 (HTML)" type="text" name="recaptcha" value="' + html.escape(d_list[0]) + '"><hr><span>리캡차 (비밀키)</span><br><br><input placeholder="리캡차 (비밀키)" type="text" name="sec_re" value="' + html.escape(d_list[1]) + '"><hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
                 menu = [['edit_set', '설정']]
             ))
     else:
@@ -728,8 +764,8 @@ def admin_plus(name = None):
         data += '<li><input type="checkbox" ' + state +  ' name="owner" ' + exist_list[7] + '> ' + lang_data['owner'] + '</li></ul>'
 
         return html_minify(render_template(skin_check(conn), 
-            imp = [lang_data['admin_group'] + ' 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data = '<form method="post">' + data + '<hr><button id="save" ' + state +  ' type="submit">저장</button></form>',
+            imp = [lang_data['admin_group'] + ' ' + lang_data['plus'] + '', wiki_set(conn, 1), custom(conn), other2([0, 0])],
+            data = '<form method="post">' + data + '<hr><button id="save" ' + state +  ' type="submit">' + lang_data['save'] + '</button></form>',
             menu = [['manager', lang_data['admin']]]
         ))        
         
@@ -918,7 +954,7 @@ def re_start():
 @app.route('/update')
 def update():
     if admin_check(conn, None, 'update') != 1:
-        return re_error(conn, '/error/3')
+       return re_error(conn, '/error/3')
 
     if platform.system() == 'Linux':
         print('')
@@ -926,10 +962,25 @@ def update():
 
         ok = os.system('git pull')
         if ok == 0:
-            print('Re Start')
+            return redirect('/re_start')
+    else:
+        if platform.system() == 'Windows':
             print('')
+            print('Download')
 
-            os.execl(sys.executable, sys.executable, *sys.argv)
+            urllib.request.urlretrieve('https://github.com/2DU/openNAMU/archive/stable.zip', 'update.zip')
+
+            print('Zip Extract')
+            zipfile.ZipFile('update.zip').extractall('')
+
+            print('Move')
+            ok = os.system('xcopy /y /r openNAMU-stable .')
+            if ok == 0:
+                print('Remove')
+                os.system('rd /s /q openNAMU-stable')
+                os.system('del update.zip')
+
+                return redirect('/re_start')
 
     return html_minify(render_template(skin_check(conn), 
         imp = ['업데이트', wiki_set(conn, 1), custom(conn), other2([0, 0])],
@@ -1356,9 +1407,9 @@ def edit_filter():
     div += '</ul>'
 
     if data:
-        div += '<hr><a href="/manager/9">(추가)</a>'
+        div += '<hr><a href="/manager/9">(' + lang_data['plus'] + ')</a>'
     else:
-        div = '<a href="/manager/9">(추가)</a>'
+        div = '<a href="/manager/9">(' + lang_data['plus'] + ')</a>'
 
     return html_minify(render_template(skin_check(conn), 
         imp = [lang_data['edit_filter'] + ' ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
@@ -1417,7 +1468,7 @@ def set_edit_filter(name = None):
 
         return html_minify(render_template(skin_check(conn), 
             imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + lang_data['edit_filter'] + ')', 0])],
-            data = '<form method="post"><input ' + stat + ' type="checkbox" ' + time_data + ' name="ban"> ' + lang_data['ban'] + '<hr><input ' + stat + ' placeholder="정규식" name="content" value="' + html.escape(textarea) + '" type="text"><hr><button ' + stat + ' id="save" type="submit">저장</button></form>',
+            data = '<form method="post"><input ' + stat + ' type="checkbox" ' + time_data + ' name="ban"> ' + lang_data['ban'] + '<hr><input ' + stat + ' placeholder="정규식" name="content" value="' + html.escape(textarea) + '" type="text"><hr><button ' + stat + ' id="save" type="submit">' + lang_data['save'] + '</button></form>',
             menu = [['edit_filter', lang_data['list']], ['edit_filter/' + url_pas(name) + '/delete', lang_data['delete']]]
         ))
 
@@ -1556,7 +1607,7 @@ def edit(name = None):
 
         return html_minify(render_template(skin_check(conn), 
             imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + lang_data['edit'] + ')', 0])],
-            data = get_name + js + '<form method="post" action="/edit/' + url_pas(name) + action + '">' + js_button + '<hr><textarea id="content" rows="25" name="content">' + html.escape(re.sub('\n$', '', data)) + '</textarea><textarea style="display: none;" name="otent">' + html.escape(re.sub('\n$', '', data_old)) + '</textarea><hr><input placeholder="사유" name="send" type="text"><hr>' + captcha_get(conn) + ip_warring(conn) + '<button id="save" type="submit">저장</button><button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">미리보기</button></form>',
+            data = get_name + js + '<form method="post" action="/edit/' + url_pas(name) + action + '">' + js_button + '<hr><textarea id="content" rows="25" name="content">' + html.escape(re.sub('\n$', '', data)) + '</textarea><textarea style="display: none;" name="otent">' + html.escape(re.sub('\n$', '', data_old)) + '</textarea><hr><input placeholder="사유" name="send" type="text"><hr>' + captcha_get(conn) + ip_warring(conn) + '<button id="save" type="submit">' + lang_data['save'] + '</button><button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">미리보기</button></form>',
             menu = [['w/' + url_pas(name), lang_data['document']], ['delete/' + url_pas(name), lang_data['delete']], ['move/' + url_pas(name), lang_data['move']]]
         ))
         
@@ -1588,7 +1639,7 @@ def preview(name = None):
     
     return html_minify(render_template(skin_check(conn), 
         imp = [name, wiki_set(conn, 1), custom(conn), other2([' (미리보기)', 0])],
-        data = js + '<form method="post" action="/edit/' + url_pas(name) + action + '">' + js_button + '<hr><textarea id="content" rows="25" name="content">' + html.escape(request.form.get('content', None)) + '</textarea><textarea style="display: none;" name="otent">' + html.escape(request.form.get('otent', None)) + '</textarea><hr><input placeholder="사유" name="send" type="text"><hr>' + captcha_get(conn) + '<button id="save" type="submit">저장</button><button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">미리보기</button></form><hr>' + end_data,
+        data = js + '<form method="post" action="/edit/' + url_pas(name) + action + '">' + js_button + '<hr><textarea id="content" rows="25" name="content">' + html.escape(request.form.get('content', None)) + '</textarea><textarea style="display: none;" name="otent">' + html.escape(request.form.get('otent', None)) + '</textarea><hr><input placeholder="사유" name="send" type="text"><hr>' + captcha_get(conn) + '<button id="save" type="submit">' + lang_data['save'] + '</button><button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">미리보기</button></form><hr>' + end_data,
         menu = [['w/' + url_pas(name), lang_data['document']]]
     ))
         
@@ -1701,19 +1752,19 @@ def move(name = None):
 def other():
     return html_minify(render_template(skin_check(conn), 
         imp = ['기타 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
-        data = '<h2>기록</h2><ul><li><a href="/manager/6">편집 기록</a></li><li><a href="/manager/7">토론 기록</a></li></ul><br><h2>' + lang_data['list'] + '</h2><ul><li><a href="/admin_list">' + lang_data['admin'] + '</a></li><li><a href="/give_log">' + lang_data['admin_group'] + '</a></li><li><a href="/not_close_topic">열린 토론</a></li></ul><br><h2>기타</h2><ul><li><a href="/title_index">' + lang_data['all'] + ' ' + lang_data['document'] + '</a></li><li><a href="/acl_list">ACL 문서</a></li><li><a href="/please">필요한 문서</a></li><li><a href="/upload">파일 올리기</a></li><li><a href="/manager/10">문서 검색</a></li></ul><br><h2>' + lang_data['admin'] + '</h2><ul><li><a href="/manager/1">' + lang_data['admin'] + ' ' + lang_data['list'] + '</a></li></ul><br><h2>버전</h2><ul><li>이 오픈나무는 <a href="https://github.com/2DU/openNAMU/blob/master/version.md">' + r_ver + '</a> 입니다.</li></ul>',
+        data = '<h2>기록</h2><ul><li><a href="/manager/6">편집 기록</a></li><li><a href="/manager/7">토론 기록</a></li></ul><br><h2>' + lang_data['list'] + '</h2><ul><li><a href="/admin_list">' + lang_data['admin'] + '</a></li><li><a href="/give_log">' + lang_data['admin_group'] + '</a></li><li><a href="/not_close_topic">열린 토론</a></li></ul><br><h2>기타</h2><ul><li><a href="/title_index">' + lang_data['all'] + ' ' + lang_data['document'] + '</a></li><li><a href="/acl_list">ACL 문서</a></li><li><a href="/please">필요한 문서</a></li><li><a href="/upload">파일 올리기</a></li><li><a href="/manager/10">문서 검색</a></li></ul><br><h2>' + lang_data['admin'] + '</h2><ul><li><a href="/manager/1">' + lang_data['admin'] + ' ' + lang_data['tool'] + '</a></li></ul><br><h2>버전</h2><ul><li>이 오픈나무는 <a id="out_link" href="https://github.com/2DU/openNAMU/blob/master/version.md">' + r_ver + '</a> 입니다.</li></ul>',
         menu = 0
     ))
     
 @app.route('/manager', methods=['POST', 'GET'])
 @app.route('/manager/<int:num>', methods=['POST', 'GET'])
 def manager(num = 1):
-    title_list = [[lang_data['document'] + ' ACL', '문서명', 'acl'], [lang_data['user'] + ' 검사', 0, 'check'], [lang_data['user'] + ' ' + lang_data['ban'], 0, 'ban'], ['권한 주기', 0, 'admin'], ['편집 기록', 0, 'record'], ['토론 기록', 0, 'topic_record'], ['그룹 생성', '그룹명', 'admin_plus'], [lang_data['edit_filter'] + ' 생성', '필터명', 'edit_filter'], ['검색', '문서명', 'search'], ['차단자 검색', 0, 'block_user'], [lang_data['admin'] + ' 검색', 0, 'block_admin'], ['주시 문서 추가', '문서명', 'watch_list']]
+    title_list = [[lang_data['document'] + ' ACL', '문서명', 'acl'], [lang_data['user'] + ' 검사', 0, 'check'], [lang_data['user'] + ' ' + lang_data['ban'], 0, 'ban'], ['권한 주기', 0, 'admin'], ['편집 기록', 0, 'record'], ['토론 기록', 0, 'topic_record'], ['그룹 생성', '그룹명', 'admin_plus'], [lang_data['edit_filter'] + ' 생성', '필터명', 'edit_filter'], ['검색', '문서명', 'search'], ['차단자 검색', 0, 'block_user'], [lang_data['admin'] + ' 검색', 0, 'block_admin'], ['주시 문서 ' + lang_data['plus'] + '', '문서명', 'watch_list']]
     
     if num == 1:
         return html_minify(render_template(skin_check(conn), 
-            imp = [lang_data['admin'] + ' ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data = '<h2>' + lang_data['list'] + '</h2><ul><li><a href="/manager/2">' + lang_data['document'] + ' ACL</a></li><li><a href="/manager/3">' + lang_data['user'] + ' 검사</a></li><li><a href="/manager/4">' + lang_data['user'] + ' ' + lang_data['ban'] + '</a></li><li><a href="/manager/5">권한 주기</a></li><li><a href="/big_delete">' + lang_data['bulk_delete'] + '</a></li><li><a href="/edit_filter">' + lang_data['edit_filter'] + '</a></li></ul><br><h2>' + lang_data['owner'] + '</h2><ul><li><a href="/indexing">인덱싱 (생성 or ' + lang_data['delete'] + ')</a></li><li><a href="/manager/8">' + lang_data['admin_group'] + ' 생성</a></li><li><a href="/edit_set">설정 편집</a></li><li><a href="/re_start">서버 재 시작</a></li><li><a href="/update">업데이트 (Git 사용)</a></li><li><a href="/inter_wiki">인터위키</a></li></ul>',
+            imp = [lang_data['admin'] + ' ' + lang_data['tool'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
+            data = '<h2>' + lang_data['list'] + '</h2><ul><li><a href="/manager/2">' + lang_data['document'] + ' ACL</a></li><li><a href="/manager/3">' + lang_data['user'] + ' 검사</a></li><li><a href="/manager/4">' + lang_data['user'] + ' ' + lang_data['ban'] + '</a></li><li><a href="/manager/5">권한 주기</a></li><li><a href="/big_delete">' + lang_data['bulk_delete'] + '</a></li><li><a href="/edit_filter">' + lang_data['edit_filter'] + '</a></li></ul><br><h2>' + lang_data['owner'] + '</h2><ul><li><a href="/indexing">인덱싱 (생성 or ' + lang_data['delete'] + ')</a></li><li><a href="/manager/8">' + lang_data['admin_group'] + ' 생성</a></li><li><a href="/edit_set">설정 편집</a></li><li><a href="/re_start">서버 재 시작</a></li><li><a href="/update">업데이트</a></li><li><a href="/inter_wiki">인터위키</a></li></ul>',
             menu = [['other', '기타']]
         ))
     elif num in range(2, 14):
@@ -2335,7 +2386,7 @@ def plus_check(name):
         return redirect('/check/' + url_pas(name) + '?plus=' + url_pas(request.form.get('name2', None)))
     else:
         return html_minify(render_template(skin_check(conn),
-            imp = ['대상 추가', wiki_set(conn, 1), custom(conn), other2([0, 0])],
+            imp = ['대상 ' + lang_data['plus'] + '', wiki_set(conn, 1), custom(conn), other2([0, 0])],
             data = '<form method="post"><input placeholder="비교 대상" name="name2" type="text"><hr><button type="submit">' + lang_data['move'] + '</button></form>',
             menu = [['manager', lang_data['admin']]]
         ))
@@ -2513,14 +2564,15 @@ def acl(name = None):
     
     user_data = re.search('^' + lang_data['user'] + ':(.+)$', name)
     if user_data:
-        if custom(conn)[2] == 0:
+        if check_data and custom(conn)[2] == 0:
             return redirect('/login')
-        elif user_data.groups()[0] != ip_check():
+        
+        if user_data.groups()[0] != ip_check():
             if admin_check(conn, 5, check_data) != 1:
                 if check_data:
                     return re_error(conn, '/error/3')
                 else:
-                    check_ok = 'disable'
+                    check_ok = 'disabled'
     else:
         if admin_check(conn, 5, check_data) != 1:
             if check_data:
@@ -2707,7 +2759,7 @@ def read_view(name = None):
     for data in curs.fetchall():
         curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
         if not curs.fetchall():
-            sub += ' (토론)'
+            sub += ' (D)'
 
             break
                 
@@ -2779,7 +2831,7 @@ def read_view(name = None):
         response_data = 404
         else_data = ''
 
-    m = re.search("^' + lang_data['user'] + ':([^/]*)", name)
+    m = re.search("^" + lang_data['user'] + ":([^/]*)", name)
     if m:
         g = m.groups()
         
@@ -2797,7 +2849,7 @@ def read_view(name = None):
     curs.execute("select dec from acl where title = ?", [name])
     data = curs.fetchall()
     if data:
-        acl += ' (ACL)'
+        acl += ' (A)'
             
     if request.args.get('froms', None):
         else_data = re.sub('\r\n#(?:redirect|넘겨주기) (?P<in>(?:(?!\r\n).)+)\r\n', ' * [[\g<in>]] 문서로 넘겨주기', '\r\n' + else_data + '\r\n')
@@ -3148,7 +3200,7 @@ def upload():
     else:
         return html_minify(render_template(skin_check(conn), 
             imp = ['파일 올리기', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data =  '<form method="post" enctype="multipart/form-data" accept-charset="utf8"><input type="file" name="f_data"><hr><input placeholder="파일 이름" name="f_name" type="text"><hr><input placeholder="라이선스" name="f_lice" type="text"><hr>' + captcha_get(conn) + '<button id="save" type="submit">저장</button></form>',
+            data =  '<form method="post" enctype="multipart/form-data" accept-charset="utf8"><input type="file" name="f_data"><hr><input placeholder="파일 이름" name="f_name" type="text"><hr><input placeholder="라이선스" name="f_lice" type="text"><hr>' + captcha_get(conn) + '<button id="save" type="submit">' + lang_data['save'] + '</button></form>',
             menu = [['other', '기타']]
         ))  
         
@@ -3219,7 +3271,7 @@ def watch_list():
     if data:
         div = '<ul>' + div + '</ul><hr>'
 
-    div += '<a href="/manager/13">(추가)</a>'
+    div += '<a href="/manager/13">(' + lang_data['plus'] + ')</a>'
 
     return html_minify(render_template(skin_check(conn), 
         imp = ['주시 문서 ' + lang_data['list'], wiki_set(conn, 1), custom(conn), other2([0, 0])],
@@ -3288,7 +3340,7 @@ def custom_head_view():
 
         return html_minify(render_template(skin_check(conn), 
             imp = [lang_data['user'] + ' HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data =  start + '<form method="post"><textarea rows="25" cols="100" name="content">' + data + '</textarea><hr><button id="save" type="submit">저장</button></form>',
+            data =  start + '<form method="post"><textarea rows="25" cols="100" name="content">' + data + '</textarea><hr><button id="save" type="submit">' + lang_data['save'] + '</button></form>',
             menu = [['user', lang_data['user']]]
         ))
 

+ 1 - 1
requirements.txt

@@ -1,4 +1,4 @@
-css-html-js-minify >= 2.2.2
+css-html-js-minify == 2.2.2
 tornado >= 4.5.2
 bcrypt >= 3.1.3
 requests >= 2.13.0

+ 36 - 11
set_mark/start.py

@@ -184,7 +184,23 @@ def start(conn, data, title):
     # 초기 설정
     data = '\n' + data + '\n'
     backlink = []
-    plus_data = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"><script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script><script>hljs.initHighlightingOnLoad(); function folding(num, test = 0) { var fol = document.getElementById(\'folding_\' + num); if(fol.style.display == \'inline-block\' || fol.style.display == \'block\') { fol.style.display = \'none\'; } else { if(num % 3 == 0 && test != 1) { fol.style.display = \'block\'; } else { fol.style.display = \'inline-block\'; } } }</script>'
+    plus_data = '''<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
+                    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+                    <script>
+                        hljs.initHighlightingOnLoad(); 
+                        function folding(num) { 
+                            var fol = document.getElementById('folding_' + num); 
+                            if(fol.style.display == 'inline-block' || fol.style.display == 'block') { 
+                                fol.style.display = 'none';
+                            } else {
+                                if(num % 2 == 0) { 
+                                    fol.style.display = 'block'; 
+                                } else { 
+                                    fol.style.display = 'inline-block'; 
+                                } 
+                            } 
+                        }
+                    </script>'''
     end_data= []
     
     # XSS 이스케이프
@@ -217,7 +233,7 @@ def start(conn, data, title):
 
                     num += 1
 
-                    end_data += [['include_one_nowiki_' + str(num), include_one_nowiki[0]]]
+                    end_data += [['include_one_nowiki_' + str(num), include_one_nowiki[0], 'normal']]
 
                     include = re.sub('(?:\\\\){2}(.)', '<span id="include_one_nowiki_' + str(num) + '"></span>', include, 1)
                 else:
@@ -254,13 +270,16 @@ def start(conn, data, title):
     data = re.sub('&amp;', '&', data)
 
     # HTML 허용
+    curs.execute('select html from html_filter')
+    html_db = curs.fetchall()
+
     src_list = ["www.youtube.com", "serviceapi.nmv.naver.com", "tv.kakao.com", "www.google.com", "serviceapi.rmcnmv.naver.com"]
     html_list = ['div', 'span', 'embed', 'iframe', 'ruby', 'rp', 'rt']
     
     html_data = re.findall('&lt;(\/)?((?:(?!&gt;| ).)+)( (?:(?:(?!&gt;).)+)?)?&gt;', data)
     for in_data in html_data:
         if in_data[0] == '':
-            if in_data[1] in html_list:
+            if in_data[1] in html_list or (html_db and in_data[1] in html_db[0]):
                 if re.search('&lt;\/' + in_data[1] + '&gt;', data):
                     src = re.search('src=([^ ]*)', in_data[2])
                     if src:
@@ -381,9 +400,9 @@ def start(conn, data, title):
                                                             else:
                                                                 folding_data = ['Test']
                                                             
-                                                            data = re.sub('{{{#!folding ?((?:(?!\n).)*)\n?', "<div>" + str(folding_data[0]) + " <div id='folding_" + str(fol_num + 1) + "' style='display: inline-block;'><a href='javascript:void(0);' onclick='folding(" + str(fol_num + 1) + "); folding(" + str(fol_num + 2) + "); folding(" + str(fol_num) + ");'>[펼치기]</a></div_end><div id='folding_" + str(fol_num + 2) + "' style='display: none; '><a href='javascript:void(0);' onclick='folding(" + str(fol_num + 1) + "); folding(" + str(fol_num + 2) + "); folding(" + str(fol_num) + ");'>[접기]</a></div_end><div id='folding_" + str(fol_num) + "' style='display: none;'>\n", data, 1)
+                                                            data = re.sub('{{{#!folding ?((?:(?!\n).)*)\n?', '<div>' + str(folding_data[0]) + ' <div style="display: inline-block;"><a href="javascript:void(0);" onclick="folding(' + str(fol_num) + ');">[작동]</a></div_end><div id="folding_' + str(fol_num) + '" style="display: none;">', data, 1)
                                                             
-                                                            fol_num += 3
+                                                            fol_num += 1
                                                         else:
                                                             middle_list += ['span']
 
@@ -429,7 +448,7 @@ def start(conn, data, title):
 
             num += 1
 
-            end_data += [['nowiki_' + str(num), nowiki_data[0]]]
+            end_data += [['nowiki_' + str(num), nowiki_data[0], 'code']]
 
             data = re.sub('<code>((?:(?:(?!<\/code>).)*\n*)*)<\/code>', '<span id="nowiki_' + str(num) + '"></span>', data, 1)
         else:
@@ -444,7 +463,7 @@ def start(conn, data, title):
 
             num += 1
 
-            end_data += [['syntax_' + str(num), syntax_data[1]]]
+            end_data += [['syntax_' + str(num), syntax_data[1], 'normal']]
 
             data = re.sub('<code class="((?:(?!").)+)">((?:(?:(?:(?!<\/code>|<span id="syntax_)).)+\n*)+)<\/code>', '<code class="' + syntax_data[0] + '"><span id="syntax_' + str(num) + '"></span></code>', data, 1)
         else:
@@ -494,7 +513,7 @@ def start(conn, data, title):
 
             num += 1
 
-            end_data += [['one_nowiki_' + str(num), one_nowiki[0]]]
+            end_data += [['one_nowiki_' + str(num), one_nowiki[0], 'normal']]
 
             data = re.sub('(?:\\\\)(.)', '<span id="one_nowiki_' + str(num) + '"></span>', data, 1)
         else:
@@ -938,14 +957,20 @@ def start(conn, data, title):
     
     # NoWiki 마지막 처리
     for re_data in end_data:
-        data = data.replace('<span id="' + re_data[0] + '"></span>', re_data[1])
-        data = data.replace(tool.url_pas('<span id="' + re_data[0] + '"></span>'), tool.url_pas(re_data[1]))
+        if re_data[2] == 'normal':
+            data = data.replace('<span id="' + re_data[0] + '"></span>', re_data[1])
+            data = data.replace(tool.url_pas('<span id="' + re_data[0] + '"></span>'), tool.url_pas(re_data[1]))
+        else:
+            if re.search('\n', re_data[1]):
+                data = data.replace('<span id="' + re_data[0] + '"></span>', '\n<pre>' + re.sub('^\n', '', re_data[1]) + '</pre>')
+            else:
+                data = data.replace('<span id="' + re_data[0] + '"></span>', '<code>' + re_data[1] + '</code>')
     
     # 마지막 처리
     data = re.sub('<\/td_end>', '</td>', data)
     data = re.sub('<include>\n', '', data)
     data = re.sub('\n<\/include>', '', data)
-
+    
     data = re.sub('(?P<in><\/h[0-9]>)(\n)+', '\g<in>', data)
     data = re.sub('\n\n<ul>', '\n<ul>', data)
     data = re.sub('<\/ul>\n\n', '</ul>\n', data)