Преглед изворни кода

Merge pull request #1806 from openNAMU/beta

fix bug
잉여개발기 (SPDV) пре 3 година
родитељ
комит
82a06d35b6
54 измењених фајлова са 1629 додато и 578 уклоњено
  1. 43 71
      app.py
  2. 4 2
      emergency_tool.py
  3. 4 4
      lang/ko-KR.json
  4. 163 0
      route/__init__.py
  5. 59 29
      route/api_topic.py
  6. 164 0
      route/bbs_edit.py
  7. 36 0
      route/bbs_main.py
  8. 44 0
      route/bbs_make.py
  9. 64 0
      route/bbs_w.py
  10. 379 0
      route/bbs_w_post.py
  11. 94 0
      route/bbs_w_set.py
  12. 15 7
      route/edit_delete_file.py
  13. 2 2
      route/edit_delete_multiple.py
  14. 8 7
      route/give_auth.py
  15. 4 4
      route/list_acl.py
  16. 1 1
      route/list_admin.py
  17. 4 3
      route/list_admin_auth_use.py
  18. 2 3
      route/list_image_file.py
  19. 1 1
      route/list_long_page.py
  20. 3 4
      route/list_please.py
  21. 3 4
      route/list_user.py
  22. 59 46
      route/main_search_deep.py
  23. 4 4
      route/main_search_goto.py
  24. 0 1
      route/main_setting_acl.py
  25. 0 1
      route/main_setting_external.py
  26. 26 25
      route/main_setting_main.py
  27. 0 1
      route/main_setting_phrase.py
  28. 10 1
      route/main_setting_skin_set.py
  29. 7 7
      route/main_tool_other.py
  30. 19 19
      route/main_tool_redirect.py
  31. 86 68
      route/tool/func.py
  32. 6 6
      route/tool/func_render.py
  33. 55 16
      route/tool/func_render_namumark.py
  34. 1 0
      route/tool/func_tool.py
  35. 10 5
      route/topic.py
  36. 11 7
      route/topic_list.py
  37. 8 1
      route/user_setting.py
  38. 2 5
      route/user_setting_pw.py
  39. 19 0
      route/user_setting_skin_set_main.py
  40. 1 1
      route/view_acl.py
  41. 53 19
      route/view_diff.py
  42. 1 1
      route/view_read.py
  43. 5 1
      route/view_xref.py
  44. 1 1
      version.json
  45. 53 1
      views/main_css/css/main.css
  46. 3 6
      views/main_css/js/route/render.js
  47. 0 185
      views/main_css/js/route/thread.js
  48. 8 0
      views/ringo/css/dark.css
  49. 48 0
      views/ringo/css/main.css
  50. 21 0
      views/ringo/index.html
  51. 1 1
      views/ringo/info.json
  52. 7 5
      views/tenshi/css/main.css
  53. 6 1
      views/tenshi/index.html
  54. 1 1
      views/tenshi/info.json

+ 43 - 71
app.py

@@ -3,32 +3,11 @@ import os
 import re
 import re
 
 
 from route.tool.func import *
 from route.tool.func import *
-# from route import *
-
-for i_data in os.listdir("route"):
-    f_src = re.search(r"(.+)\.py$", i_data)
-    f_src = f_src.group(1) if f_src else ""
-    
-    if not f_src in ('', '__init__'):
-        try:
-            exec(
-                "from route." + f_src + " " + 
-                "import " + f_src
-            )
-        except:
-            try:
-                exec(
-                    "from route." + f_src + " " + 
-                    "import " + f_src + "_2"
-                )
-            except:
-                pass
+from route import *
 
 
 # Init-Version
 # Init-Version
-version_list = json.loads(open(
-    'version.json', 
-    encoding = 'utf8'
-).read())
+with open('version.json', encoding = 'utf8') as file_data:
+    version_list = json.loads(file_data.read())
 
 
 # Init-DB
 # Init-DB
 data_db_set = class_check_json()
 data_db_set = class_check_json()
@@ -70,6 +49,8 @@ with get_db_connect() as conn:
             except:
             except:
                 pass
                 pass
 
 
+        conn.select_db(data_db_set['name'])
+
     if setup_tool != 'normal':
     if setup_tool != 'normal':
         create_data = get_db_table_list()
         create_data = get_db_table_list()
         for create_table in create_data:
         for create_table in create_data:
@@ -317,53 +298,37 @@ app.route('/list/document/old')(list_old_page)
 app.route('/list/document/old/<int:num>')(list_old_page)
 app.route('/list/document/old/<int:num>')(list_old_page)
 
 
 # /list/document/acl
 # /list/document/acl
-@app.route('/acl_list')
-def list_acl():
-    return list_acl_2()
-
-# /list/document/acl/add
-@app.route('/acl/<everything:name>', methods = ['POST', 'GET'])
-def give_acl(name = None):
-    return give_acl_2(name)
+app.route('/list/document/acl')(list_acl)
+app.route('/list/document/acl/<int:arg_num>')(list_acl)
 
 
 # /list/document/need
 # /list/document/need
-@app.route('/please')
-def list_please():
-    return list_please_2()
+app.route('/list/document/need')(list_please)
+app.route('/list/document/need/<int:arg_num>')(list_please)
 
 
 # /list/document/all
 # /list/document/all
 app.route('/list/document/all')(list_title_index)
 app.route('/list/document/all')(list_title_index)
 app.route('/list/document/all/<int:num>')(list_title_index)
 app.route('/list/document/all/<int:num>')(list_title_index)
 
 
 # /list/document/long
 # /list/document/long
-@app.route('/long_page')
-def list_long_page():
-    return list_long_page_2('long_page')
+app.route('/list/document/long')(list_long_page)
 
 
 # /list/document/short
 # /list/document/short
-@app.route('/short_page')
-def list_short_page():
-    return list_long_page_2('short_page')
+app.route('/list/document/short', defaults = { 'tool' : 'short_page' })(list_long_page)
 
 
 # /list/file
 # /list/file
-@app.route('/image_file_list')
-def list_image_file():
-    return list_image_file_2()
+app.route('/list/file')(list_image_file)
 
 
 # /list/admin
 # /list/admin
 # /list/admin/list
 # /list/admin/list
-@app.route('/admin_list')
-def list_admin():
-    return list_admin_2()
+app.route('/list/admin')(list_admin)
 
 
 # /list/admin/auth_use
 # /list/admin/auth_use
-app.route('/list/admin/auth_use', methods = ['POST', 'GET'])(list_admin_use)
-app.route('/list/admin/auth_use/<arg_search>/<int:arg_num>', methods = ['POST', 'GET'])(list_admin_use)
+app.route('/list/admin/auth_use', methods = ['POST', 'GET'])(list_admin_auth_use)
+app.route('/list/admin/auth_use/<arg_search>/<int:arg_num>', methods = ['POST', 'GET'])(list_admin_auth_use)
 
 
 # /list/user
 # /list/user
-@app.route('/user_log')
-def list_user():
-    return list_user_2()
+app.route('/list/user')(list_user)
+app.route('/list/user/<int:arg_num>')(list_user)
 
 
 # /list/user/check
 # /list/user/check
 @app.route('/check/<name>')
 @app.route('/check/<name>')
@@ -378,9 +343,8 @@ def give_user_check_delete():
 # Func-auth
 # Func-auth
 # /auth/give
 # /auth/give
 # /auth/give/<name>
 # /auth/give/<name>
-@app.route('/admin/<name>', methods = ['POST', 'GET'])
-def give_admin(name = None):
-    return give_admin_2(name)
+app.route('/auth/give', methods = ['POST', 'GET'])(give_auth)
+app.route('/auth/give/<name>', methods = ['POST', 'GET'])(give_auth)
 
 
 # /auth/give
 # /auth/give
 # /auth/give/<name>
 # /auth/give/<name>
@@ -447,6 +411,8 @@ app.route('/diff/<int(signed = True):num_a>/<int(signed = True):num_b>/<everythi
 
 
 app.route('/down/<everything:name>')(view_down)
 app.route('/down/<everything:name>')(view_down)
 
 
+app.route('/acl/<everything:name>', methods = ['POST', 'GET'])(view_acl)
+
 # everything 다음에 추가 붙은 경우에 대해서 재검토 필요 (진행중)
 # everything 다음에 추가 붙은 경우에 대해서 재검토 필요 (진행중)
 app.route('/w_rev/<int(signed = True):doc_rev>/<everything:name>')(view_read)
 app.route('/w_rev/<int(signed = True):doc_rev>/<everything:name>')(view_read)
 app.route('/w_from/<everything:name>', defaults = { 'do_type' : 'from' })(view_read)
 app.route('/w_from/<everything:name>', defaults = { 'do_type' : 'from' })(view_read)
@@ -589,13 +555,17 @@ app.route('/vote/list/close/<int:num>', defaults = { 'list_type' : 'close' })(vo
 app.route('/vote/add', methods = ['POST', 'GET'])(vote_add)
 app.route('/vote/add', methods = ['POST', 'GET'])(vote_add)
 
 
 # Func-bbs
 # Func-bbs
-# app.route('/bbs/main')
+app.route('/bbs/main')(bbs_main)
+app.route('/bbs/make', methods = ['POST', 'GET'])(bbs_make)
 # app.route('/bbs/main/set')
 # app.route('/bbs/main/set')
-# app.route('/bbs/make')
-# app.route('/bbs/w/<int:bbs_num>')
-# app.route('/bbs/set/<int:bbs_num>')
-# app.route('/bbs/edit/<int:bbs_num>')
-# app.route('/bbs/w/<int:bbs_num>/<int:post_num>')
+app.route('/bbs/w/<int:bbs_num>')(bbs_w)
+app.route('/bbs/set/<int:bbs_num>', methods = ['POST', 'GET'])(bbs_w_set)
+app.route('/bbs/edit/<int:bbs_num>', methods = ['POST', 'GET'])(bbs_edit)
+app.route('/bbs/edit/preview/<int:bbs_num>', methods = ['POST', 'GET'], defaults = { 'do_type' : 'preview' })(bbs_edit)
+app.route('/bbs/w/<int:bbs_num>/<int:post_num>', methods = ['POST', 'GET'])(bbs_w_post)
+app.route('/bbs/edit/<int:bbs_num>/<int:post_num>', methods = ['POST', 'GET'])(bbs_edit)
+app.route('/bbs/edit/preview/<int:bbs_num>/<int:post_num>', methods = ['POST', 'GET'], defaults = { 'do_type' : 'preview' })(bbs_edit)
+app.route('/bbs/w/preview/<int:bbs_num>/<int:post_num>', methods = ['POST'], defaults = { 'do_type' : 'preview' })(bbs_w_post)
 # app.route('/bbs/edit/<int:bbs_num>/<int:post_num>')
 # app.route('/bbs/edit/<int:bbs_num>/<int:post_num>')
 
 
 # Func-api
 # Func-api
@@ -610,6 +580,7 @@ app.route('/api/skin_info/<name>')(api_skin_info)
 app.route('/api/user_info/<name>', methods = ['POST', 'GET'])(api_user_info)
 app.route('/api/user_info/<name>', methods = ['POST', 'GET'])(api_user_info)
 app.route('/api/setting/<name>')(api_setting)
 app.route('/api/setting/<name>')(api_setting)
 
 
+app.route('/api/thread/<int:topic_num>/<tool>/<int:num>/<render>')(api_topic)
 app.route('/api/thread/<int:topic_num>/<tool>/<int:num>')(api_topic)
 app.route('/api/thread/<int:topic_num>/<tool>/<int:num>')(api_topic)
 app.route('/api/thread/<int:topic_num>/<tool>')(api_topic)
 app.route('/api/thread/<int:topic_num>/<tool>')(api_topic)
 app.route('/api/thread/<int:topic_num>')(api_topic)
 app.route('/api/thread/<int:topic_num>')(api_topic)
@@ -641,10 +612,10 @@ app.route('/manager/<int:num>/<everything:add_2>', methods = ['POST', 'GET'])(ma
 # app.route('/guide/<doc_name>')(main_tool_guide)
 # app.route('/guide/<doc_name>')(main_tool_guide)
 
 
 app.route('/search', methods=['POST'])(main_search)
 app.route('/search', methods=['POST'])(main_search)
-app.route('/search/<everything:name>')(main_search_deep)
-app.route('/search/<int:num>/<everything:name>')(main_search_deep)
-app.route('/search_data/<everything:name>', defaults = { 'search_type' : 'data' })(main_search_deep)
-app.route('/search_data/<int:num>/<everything:name>', defaults = { 'search_type' : 'data' })(main_search_deep)
+app.route('/search/<everything:name>', methods = ['POST', 'GET'])(main_search_deep)
+app.route('/search/<int:num>/<everything:name>', methods = ['POST', 'GET'])(main_search_deep)
+app.route('/search_data/<everything:name>', defaults = { 'search_type' : 'data' }, methods = ['POST', 'GET'])(main_search_deep)
+app.route('/search_data/<int:num>/<everything:name>', defaults = { 'search_type' : 'data' }, methods = ['POST', 'GET'])(main_search_deep)
 app.route('/goto', methods=['POST'])(main_search_goto)
 app.route('/goto', methods=['POST'])(main_search_goto)
 app.route('/goto/<everything:name>', methods=['POST'])(main_search_goto)
 app.route('/goto/<everything:name>', methods=['POST'])(main_search_goto)
 
 
@@ -668,11 +639,11 @@ app.route('/setting/skin_set', methods = ['POST', 'GET'])(main_setting_skin_set)
 app.route('/easter_egg')(main_func_easter_egg)
 app.route('/easter_egg')(main_func_easter_egg)
 
 
 # views -> view
 # views -> view
-app.route('/view/<everything:name>')(main_view)
-app.route('/views/<everything:name>')(main_view)
-app.route('/image/<everything:name>')(main_view_image)
+app.route('/view/<path:name>')(main_view)
+app.route('/views/<path:name>')(main_view)
+app.route('/image/<path:name>')(main_view_image)
 # 조정 계획 중
 # 조정 계획 중
-app.route('/<regex("[^.]+\.(?:txt|xml)"):data>')(main_view_file)
+app.route('/<regex("[^.]+\\.(?:txt|xml)"):data>')(main_view_file)
 
 
 app.route('/shutdown', methods = ['POST', 'GET'])(main_sys_shutdown)
 app.route('/shutdown', methods = ['POST', 'GET'])(main_sys_shutdown)
 app.route('/restart', methods = ['POST', 'GET'])(main_sys_restart)
 app.route('/restart', methods = ['POST', 'GET'])(main_sys_restart)
@@ -685,5 +656,6 @@ if __name__ == "__main__":
         app,
         app,
         host = server_set['host'],
         host = server_set['host'],
         port = int(server_set['port']),
         port = int(server_set['port']),
-        threads = 1
-    )
+        threads = 1,
+        clear_untrusted_proxy_headers = True
+    )

+ 4 - 2
emergency_tool.py

@@ -239,14 +239,16 @@ elif what_i_do == '20':
     print('----')
     print('----')
     domain = input('Domain (EX : 2du.pythonanywhere.com) : ')
     domain = input('Domain (EX : 2du.pythonanywhere.com) : ')
 
 
-    curs.execute(db_change("update other set data = ? where name = 'domain'"), [domain])
+    curs.execute(db_change('delete from other where name = "domain"'))
+    curs.execute(db_change('insert into other (name, data, coverage) values ("domain", ?, "")'), [domain])
 elif what_i_do == '21':
 elif what_i_do == '21':
     print('----')
     print('----')
     tls_v = input('TLS (http) [http, https] : ')
     tls_v = input('TLS (http) [http, https] : ')
     if not tls_v in ['http', 'https']:
     if not tls_v in ['http', 'https']:
         tls_v = 'http'
         tls_v = 'http'
 
 
-    curs.execute(db_change("update other set data = ? where name = 'http_select'"), [tls_v])
+    curs.execute(db_change('delete from other where name = "http_select"'))
+    curs.execute(db_change('insert into other (name, data, coverage) values ("http_select", ?, "")'), [tls_v])
 else:
 else:
     raise ValueError(what_i_do)
     raise ValueError(what_i_do)
 
 

+ 4 - 4
lang/ko-KR.json

@@ -1,6 +1,6 @@
 {
 {
     "language_tag": "ko-KR",
     "language_tag": "ko-KR",
-    "delete_admin_group": "관리자 그룹 삭제",
+    "delete_admin_group": "권한 그룹 삭제",
     "document_name": "문서명",
     "document_name": "문서명",
     "non_login_alert": "비로그인 알림",
     "non_login_alert": "비로그인 알림",
     "hide": "숨김",
     "hide": "숨김",
@@ -153,7 +153,7 @@
     "admin": "관리자",
     "admin": "관리자",
     "edit_filter_list": "편집 필터 목록",
     "edit_filter_list": "편집 필터 목록",
     "wiki_skin": "위키 스킨",
     "wiki_skin": "위키 스킨",
-    "admin_group": "관리자 그룹",
+    "admin_group": "권한 그룹",
     "all": "전체",
     "all": "전체",
     "error_skin_set": "사용 중인 스킨은 스킨 설정 기능을 지원하지 않습니다.",
     "error_skin_set": "사용 중인 스킨은 스킨 설정 기능을 지원하지 않습니다.",
     "error_skin_set_old": "일부 오래된 스킨은 구버전 링크를 이용해야만 작동할 수도 있습니다.",
     "error_skin_set_old": "일부 오래된 스킨은 구버전 링크를 이용해야만 작동할 수도 있습니다.",
@@ -200,7 +200,7 @@
     "topic_long_error": "토론 제목은 256자를 넘을 수 없습니다.",
     "topic_long_error": "토론 제목은 256자를 넘을 수 없습니다.",
     "error_401": "ACL 읽기 제한 문서 문구",
     "error_401": "ACL 읽기 제한 문서 문구",
     "history": "역사",
     "history": "역사",
-    "admin_group_list": "관리자 그룹 목록",
+    "admin_group_list": "권한 그룹 목록",
     "time": "시간",
     "time": "시간",
     "password_search_text": "비밀번호 찾기 문구",
     "password_search_text": "비밀번호 찾기 문구",
     "agreed_discussion": "합의된 토론",
     "agreed_discussion": "합의된 토론",
@@ -325,7 +325,7 @@
     "all_register_num": "모든 가입 신청자의 수",
     "all_register_num": "모든 가입 신청자의 수",
     "replace_move": "서로 바꾸기",
     "replace_move": "서로 바꾸기",
     "merge_move": "문서 병합",
     "merge_move": "문서 병합",
-    "add_admin_group": "관리자 그룹 추가",
+    "add_admin_group": "권한 그룹 추가",
     "add_watchlist": "주시 문서 추가",
     "add_watchlist": "주시 문서 추가",
     "blocked_user": "차단된 사용자",
     "blocked_user": "차단된 사용자",
     "blocked_admin": "차단한 관리자",
     "blocked_admin": "차단한 관리자",

+ 163 - 0
route/__init__.py

@@ -0,0 +1,163 @@
+from route.api_func_lang import api_func_lang
+from route.api_func_sha224 import api_func_sha224
+from route.api_image_view import api_image_view
+from route.api_raw import api_raw
+from route.api_recent_change import api_recent_change
+from route.api_recent_discuss import api_recent_discuss
+from route.api_search import api_search
+from route.api_setting import api_setting
+from route.api_skin_info import api_skin_info
+from route.api_title_index import api_title_index
+from route.api_topic import api_topic
+from route.api_user_info import api_user_info
+from route.api_version import api_version
+from route.api_w import api_w
+
+from route.bbs_edit import bbs_edit
+from route.bbs_main import bbs_main
+from route.bbs_make import bbs_make
+from route.bbs_w import bbs_w
+from route.bbs_w_post import bbs_w_post
+from route.bbs_w_set import bbs_w_set
+
+from route.edit import edit
+from route.edit_backlink_reset import edit_backlink_reset
+from route.edit_delete import edit_delete
+from route.edit_delete_file import edit_delete_file
+from route.edit_delete_multiple import edit_delete_multiple
+from route.edit_move import edit_move
+from route.edit_revert import edit_revert
+from route.edit_upload import edit_upload
+
+from route.filter_document import filter_document
+from route.filter_document_add import filter_document_add
+from route.filter_document_delete import filter_document_delete
+from route.filter_inter_wiki import filter_inter_wiki
+from route.filter_inter_wiki_add import filter_inter_wiki_add
+from route.filter_inter_wiki_delete import filter_inter_wiki_delete
+
+from route.give_admin_groups import give_admin_groups_2
+from route.give_auth import give_auth
+from route.give_delete_admin_group import give_delete_admin_group_2
+from route.give_user_ban import give_user_ban
+from route.give_user_check import give_user_check_2
+from route.give_user_check_delete import give_user_check_delete_2
+from route.give_user_fix import give_user_fix
+
+from route.list_acl import list_acl
+from route.list_admin import list_admin
+from route.list_admin_auth_use import list_admin_auth_use
+from route.list_admin_group import list_admin_group_2
+from route.list_image_file import list_image_file
+from route.list_long_page import list_long_page
+from route.list_old_page import list_old_page
+from route.list_please import list_please
+from route.list_title_index import list_title_index
+from route.list_user import list_user
+
+from route.login_find import login_find
+from route.login_find_email import login_find_email
+from route.login_find_email_check import login_find_email_check
+from route.login_find_key import login_find_key
+from route.login_login import login_login_2
+from route.login_login_2fa import login_login_2fa_2
+from route.login_login_2fa_email import login_login_2fa_email_2
+from route.login_logout import login_logout
+
+from route.login_register import login_register_2
+from route.login_register_email import login_register_email_2
+from route.login_register_email_check import login_register_email_check_2
+from route.login_register_submit import login_register_submit_2
+
+from route.main_func_easter_egg import main_func_easter_egg
+from route.main_func_error_404 import main_func_error_404
+
+from route.main_search import main_search
+from route.main_search_deep import main_search_deep
+from route.main_search_goto import main_search_goto
+
+from route.main_setting import main_setting
+from route.main_setting_acl import main_setting_acl
+from route.main_setting_external import main_setting_external
+from route.main_setting_head import main_setting_head
+from route.main_setting_main import main_setting_main
+from route.main_setting_main_logo import main_setting_main_logo
+from route.main_setting_phrase import main_setting_phrase
+from route.main_setting_robot import main_setting_robot
+from route.main_setting_sitemap import main_setting_sitemap
+from route.main_setting_skin_set import main_setting_skin_set
+from route.main_setting_top_menu import main_setting_top_menu
+
+from route.main_sys_restart import main_sys_restart
+from route.main_sys_shutdown import main_sys_shutdown
+from route.main_sys_update import main_sys_update
+
+from route.main_tool_admin import main_tool_admin
+from route.main_tool_other import main_tool_other
+from route.main_tool_redirect import main_tool_redirect
+
+from route.main_view import main_view
+from route.main_view_file import main_view_file
+from route.main_view_image import main_view_image
+
+from route.recent_app_submit import recent_app_submit_2
+
+from route.recent_block import recent_block_2
+from route.recent_change import recent_change
+from route.recent_discuss import recent_discuss
+from route.recent_history_add import recent_history_add
+from route.recent_history_delete import recent_history_delete
+from route.recent_history_hidden import recent_history_hidden
+from route.recent_history_reset import recent_history_reset
+from route.recent_history_send import recent_history_send
+from route.recent_history_tool import recent_history_tool
+from route.recent_record_reset import recent_record_reset
+from route.recent_record_topic import recent_record_topic
+
+from route.topic import topic
+from route.topic_comment_blind import topic_comment_blind
+from route.topic_comment_delete import topic_comment_delete
+from route.topic_comment_notice import topic_comment_notice
+from route.topic_comment_tool import topic_comment_tool
+from route.topic_list import topic_list
+from route.topic_tool import topic_tool
+from route.topic_tool_acl import topic_tool_acl
+from route.topic_tool_change import topic_tool_change
+from route.topic_tool_delete import topic_tool_delete
+from route.topic_tool_setting import topic_tool_setting
+
+from route.user_alarm import user_alarm
+from route.user_alarm_delete import user_alarm_delete
+from route.user_challenge import user_challenge
+from route.user_count import user_count
+from route.user_info import user_info
+
+from route.user_setting import user_setting
+from route.user_setting_email import user_setting_email_2
+from route.user_setting_email_check import user_setting_email_check_2
+from route.user_setting_email_delete import user_setting_email_delete
+from route.user_setting_head import user_setting_head
+from route.user_setting_head_reset import user_setting_head_reset
+from route.user_setting_key import user_setting_key
+from route.user_setting_key_delete import user_setting_key_delete
+from route.user_setting_pw import user_setting_pw
+from route.user_setting_skin_set import user_setting_skin_set
+from route.user_setting_skin_set_main import user_setting_skin_set_main
+from route.user_setting_top_menu import user_setting_top_menu
+
+from route.user_watch_list import user_watch_list
+from route.user_watch_list_name import user_watch_list_name
+
+from route.view_acl import view_acl
+from route.view_diff import view_diff
+from route.view_down import view_down
+from route.view_random import view_random
+from route.view_raw import view_raw_2
+from route.view_read import view_read
+from route.view_xref import view_xref
+
+from route.vote_add import vote_add
+from route.vote_close import vote_close
+from route.vote_end import vote_end
+from route.vote_list import vote_list
+from route.vote_select import vote_select

+ 59 - 29
route/api_topic.py

@@ -1,6 +1,7 @@
 from .tool.func import *
 from .tool.func import *
+from .bbs_w_post import bbs_w_post_make_thread
 
 
-def api_topic(topic_num = 1, tool = 'normal', num = ''):
+def api_topic(topic_num = 1, tool = 'normal', num = '', render = ''):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
@@ -9,32 +10,19 @@ def api_topic(topic_num = 1, tool = 'normal', num = ''):
         if acl_check('', 'topic_view', topic_num) != 1:
         if acl_check('', 'topic_view', topic_num) != 1:
             if tool == 'normal':
             if tool == 'normal':
                 if num != '':
                 if num != '':
-                    curs.execute(db_change(
-                        "select id, data, date, ip, block, top from topic where code = ? and id + 0 = ? + 0 order by id + 0 asc"
-                    ), [
-                        topic_num,
-                        num
-                    ])
+                    curs.execute(db_change("select id, data, date, ip, block, top from topic where code = ? and id + 0 = ? + 0 order by id + 0 asc"), [topic_num, num])
                 else:
                 else:
-                    curs.execute(db_change(
-                        "select id, data, date, ip, block, top from topic where code = ? order by id + 0 asc"
-                    ), [
-                        topic_num
-                    ])
-            elif tool == 'length':
+                    curs.execute(db_change("select id, data, date, ip, block, top from topic where code = ? order by id + 0 asc"), [topic_num])
+            elif tool == 'top':
+                curs.execute(db_change("select id, data, date, ip, block, top from topic where code = ? and top = 'O' order by id + 0 asc"), [topic_num])
+            else:
+                # tool == 'length'
                 curs.execute(db_change("select id from topic where code = ? order by id + 0 desc limit 1"), [topic_num])
                 curs.execute(db_change("select id from topic where code = ? order by id + 0 desc limit 1"), [topic_num])
                 db_data = curs.fetchall()
                 db_data = curs.fetchall()
-
                 if db_data:
                 if db_data:
                     return flask.jsonify({ 'length' : db_data[0][0] })
                     return flask.jsonify({ 'length' : db_data[0][0] })
                 else:
                 else:
                     return flask.jsonify({})
                     return flask.jsonify({})
-            else:
-                curs.execute(db_change(
-                    "select id, data, date, ip, block, top from topic where code = ? and top = 'O' order by id + 0 asc"
-                ), [
-                    topic_num
-                ])
 
 
             data = curs.fetchall()
             data = curs.fetchall()
             if data:
             if data:
@@ -48,28 +36,70 @@ def api_topic(topic_num = 1, tool = 'normal', num = ''):
                     "ip_first" : ip_pas(data_f, 1),
                     "ip_first" : ip_pas(data_f, 1),
                     "admin" : str(admin)
                     "admin" : str(admin)
                 }
                 }
+                data_a['data'] = []
 
 
                 ip_a = ip_pas([i[3] for i in data])
                 ip_a = ip_pas([i[3] for i in data])
                 ip_a_2 = ip_pas([i[3] for i in data], 1)
                 ip_a_2 = ip_pas([i[3] for i in data], 1)
                 for i in data:
                 for i in data:
                     data_v = i[1] if i[4] != 'O' or admin == 1 else ''
                     data_v = i[1] if i[4] != 'O' or admin == 1 else ''
+                    if data_v != '':
+                        data_v = render_set(
+                            doc_data = data_v, 
+                            data_type = 'api_view',
+                            data_in = 'topic_' + topic_num + '_' + i[0],
+                            doc_acl = 0
+                        )
+                        data_v[0] = re.sub(
+                            r'&lt;topic_a&gt;(?P<in>(?:(?!&lt;\/topic_a&gt;).)+)&lt;\/topic_a&gt;',
+                            '<a href="\g<in>">\g<in></a>',
+                            data_v[0]
+                        )
+                        data_v[0] = re.sub(
+                            r'&lt;topic_call&gt;@(?P<in>(?:(?!&lt;\/topic_call&gt;).)+)&lt;\/topic_call&gt;',
+                            '<a href="/w/user:\g<in>">@\g<in></a>',
+                            data_v[0]
+                        )
+                    else:
+                        data_v = ['', '']
+
+                    data_a['data'] += [{
+                        "id" : i[0],
 
 
-                    data_a[i[0]] = {
                         "data" : data_v,
                         "data" : data_v,
                         "date" : i[2],
                         "date" : i[2],
                         "ip" : ip_a_2[i[3]],
                         "ip" : ip_a_2[i[3]],
                         "blind" : i[4],
                         "blind" : i[4],
 
 
                         "ip_pas" : ip_a[i[3]],
                         "ip_pas" : ip_a[i[3]],
-                        "data_pas" : render_set(
-                            doc_data = data_v, 
-                            data_type = 'api_view',
-                            data_in = 'topic_' + topic_num + '_' + i[0],
-                            doc_acl = 0
-                        )
-                    }
+                        "data_pas" : data_v
+                    }]
+
+                if render == '':
+                    return flask.jsonify(data_a)
+                else:
+                    data_r = ''
+                    if 'data' in data_a:
+                        for for_a in data_a['data']:
+                            if tool == 'top':
+                                color = 'red'
+                            else:
+                                if data_a['data_main']["ip_first"] == for_a["ip"]:
+                                    color = 'green'
+                                else:
+                                    color = 'default'
+
+                            data_r += bbs_w_post_make_thread(
+                                for_a["ip_pas"],
+                                '<a href="/thread/' + topic_num + '/comment/' + for_a["id"] + '/tool">(' + load_lang('tool') + ')</a> ' + for_a["date"],
+                                for_a["data_pas"][0] + '<script>' + for_a["data_pas"][1] + '</script>',
+                                for_a["id"],
+                                color = color,
+                                blind = for_a["blind"],
+                                add_style = ''
+                            )
+                            data_r += '<hr class="main_hr">'
 
 
-                return flask.jsonify(data_a)
+                    return flask.jsonify({ "data" : data_r })
             else:
             else:
                 return flask.jsonify({})
                 return flask.jsonify({})
         else:
         else:

+ 164 - 0
route/bbs_edit.py

@@ -0,0 +1,164 @@
+from .tool.func import *
+
+def bbs_edit(bbs_num = '', post_num = '', do_type = ''):
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        bbs_num_str = str(bbs_num)
+        post_num_str = str(post_num)
+
+        ip = ip_check()
+
+        curs.execute(db_change('select set_id from bbs_set where set_id = ? and set_name = "bbs_name"'), [bbs_num_str])
+        if not curs.fetchall():
+            return redirect('/bbs/main')
+        
+        if post_num != '':
+            curs.execute(db_change('select set_data from bbs_data where set_name = "user_id" and set_id = ? and set_code = ?'), [bbs_num, post_num])
+            db_data = curs.fetchall()
+            if not db_data:
+                return redirect('/bbs/main')
+            else:
+                if not db_data[0][0] == ip and admin_check() != 1:
+                    return re_error('/ban')
+            
+        if acl_check(bbs_num_str, 'bbs_edit') == 1:
+            return redirect('/bbs/set/' + bbs_num_str)
+
+        if flask.request.method == 'POST' and do_type != 'preview':
+            if captcha_post(flask.request.form.get('g-recaptcha-response', flask.request.form.get('g-recaptcha', ''))) == 1:
+                return re_error('/error/13')
+            else:
+                captcha_post('', 0)
+        
+            if post_num == '':
+                curs.execute(db_change('select set_code from bbs_data where set_name = "title" and set_id = ? order by set_code + 0 desc'), [bbs_num_str])
+                db_data = curs.fetchall()
+                id_data = str(int(db_data[0][0]) + 1) if db_data else '1'
+            else:
+                id_data = post_num_str
+
+            title = flask.request.form.get('title', 'test')
+            title = 'test' if title == '' else title
+            data = flask.request.form.get('content', '')
+            if data == '':
+                # re_error로 대체 예정
+                return redirect('/bbs/w/' + bbs_num_str)
+            
+            date = get_time()
+
+            if post_num == '':
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('title', ?, ?, ?)"), [id_data, bbs_num_str, title])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('data', ?, ?, ?)"), [id_data, bbs_num_str, data])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('date', ?, ?, ?)"), [id_data, bbs_num_str, date])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('user_id', ?, ?, ?)"), [id_data, bbs_num_str, ip])
+            else:
+                curs.execute(db_change("update bbs_data set set_data = ? where set_name = 'title' and set_code = ? and set_id = ?"), [title, post_num, bbs_num_str])
+                curs.execute(db_change("update bbs_data set set_data = ? where set_name = 'data' and set_code = ? and set_id = ?"), [data, id_data, bbs_num_str])
+                curs.execute(db_change("update bbs_data set set_data = ? where set_name = 'date' and set_code = ? and set_id = ?"), [date, id_data, bbs_num_str])
+
+            return redirect('/bbs/w/' + bbs_num_str + '/' + id_data)
+        else:
+            if do_type == 'preview':
+                title = flask.request.form.get('title', '')
+                data = flask.request.form.get('content', '')
+                data = data.replace('\r', '')
+
+                data_preview = render_set(
+                    doc_name = '', 
+                    doc_data = data,
+                    data_in = 'from'
+                )
+            else:
+                if post_num == '':
+                    title = ''
+                    data = ''
+                    data_preview = ''
+                else:
+                    curs.execute(db_change('select set_name, set_data, set_code from bbs_data where set_id = ? and set_code = ?'), [bbs_num, post_num])
+                    db_data = curs.fetchall()
+                    db_data = list(db_data) if db_data else []
+
+                    temp_id = ''
+                    temp_dict = {}
+
+                    for for_a in db_data + [['', '', '']]:
+                        if temp_id != for_a[2]:
+                            temp_id = for_a[2]
+                            temp_dict['code'] = for_a[2]
+
+                        temp_dict[for_a[0]] = for_a[1]
+
+                    title = temp_dict['title']
+                    data = temp_dict['data']
+                    data_preview = ''
+            
+            if post_num == '':
+                form_action = 'formaction="/bbs/edit/' + bbs_num_str + '"'
+                form_action_preview = 'formaction="/bbs/edit/preview/' + bbs_num_str + '"'
+            else:
+                form_action = 'formaction="/bbs/edit/' + bbs_num_str + '/' + post_num_str + '"'
+                form_action_preview = 'formaction="/bbs/edit/preview/' + bbs_num_str + '/' + post_num_str + '"'
+    
+            editor_top_text = '<a href="/edit_filter">(' + load_lang('edit_filter_rule') + ')</a>'
+            
+            monaco_on = get_main_skin_set(curs, flask.session, 'main_css_monaco', ip)
+            if monaco_on == 'use':
+                editor_display = 'style="display: none;"'
+                monaco_display = ''
+                add_get_file = '''
+                    <link   rel="stylesheet"
+                            data-name="vs/editor/editor.main" 
+                            href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.37.1/min/vs/editor/editor.main.min.css">
+                    <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.37.1/min/vs/loader.min.js"></script>
+                '''
+
+                editor_top_text += ' <a href="javascript:opennamu_edit_turn_off_monaco();">(' + load_lang('turn_off_monaco') + ')</a>'
+                
+                if flask.request.cookies.get('main_css_darkmode', '0') == '1':
+                    monaco_thema = 'vs-dark'
+                else:
+                    monaco_thema = ''
+                
+                add_script = 'do_monaco_init("' + monaco_thema + '");'
+            else:
+                editor_display = ''
+                monaco_display = 'style="display: none;"'
+                add_get_file = ''
+                add_script = 'opennamu_edit_turn_off_monaco();'
+
+            if editor_top_text != '':
+                editor_top_text += '<hr class="main_hr">'
+    
+            return easy_minify(flask.render_template(skin_check(), 
+                imp = [load_lang('bbs_edit'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+                data =  editor_top_text + add_get_file + '''
+                    <form method="post">
+                        <textarea style="display: none;" id="opennamu_edit_origin" name="doc_data_org"></textarea>
+
+                        <div>''' + edit_button('opennamu_edit_textarea', 'opennamu_monaco_editor') + '''</div>
+                        
+                        <input placeholder="''' + load_lang('bbs_title') + '''" name="title" value="''' + html.escape(title) + '''">
+                        <hr class="main_hr">
+
+                        <div id="opennamu_monaco_editor" class="opennamu_textarea_500" ''' + monaco_display + '''></div>
+                        <textarea id="opennamu_edit_textarea" ''' + editor_display + ''' class="opennamu_textarea_500" name="content">''' + html.escape(data) + '''</textarea>
+                        <hr class="main_hr">
+                        
+                        ''' + captcha_get() + ip_warning() + '''
+                        
+                        <button id="opennamu_save_button" type="submit" ''' + form_action + ''' onclick="do_monaco_to_textarea(); do_stop_exit_release();">''' + load_lang('save') + '''</button>
+                        <button id="opennamu_preview_button" type="submit" ''' + form_action_preview + ''' onclick="do_monaco_to_textarea(); do_stop_exit_release();">''' + load_lang('preview') + '''</button>
+                    </form>
+                    
+                    <hr class="main_hr">
+                    <div id="opennamu_preview_area">''' + data_preview + '''</div>
+                    
+                    <script>
+                        do_stop_exit();
+                        do_paste_image('opennamu_edit_textarea', 'opennamu_monaco_editor');
+                        ''' + add_script + '''
+                    </script>
+                ''',
+                menu = [['bbs/w/' + bbs_num_str, load_lang('return')]]
+            ))

+ 36 - 0
route/bbs_main.py

@@ -0,0 +1,36 @@
+from .tool.func import *
+
+def bbs_main():
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        curs.execute(db_change('select set_data, set_id from bbs_set where set_name = "bbs_name"'))
+        db_data = curs.fetchall()
+        
+        data = ''
+
+        if db_data:
+            data += '<ul class="opennamu_ul">'
+            for for_a in db_data:
+                curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_type" and set_id = ?'), [for_a[1]])
+                db_data_2 = curs.fetchall()
+                bbs_type = db_data_2[0][0] if db_data_2 else 'comment'
+                
+                curs.execute(db_change('select set_data from bbs_data where set_id = ? and set_name = "date" order by set_code + 0 desc limit 1'), [for_a[1]])
+                db_data_2 = curs.fetchall()
+                last_date = ('(' + db_data_2[0][0] + ')') if db_data_2 else ''
+
+                data += '<li><a href="/bbs/w/' + for_a[1] + '">' + for_a[0] + ' (' + bbs_type + ') ' + last_date + '</a></li>'
+
+            data += '</ul>'
+
+        if admin_check() == 1:
+            menu = [['bbs/make', load_lang('add')]]
+        else:
+            menu = []
+
+        return easy_minify(flask.render_template(skin_check(),
+            imp = [load_lang('bbs_main'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+            data = data,
+            menu = [['other', load_lang('return')]] + menu
+        ))

+ 44 - 0
route/bbs_make.py

@@ -0,0 +1,44 @@
+from .tool.func import *
+
+def bbs_make():   
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        if admin_check() != 1:
+            return re_error('/error/3')
+        
+        if flask.request.method == 'POST':
+            
+            curs.execute(db_change('select set_id from bbs_set where set_name = "bbs_name" order by set_id + 0 desc'))
+            db_data = curs.fetchall()
+
+            bbs_num = str(int(db_data[0][0]) + 1) if db_data else '1'
+            bbs_name = flask.request.form.get('bbs_name', 'test')
+            bbs_type = flask.request.form.get('bbs_type', 'comment')
+            bbs_type = bbs_type if bbs_type in ['comment', 'thread'] else 'comment'
+
+            curs.execute(db_change("insert into bbs_set (set_name, set_code, set_id, set_data) values ('bbs_name', '', ?, ?)"), [bbs_num, bbs_name])
+            curs.execute(db_change("insert into bbs_set (set_name, set_code, set_id, set_data) values ('bbs_type', '', ?, ?)"), [bbs_num, bbs_type])
+
+            conn.commit()
+
+            return redirect('/bbs/main')
+        else:
+            return easy_minify(flask.render_template(skin_check(),
+                imp = [load_lang('bbs_make'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+                data = '''
+                    <form method="post">
+                        <input placeholder="''' + load_lang('bbs_name') + '''" name="bbs_name">
+                        <hr class="main_hr">
+                        
+                        <select name="bbs_type">
+                            <option value="comment">''' + load_lang('comment') + '''</option>
+                            <option value="thread">''' + load_lang('thread') + '''</option>
+                        </select>
+                        <hr class="main_hr">
+                        
+                        <button type="submit">''' + load_lang('save') + '''</button>
+                    </form>
+                ''',
+                menu = [['bbs/main', load_lang('return')]]
+            ))

+ 64 - 0
route/bbs_w.py

@@ -0,0 +1,64 @@
+from .tool.func import *
+
+def bbs_w(bbs_num = ''):
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        curs.execute(db_change('select set_id from bbs_set where set_id = ? and set_name = "bbs_name"'), [bbs_num])
+        if not curs.fetchall():
+            return redirect('/bbs/main')
+
+        bbs_num_str = str(bbs_num)
+
+        data = ''
+        data += '''
+            <table id="main_table_set">
+                <tr id="main_table_top_tr">
+                    <td id="main_table_width">''' + load_lang('version') + '''</td>
+                    <td id="main_table_width">''' + load_lang('editor') + '''</td>
+                    <td id="main_table_width">''' + load_lang('time') + '''</td>
+                </tr>
+        '''
+        
+        temp_id = ''
+        temp_dict = {}
+
+        curs.execute(db_change('select set_name, set_data, set_code from bbs_data where set_id = ? order by set_code + 0 desc'), [bbs_num])
+        db_data = curs.fetchall()
+        db_data = list(db_data) if db_data else []
+
+        for for_a in db_data + [['', '', '']]:
+            if temp_id != for_a[2]:
+                if temp_id != '':
+                    curs.execute(db_change('select set_data from bbs_data where set_name = "comment_date" and set_id = ? order by set_code + 0 desc'), [bbs_num_str + '-' + temp_dict['code']])
+                    db_data = curs.fetchall()
+                    last_comment_date = db_data[0][0] if db_data else '0'
+                    comment_count = str(len(db_data)) if db_data else '0'
+                    
+                    data += '''
+                        <tr>
+                            <td>''' + temp_dict['code'] + '''</td>
+                            <td>''' + ip_pas(temp_dict['user_id']) + '''</td>
+                            <td>''' + temp_dict['date'] + '''</td>
+                        </tr>
+                        <tr>
+                            <td colspan="3">
+                                <a href="/bbs/w/''' + bbs_num_str + '/' + temp_dict['code'] + '">' + temp_dict['title'] + '''</a> 
+                                (''' + comment_count + ''') 
+                                (''' + last_comment_date + ''')
+                            </td>
+                        </tr>
+                    '''
+
+                temp_id = for_a[2]
+                temp_dict['code'] = for_a[2]
+
+            temp_dict[for_a[0]] = for_a[1]
+
+        data += '</table>'
+
+        return easy_minify(flask.render_template(skin_check(),
+            imp = [load_lang('bbs_main'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+            data = data,
+            menu = [['bbs/main', load_lang('return')], ['bbs/edit/' + bbs_num_str, load_lang('add')], ['bbs/set/' + bbs_num_str, load_lang('setting')]]
+        ))

+ 379 - 0
route/bbs_w_post.py

@@ -0,0 +1,379 @@
+from .tool.func import *
+
+def bbs_w_post_make_thread(user_id, date, data, code, color = '', blind = '', add_style = ''):
+    if blind != '':
+        if data == '':
+            color_b = 'opennamu_comment_blind'
+        else:
+            color_b = 'opennamu_comment_blind_admin'
+    else:
+        color_b = 'opennamu_comment_blind_not'
+
+    return '''
+        <table class="opennamu_comment" style="''' + add_style + '''">
+            <tr>
+                <td class="opennamu_comment_color_''' + color + '''">
+                    <a href="#thread_shortcut" id="''' + code + '''">#''' + code + '''</a>
+                    ''' + user_id + '''
+                    <span style="float: right;">''' + date + '''</span>
+                </td>
+            </tr>
+            <tr>
+                <td class="''' + color_b + '''" id="opennamu_comment_data_main">
+                    ''' + data + '''
+                </td>
+            </tr>
+        </table>
+    '''
+
+def bbs_w_post(bbs_num = '', post_num = '', do_type = ''):
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        curs.execute(db_change('select set_name, set_data, set_code from bbs_data where set_id = ? and set_code = ?'), [bbs_num, post_num])
+        db_data = curs.fetchall()
+        if not db_data:
+            return redirect('/bbs/main')
+
+        bbs_num_str = str(bbs_num)
+        post_num_str = str(post_num)
+        bbs_comment_acl = acl_check(bbs_num_str, 'bbs_comment')
+        ip = ip_check()
+        
+        curs.execute(db_change('select set_data from bbs_set where set_id = ? and set_name = "bbs_type"'), [bbs_num])
+        db_data_2 = curs.fetchall()
+        if not db_data_2:
+            return redirect('/bbs/main')
+        elif db_data_2[0][0] == 'thread':
+            if flask.request.method == 'POST' and do_type != 'preview':
+                if bbs_comment_acl == 1:
+                    return redirect('/bbs/set/' + bbs_num_str)
+                
+                if captcha_post(flask.request.form.get('g-recaptcha-response', flask.request.form.get('g-recaptcha', ''))) == 1:
+                    return re_error('/error/13')
+                else:
+                    captcha_post('', 0)
+
+                set_id = bbs_num_str + '-' + post_num_str
+
+                curs.execute(db_change('select set_code from bbs_data where set_name = "comment" and set_id = ? order by set_code + 0 desc'), [set_id])
+                db_data = curs.fetchall()
+                id_data = str(int(db_data[0][0]) + 1) if db_data else '1'
+
+                data = flask.request.form.get('content', '')
+                if data == '':
+                    # re_error로 대체 예정
+                    return redirect('/bbs/w/' + bbs_num_str + '/' + post_num_str)
+                
+                date = get_time()
+
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment', ?, ?, ?)"), [id_data, set_id, data])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment_date', ?, ?, ?)"), [id_data, set_id, date])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment_user_id', ?, ?, ?)"), [id_data, set_id, ip])
+
+                conn.commit()
+
+                return redirect('/bbs/w/' + bbs_num_str + '/' + post_num_str + '#comment_' + str(int(id_data) + 1))
+            else:
+                if acl_check(bbs_num_str, 'bbs_view') == 1:
+                    return re_error('/ban')
+
+                if do_type == 'preview':
+                    text = flask.request.form.get('content', '')
+                    text = text.replace('\r', '')
+
+                    data_preview = render_set(
+                        doc_name = '', 
+                        doc_data = text,
+                        data_in = 'from'
+                    )
+                else:
+                    text = ''
+                    data_preview = ''
+                
+                temp_id = ''
+                temp_dict = {}
+
+                db_data = list(db_data) if db_data else []
+                for for_a in db_data + [['', '', '']]:
+                    if temp_id != for_a[2]:
+                        temp_id = for_a[2]
+                        temp_dict['code'] = for_a[2]
+
+                    temp_dict[for_a[0]] = for_a[1]
+
+                count = 1
+
+                data = ''
+                data += '<h2>' + html.escape(temp_dict['title']) + '</h2>'
+                data += bbs_w_post_make_thread(
+                    ip_pas(temp_dict['user_id']),
+                    temp_dict['date'],
+                    render_set(
+                        doc_name = '', 
+                        doc_data = temp_dict['data'],
+                        data_in = 'from'
+                    ),
+                    '1',
+                    color = 'green'
+                )
+                data += '<hr class="main_hr">'
+
+                user_id = temp_dict['user_id']
+
+                temp_id = ''
+                temp_dict = {}
+
+                curs.execute(db_change('select set_name, set_data, set_code, set_id from bbs_data where (set_name = "comment" or set_name = "comment_date" or set_name = "comment_user_id") and set_id = ? order by set_code + 0 asc'), [bbs_num_str + '-' + post_num_str])
+                db_data = curs.fetchall()
+                db_data = list(db_data) if db_data else []
+
+                for for_a in db_data + [['', '', '']]:
+                    if temp_id == '':
+                        temp_id = for_a[2]
+
+                    if temp_id != for_a[2]:
+                        temp_id = for_a[2]
+                        temp_dict['code'] = for_a[2]
+                        count += 1
+
+                        if user_id == temp_dict['comment_user_id']:
+                            color = 'green'
+                        else:
+                            color = 'default'
+
+                        data += bbs_w_post_make_thread(
+                            ip_pas(temp_dict['comment_user_id']),
+                            temp_dict['comment_date'],
+                            render_set(
+                                doc_name = '', 
+                                doc_data = temp_dict['comment'],
+                                data_in = 'from'
+                            ),
+                            str(count),
+                            color = color
+                        )
+                        data += '<hr class="main_hr">'
+
+                    temp_dict[for_a[0]] = for_a[1]
+
+                bbs_comment_form = ''
+                if bbs_comment_acl == 0:
+                    bbs_comment_form = '''                        
+                        <textarea name="content" id="opennamu_edit_textarea" class="opennamu_textarea_100">''' + html.escape(text) + '''</textarea>
+                        <hr class="main_hr">
+                        
+                        ''' + captcha_get() + ip_warning() + '''
+
+                        <button id="opennamu_save_button" formaction="/bbs/w/''' + bbs_num_str + '''/''' + post_num_str + '''" type="submit">''' + load_lang('send') + '''</button>
+                        <button id="opennamu_preview_button" formaction="/bbs/w/preview/''' + bbs_num_str + '''/''' + post_num_str + '''#opennamu_edit_textarea" type="submit">''' + load_lang('preview') + '''</button>
+                        <hr class="main_hr">
+                    '''
+
+                data += '''
+                    <form method="post">
+                        ''' + bbs_comment_form + '''
+                        ''' + data_preview + '''
+                    </form>
+                '''
+
+                return easy_minify(flask.render_template(skin_check(),
+                    imp = [load_lang('bbs_main'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+                    data = data,
+                    menu = [['bbs/w/' + bbs_num_str, load_lang('return')], ['bbs/edit/' + bbs_num_str + '/' + post_num_str, load_lang('edit')]]
+                ))
+        else:
+            # db_data_2[0][0] == 'comment'
+            if flask.request.method == 'POST' and do_type != 'preview':
+                if bbs_comment_acl == 1:
+                    return redirect('/bbs/set/' + bbs_num_str)
+                
+                if captcha_post(flask.request.form.get('g-recaptcha-response', flask.request.form.get('g-recaptcha', ''))) == 1:
+                    return re_error('/error/13')
+                else:
+                    captcha_post('', 0)
+                
+                select = flask.request.form.get('comment_select', 'default')
+                select = '' if select == 'default' else select
+                if select != '':
+                    select = select.split('-')
+                    if len(select) < 2:
+                        curs.execute(db_change('select set_code from bbs_data where set_name = "comment" and set_id = ? and set_code = ? limit 1'), [bbs_num_str + '-' + post_num_str, select[0]])
+                        if not curs.fetchall():
+                            return ''
+                        else:
+                            set_id = bbs_num_str + '-' + post_num_str + '-' + select[0]
+                    else:
+                        curs.execute(db_change('select set_code from bbs_data where set_name = "comment" and set_id = ? and set_code = ? limit 1'), [bbs_num_str + '-' + post_num_str + '-' + '-'.join(select[0:len(select) - 1]), select[len(select) - 1]])
+                        if not curs.fetchall():
+                            return ''
+                        else:
+                            set_id = bbs_num_str + '-' + post_num_str + '-' + '-'.join(select)
+                else:
+                    set_id = bbs_num_str + '-' + post_num_str
+
+                curs.execute(db_change('select set_code from bbs_data where set_name = "comment" and set_id = ? order by set_code + 0 desc'), [set_id])
+                db_data = curs.fetchall()
+                id_data = str(int(db_data[0][0]) + 1) if db_data else '1'
+
+                data = flask.request.form.get('content', '')
+                if data == '':
+                    # re_error로 대체 예정
+                    return redirect('/bbs/w/' + bbs_num_str + '/' + post_num_str)
+
+                date = get_time()
+
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment', ?, ?, ?)"), [id_data, set_id, data])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment_date', ?, ?, ?)"), [id_data, set_id, date])
+                curs.execute(db_change("insert into bbs_data (set_name, set_code, set_id, set_data) values ('comment_user_id', ?, ?, ?)"), [id_data, set_id, ip])
+
+                conn.commit()
+            
+                if set_id == '':
+                    return redirect('/bbs/w/' + bbs_num_str + '/' + post_num_str + '#comment_' + id_data)
+                else:
+                    set_id = re.sub(r'^[0-9]+-[0-9]+-?', '', set_id)
+                    return redirect('/bbs/w/' + bbs_num_str + '/' + post_num_str + '#comment_' + set_id + '-' + id_data)
+            else:
+                if acl_check(bbs_num_str, 'bbs_view') == 1:
+                    return re_error('/ban')
+                    
+                if do_type == 'preview':
+                    text = flask.request.form.get('content', '')
+                    text = text.replace('\r', '')
+
+                    data_preview = render_set(
+                        doc_name = '', 
+                        doc_data = text,
+                        data_in = 'from'
+                    )
+                else:
+                    text = ''
+                    data_preview = ''
+
+                temp_id = ''
+                temp_dict = {}
+
+                db_data = list(db_data) if db_data else []
+                for for_a in db_data + [['', '', '']]:
+                    if temp_id != for_a[2]:
+                        temp_id = for_a[2]
+                        temp_dict['code'] = for_a[2]
+
+                    temp_dict[for_a[0]] = for_a[1]
+
+                data = ''
+                data += '<h2>' + html.escape(temp_dict['title']) + '</h2>'
+                data += bbs_w_post_make_thread(
+                    ip_pas(temp_dict['user_id']),
+                    temp_dict['date'],
+                    render_set(
+                        doc_name = '', 
+                        doc_data = temp_dict['data'],
+                        data_in = 'from'
+                    ),
+                    '0',
+                    color = 'red'
+                )
+
+                user_id = temp_dict['user_id']
+                temp_id = ''
+                temp_dict = {}
+                comment_data = ''
+
+                comment_select = '<hr class="main_hr"><select name="comment_select">'
+                comment_select += '<option value="default">' + load_lang('normal') + '</option>'
+
+                curs.execute(db_change('select set_name, set_data, set_code, set_id from bbs_data where (set_name = "comment" or set_name = "comment_date" or set_name = "comment_user_id") and set_id = ? order by set_code + 0 asc'), [bbs_num_str + '-' + post_num_str])
+                db_data = curs.fetchall()
+                if db_data:
+                    data += '<hr class="main_hr"><hr>'
+                else:
+                    db_data = []
+
+                for_a = 0
+                db_data_2 = db_data + [['', '', '', '']]
+                db_data_len = len(db_data_2)
+                comment_count = 0
+                comment_add_count = 0
+                while(for_a < db_data_len):
+                    if temp_id != (db_data_2[for_a][3] + '-' + db_data_2[for_a][2]):
+                        if temp_id != '':
+                            temp_dict['code'] = temp_id
+                            temp_dict['code'] = re.sub(r'^[0-9]+-[0-9]+-', '', temp_dict['code'])
+
+                            if user_id == temp_dict['comment_user_id']:
+                                color = 'green'
+                            else:
+                                color = 'default'
+
+                            margin_count = temp_dict['code'].count('-')
+                            if margin_count == 0:
+                                comment_count += 1
+                            else:
+                                comment_add_count += 1
+
+                            comment_data += '<span style="padding-left: 20px;"></span>' * margin_count
+                            comment_data += bbs_w_post_make_thread(
+                                ip_pas(temp_dict['comment_user_id']),
+                                temp_dict['comment_date'],
+                                render_set(
+                                    doc_name = '', 
+                                    doc_data = temp_dict['comment'],
+                                    data_in = 'from'
+                                ),
+                                temp_dict['code'],
+                                color = color,
+                                add_style = 'width: calc(100% - ' + str(margin_count * 20) + 'px);'
+                            )
+
+                            comment_select += '<option value="' + temp_dict['code'] + '">' + temp_dict['code'] + '</option>'
+
+                            curs.execute(db_change('select set_name, set_data, set_code, set_id from bbs_data where (set_name = "comment" or set_name = "comment_date" or set_name = "comment_user_id") and set_id = ? order by set_code + 0 asc'), [bbs_num_str + '-' + post_num_str + '-' + temp_dict['code']])
+                            db_data = curs.fetchall()
+                            if db_data:
+                                db_data_2 = db_data_2[:for_a] + db_data + db_data_2[for_a:]
+                                db_data_len += len(db_data)
+
+                            if db_data_2[for_a][0] != '':
+                                comment_data += '<hr class="main_hr">'
+
+                        temp_id = db_data_2[for_a][3] + '-' + db_data_2[for_a][2]
+
+                    temp_dict[db_data_2[for_a][0]] = db_data_2[for_a][1]
+                    for_a += 1
+
+                comment_select += '</select>'
+                if comment_data != '':
+                    data += load_lang('comment') + ' : ' + str(comment_count) + '<hr class="main_hr">'
+                    data += load_lang('reply') + ' : ' + str(comment_add_count) + '<hr class="main_hr">'
+                    data += comment_data
+
+                bbs_comment_form = ''
+                if bbs_comment_acl == 0:
+                    bbs_comment_form = '''
+                        ''' + comment_select + '''
+                        <hr class="main_hr">
+                        
+                        <textarea name="content" id="opennamu_edit_textarea" class="opennamu_textarea_100">''' + html.escape(text) + '''</textarea>
+                        <hr class="main_hr">
+                        
+                        ''' + captcha_get() + ip_warning() + '''
+
+                        <button id="opennamu_save_button" formaction="/bbs/w/''' + bbs_num_str + '''/''' + post_num_str + '''" type="submit">''' + load_lang('send') + '''</button>
+                        <button id="opennamu_preview_button" formaction="/bbs/w/preview/''' + bbs_num_str + '''/''' + post_num_str + '''#opennamu_edit_textarea" type="submit">''' + load_lang('preview') + '''</button>
+                        <hr class="main_hr">
+                    '''
+
+                data += '''
+                    <form method="post">
+                        ''' + bbs_comment_form + '''
+                        ''' + data_preview + '''
+                    </form>
+                '''
+
+                return easy_minify(flask.render_template(skin_check(),
+                    imp = [load_lang('bbs_main'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+                    data = data,
+                    menu = [['bbs/w/' + bbs_num_str, load_lang('return')], ['bbs/edit/' + bbs_num_str + '/' + post_num_str, load_lang('edit')]]
+                ))

+ 94 - 0
route/bbs_w_set.py

@@ -0,0 +1,94 @@
+from .tool.func import *
+
+def bbs_w_set(bbs_num = ''):
+    with get_db_connect() as conn:
+        curs = conn.cursor()
+
+        curs.execute(db_change('select set_id from bbs_set where set_id = ? and set_name = "bbs_name"'), [bbs_num])
+        if not curs.fetchall():
+            return redirect('/bbs/main')
+
+        i_list = {
+            1 : 'bbs_acl',
+            2 : 'bbs_edit_acl',
+            3 : 'bbs_comment_acl',
+            4 : 'bbs_view_acl'
+        }
+        bbs_num_str = str(bbs_num)
+
+        if flask.request.method == 'POST':
+            if admin_check(None, 'bbs_set (acl)') != 1:
+                return re_error('/ban')
+            else:
+                for i in i_list:
+                    curs.execute(db_change("update bbs_set set set_data = ? where set_name = ? and set_id = ?"), [
+                        flask.request.form.get(i_list[i], 'normal'),
+                        i_list[i],
+                        bbs_num
+                    ])
+
+                conn.commit()
+
+                return redirect('/bbs/set/' + bbs_num_str)
+        else:
+            d_list = {}
+
+            if admin_check() != 1:
+                disable = 'disabled'
+            else:
+                disable = ''
+
+            for i in i_list:
+                curs.execute(db_change('select set_data from bbs_set where set_name = ? and set_id = ?'), [i_list[i], bbs_num])
+                sql_d = curs.fetchall()
+                if sql_d:
+                    d_list[i] = sql_d[0][0]
+                else:
+                    curs.execute(db_change('insert into bbs_set (set_name, set_code, set_id, set_data) values (?, "", ?, ?)'), [i_list[i], bbs_num, 'normal'])
+                    d_list[i] = 'normal'
+
+            conn.commit()
+
+            acl_div = []
+            for i in range(0, len(i_list)):
+                acl_div += ['']
+
+            acl_list = get_acl_list()
+            for i in range(0, len(i_list)):
+                for data_list in acl_list:
+                    if data_list == d_list[i + 1]:
+                        check = 'selected="selected"'
+                    else:
+                        check = ''
+
+                    acl_div[i] += '<option value="' + data_list + '" ' + check + '>' + (data_list if data_list != '' else 'normal') + '</option>'
+
+            return easy_minify(flask.render_template(skin_check(),
+                imp = [load_lang('main_acl_setting'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
+                data = render_simple_set('''
+                    <form method="post">
+                        <hr class="main_hr">
+                        <a href="/acl/TEST#exp">(''' + load_lang('reference') + ''')</a>
+                        
+                        <h2>''' + load_lang('acl') + '''</h2>
+                        <h3>''' + load_lang('bbs_view_acl') + '''</h3>
+                        <select ''' + disable + ''' name="bbs_view_acl">''' + acl_div[3] + '''</select>
+
+                        <h4>''' + load_lang('bbs_acl') + '''</h4>
+                        <select ''' + disable + ''' name="bbs_acl">''' + acl_div[0] + '''</select>
+
+                        <h5>''' + load_lang('bbs_edit_acl') + '''</h5>
+                        <select ''' + disable + ''' name="bbs_edit_acl">''' + acl_div[1] + '''</select>
+
+                        <h5>''' + load_lang('bbs_comment_acl') + '''</h5>
+                        <select ''' + disable + ''' name="bbs_comment_acl">''' + acl_div[2] + '''</select>
+
+                        <h2>''' + load_lang('markup') + '''</h2>
+                        ''' + load_lang('not_working') + '''
+                        
+                        <hr class="main_hr">
+                        <button id="opennamu_save_button" type="submit">''' + load_lang('save') + '''</button>
+                    </form>
+                '''),
+                menu = [['bbs/w/' + bbs_num_str, load_lang('return')]]
+            ))

+ 15 - 7
route/edit_delete_file.py

@@ -1,24 +1,27 @@
 from .tool.func import *
 from .tool.func import *
+from .edit_delete import edit_delete
 
 
-def edit_delete_file(name = 'test.jpg'):
+# 처음으로 차세대 코드 방법론 적용
+# 앞으로 다 이렇게 작성할 예정
+def edit_delete_file(name : str = 'test.jpg') -> str:
     with get_db_connect() as conn:
     with get_db_connect() as conn:
-        curs = conn.cursor()
+        curs : typing.Union[sqlite3.dbapi2.Cursor, pymysql.cursors.Cursor, None] = conn.cursor()
 
 
-        ip = ip_check()
+        ip : str = ip_check()
         if admin_check() == 0:
         if admin_check() == 0:
             return re_error('/ban')
             return re_error('/ban')
 
 
-        mime_type = re.search(r'([^.]+)$', name)
+        mime_type : typing.Union[re.Match, None] = re.search(r'([^.]+)$', name)
         if mime_type:
         if mime_type:
             mime_type = mime_type.group(1).lower()
             mime_type = mime_type.group(1).lower()
         else:
         else:
             mime_type = 'jpg'
             mime_type = 'jpg'
 
 
-        file_name = re.sub(r'\.([^.]+)$', '', name)
+        file_name : str = re.sub(r'\.([^.]+)$', '', name)
         file_name = re.sub(r'^file:', '', file_name)
         file_name = re.sub(r'^file:', '', file_name)
 
 
-        file_all_name = sha224_replace(file_name) + '.' + mime_type
-        file_directory = os.path.join(load_image_url(), file_all_name)
+        file_all_name : str = sha224_replace(file_name) + '.' + mime_type
+        file_directory : str = os.path.join(load_image_url(), file_all_name)
 
 
         if not os.path.exists(file_directory):
         if not os.path.exists(file_directory):
             return redirect('/w/' + url_pas(name))
             return redirect('/w/' + url_pas(name))
@@ -27,6 +30,9 @@ def edit_delete_file(name = 'test.jpg'):
             admin_check(None, 'file del (' + name + ')')
             admin_check(None, 'file del (' + name + ')')
             os.remove(file_directory)
             os.remove(file_directory)
 
 
+            if flask.request.form.get('with_doc', '') != '':
+                edit_delete(name)
+
             return redirect('/w/' + url_pas(name))
             return redirect('/w/' + url_pas(name))
         else:
         else:
             return easy_minify(flask.render_template(skin_check(),
             return easy_minify(flask.render_template(skin_check(),
@@ -37,6 +43,8 @@ def edit_delete_file(name = 'test.jpg'):
                         <hr class="main_hr">
                         <hr class="main_hr">
                         <a href="/image/''' + url_pas(file_all_name) + '''">/image/''' + url_pas(file_all_name) + '''</a>
                         <a href="/image/''' + url_pas(file_all_name) + '''">/image/''' + url_pas(file_all_name) + '''</a>
                         <hr class="main_hr">
                         <hr class="main_hr">
+                        <input name="with_doc" type="checkbox" checked> ''' + load_lang('file_delete_with_document') + '''
+                        <hr class="main_hr">
                         <button type="submit">''' + load_lang('file_delete') + '''</button>
                         <button type="submit">''' + load_lang('file_delete') + '''</button>
                     </form>
                     </form>
                 ''',
                 ''',

+ 2 - 2
route/edit_delete_multiple.py

@@ -1,5 +1,5 @@
 from .tool.func import *
 from .tool.func import *
-from . import edit_delete
+from .edit_delete import edit_delete
 
 
 def edit_delete_multiple():
 def edit_delete_multiple():
     with get_db_connect() as conn:
     with get_db_connect() as conn:
@@ -21,7 +21,7 @@ def edit_delete_multiple():
             
             
             all_title = re.findall(r'([^\n]+)\n', flask.request.form.get('content', '').replace('\r', '') + '\n')
             all_title = re.findall(r'([^\n]+)\n', flask.request.form.get('content', '').replace('\r', '') + '\n')
             for name in all_title:
             for name in all_title:
-                edit_delete.edit_delete(name)
+                edit_delete(name)
 
 
             return redirect('/recent_change')
             return redirect('/recent_change')
         else:
         else:

+ 8 - 7
route/give_admin.py → route/give_auth.py

@@ -1,10 +1,11 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def give_admin_2(name):
+def give_auth(name):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
-        owner = admin_check()
+        owner_auth = admin_check()
+        admin_auth = admin_check(7)
 
 
         curs.execute(db_change("select data from user_set where id = ? and name = 'acl'"), [name])
         curs.execute(db_change("select data from user_set where id = ? and name = 'acl'"), [name])
         user_acl = curs.fetchall()
         user_acl = curs.fetchall()
@@ -13,7 +14,7 @@ def give_admin_2(name):
         else:
         else:
             user_acl = user_acl[0][0]
             user_acl = user_acl[0][0]
 
 
-        if owner != 1:
+        if owner_auth != 1:
             curs.execute(db_change('select name from alist where name = ? and acl = "owner"'), [user_acl])
             curs.execute(db_change('select name from alist where name = ? and acl = "owner"'), [user_acl])
             if curs.fetchall():
             if curs.fetchall():
                 return re_error('/error/3')
                 return re_error('/error/3')
@@ -31,7 +32,7 @@ def give_admin_2(name):
                 select_data = flask.request.form.get('select', 'X')
                 select_data = flask.request.form.get('select', 'X')
 
 
             curs.execute(db_change('select name from alist where name = ? and acl = "owner"'), [select_data])
             curs.execute(db_change('select name from alist where name = ? and acl = "owner"'), [select_data])
-            if owner != 1 and curs.fetchall():
+            if owner_auth != 1 and curs.fetchall():
                 return re_error('/error/3')
                 return re_error('/error/3')
 
 
             curs.execute(db_change("update user_set set data = ? where id = ? and name = 'acl'"), [
             curs.execute(db_change("update user_set set data = ? where id = ? and name = 'acl'"), [
@@ -41,12 +42,12 @@ def give_admin_2(name):
 
 
             conn.commit()
             conn.commit()
 
 
-            return redirect('/admin/' + url_pas(name))
+            return redirect('/auth/give/' + url_pas(name))
         else:
         else:
-            if admin_check(7) != 1:
+            if admin_auth != 1:
                 return re_error('/error/3')
                 return re_error('/error/3')
 
 
-            div = '<option value="X">X</option>'
+            div = '<option value="X">' + load_lang('normal') + '</option>'
 
 
             curs.execute(db_change('select distinct name from alist order by name asc'))
             curs.execute(db_change('select distinct name from alist order by name asc'))
             for data in curs.fetchall():
             for data in curs.fetchall():

+ 4 - 4
route/list_acl.py

@@ -1,11 +1,11 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_acl_2():
+def list_acl(arg_num = 1):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
-        num = int(number_check(flask.request.args.get('num', '1')))
-        sql_num = (num * 50 - 50) if num * 50 > 0 else 0
+        sql_num = (arg_num * 50 - 50) if arg_num * 50 > 0 else 0
+
         div = '<ul class="opennamu_ul">'
         div = '<ul class="opennamu_ul">'
 
 
         curs.execute(db_change(
         curs.execute(db_change(
@@ -30,7 +30,7 @@ def list_acl_2():
             ''
             ''
 
 
         div += '</ul>'
         div += '</ul>'
-        div += next_fix('/acl_list?num=', num, list_data)
+        div += next_fix('/list/document/acl/', arg_num, list_data)
 
 
         return easy_minify(flask.render_template(skin_check(),
         return easy_minify(flask.render_template(skin_check(),
             imp = [load_lang('acl_document_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
             imp = [load_lang('acl_document_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],

+ 1 - 1
route/list_admin.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_admin_2():
+def list_admin():
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 

+ 4 - 3
route/list_admin_use.py → route/list_admin_auth_use.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_admin_use(arg_num = 1, arg_search = 'normal'):
+def list_admin_auth_use(arg_num = 1, arg_search = 'normal'):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
@@ -35,12 +35,13 @@ def list_admin_use(arg_num = 1, arg_search = 'normal'):
             list_data += '</ul>'
             list_data += '</ul>'
             list_data += next_fix('/list/admin/auth_use/' + url_pas(arg_search) + '/', arg_num, get_list)
             list_data += next_fix('/list/admin/auth_use/' + url_pas(arg_search) + '/', arg_num, get_list)
 
 
+            arg_search = html.escape(arg_search) if arg_search != 'normal' else ''
+
             return easy_minify(flask.render_template(skin_check(),
             return easy_minify(flask.render_template(skin_check(),
                 imp = [load_lang('authority_use_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
                 imp = [load_lang('authority_use_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
                 data = '''
                 data = '''
                     <form method="post">
                     <form method="post">
-                        <input name="search">
-                        <hr class="main_hr">
+                        <input class="opennamu_width_200" name="search" value="''' + arg_search + '''">
                         <button type="submit">''' + load_lang('search') + '''</button>
                         <button type="submit">''' + load_lang('search') + '''</button>
                     </form>
                     </form>
                     <hr class="main_hr">
                     <hr class="main_hr">

+ 2 - 3
route/list_image_file.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_image_file_2():
+def list_image_file():
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
@@ -8,14 +8,13 @@ def list_image_file_2():
         sql_num = (num * 50 - 50) if num * 50 > 0 else 0
         sql_num = (num * 50 - 50) if num * 50 > 0 else 0
 
 
         list_data = '<ul class="opennamu_ul">'
         list_data = '<ul class="opennamu_ul">'
-        back = ''
 
 
         curs.execute(db_change("select title from data where title like 'file:%' limit ?, 50"), [sql_num])
         curs.execute(db_change("select title from data where title like 'file:%' limit ?, 50"), [sql_num])
         data_list = curs.fetchall()
         data_list = curs.fetchall()
         for data in data_list:
         for data in data_list:
             list_data += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a></li>'
             list_data += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a></li>'
 
 
-        list_data += next_fix('/image_file_list?num=', num, data_list)
+        list_data += next_fix('/list/file/', num, data_list)
 
 
         return easy_minify(flask.render_template(skin_check(),
         return easy_minify(flask.render_template(skin_check(),
             imp = [load_lang('image_file_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
             imp = [load_lang('image_file_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],

+ 1 - 1
route/list_long_page.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_long_page_2(tool):
+def list_long_page(tool = 'long_page'):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 

+ 3 - 4
route/list_please.py

@@ -1,11 +1,10 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_please_2():
+def list_please(arg_num = 1):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
-        num = int(number_check(flask.request.args.get('num', '1')))
-        sql_num = (num * 50 - 50) if num * 50 > 0 else 0
+        sql_num = (arg_num * 50 - 50) if arg_num * 50 > 0 else 0
 
 
         curs.execute(db_change('select data from other where name = "count_all_title"'))
         curs.execute(db_change('select data from other where name = "count_all_title"'))
         if int(curs.fetchall()[0][0]) > 30000:
         if int(curs.fetchall()[0][0]) > 30000:
@@ -23,7 +22,7 @@ def list_please_2():
                 '</li>' + \
                 '</li>' + \
             ''
             ''
 
 
-        div += '</ul>' + next_fix('/please?num=', num, data_list)
+        div += '</ul>' + next_fix('/list/document/need/', arg_num, data_list)
 
 
         return easy_minify(flask.render_template(skin_check(),
         return easy_minify(flask.render_template(skin_check(),
             imp = [load_lang('need_document'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
             imp = [load_lang('need_document'), wiki_set(), wiki_custom(), wiki_css([0, 0])],

+ 3 - 4
route/list_user.py

@@ -1,11 +1,10 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def list_user_2():
+def list_user(arg_num = 1):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 
-        num = int(number_check(flask.request.args.get('num', '1')))
-        sql_num = (num * 50 - 50) if num * 50 > 0 else 0
+        sql_num = (arg_num * 50 - 50) if arg_num * 50 > 0 else 0
 
 
         list_data = '<ul class="opennamu_ul">'
         list_data = '<ul class="opennamu_ul">'
 
 
@@ -18,7 +17,7 @@ def list_user_2():
                 '</li>' + \
                 '</li>' + \
             ''
             ''
 
 
-        list_data += '</ul>' + next_fix('/user_log?num=', num, user_list)
+        list_data += '</ul>' + next_fix('/list/user/', arg_num, user_list)
 
 
         return easy_minify(flask.render_template(skin_check(),
         return easy_minify(flask.render_template(skin_check(),
             imp = [load_lang('member_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
             imp = [load_lang('member_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],

+ 59 - 46
route/main_search_deep.py

@@ -9,58 +9,71 @@ def main_search_deep(name = 'Test', search_type = 'title', num = 1):
 
 
         sql_num = (num * 50 - 50) if num * 50 > 0 else 0
         sql_num = (num * 50 - 50) if num * 50 > 0 else 0
 
 
-        div = ''
-        if search_type == 'title':
-            div += '<a href="/search_data/1/' + url_pas(name) + '">(' + load_lang('search_document_data') + ')</a>'
+        if flask.request.method == 'POST':
+            if search_type == 'title':
+                return redirect('/search/1/' + url_pas(flask.request.form.get('search', 'test')))
+            else:
+                return redirect('/search_data/1/' + url_pas(flask.request.form.get('search', 'test')))
         else:
         else:
-            div += '<a href="/search/1/' + url_pas(name) + '">(' + load_lang('search_document_name') + ')</a>'
+            div = '''
+                <form method="post">
+                    <input class="opennamu_width_200" name="search" value="''' + html.escape(name) + '''">
+                    <button type="submit">''' + load_lang('search') + '''</button>
+                </form>
+                <hr class="main_hr">
+            '''
 
 
-        name_new = ''
-        if re.search(r'^분류:', name):
-            name_new = re.sub(r"^분류:", 'category:', name)
-        elif re.search(r"^사용자:", name):
-            name_new = re.sub(r"^사용자:", 'user:', name)
-        elif re.search(r"^파일:", name):
-            name_new = re.sub(r"^파일:", 'file:', name)
+            if search_type == 'title':
+                div += '<a href="/search_data/1/' + url_pas(name) + '">(' + load_lang('search_document_data') + ')</a>'
+            else:
+                div += '<a href="/search/1/' + url_pas(name) + '">(' + load_lang('search_document_name') + ')</a>'
 
 
-        if name_new != '':
-            div += ' <a href="/search/1/' + url_pas(name_new) + '">(' + name_new + ')</a>'
+            name_new = ''
+            if re.search(r'^분류:', name):
+                name_new = re.sub(r"^분류:", 'category:', name)
+            elif re.search(r"^사용자:", name):
+                name_new = re.sub(r"^사용자:", 'user:', name)
+            elif re.search(r"^파일:", name):
+                name_new = re.sub(r"^파일:", 'file:', name)
 
 
-        curs.execute(db_change("select title from data where title = ?"), [name])
-        link_id = '' if curs.fetchall() else 'class="opennamu_not_exist_link"'
+            if name_new != '':
+                div += ' <a href="/search/1/' + url_pas(name_new) + '">(' + name_new + ')</a>'
 
 
-        div += '''
-            <ul class="opennamu_ul">
-                <li>
-                    <a ''' + link_id + ' href="/w/' + url_pas(name) + '">' + html.escape(name) + '''</a>
-                </li>
-            </ul>
-            <hr class="main_hr">
-            <ul class="opennamu_ul">
-        '''
+            curs.execute(db_change("select title from data where title = ? collate nocase"), [name])
+            link_id = '' if curs.fetchall() else 'class="opennamu_not_exist_link"'
 
 
-        if search_type == 'title':
-            curs.execute(db_change("select title from data where title like ? order by title limit ?, 50"),
-                ['%' + name + '%', sql_num]
-            )
-        else:
-            curs.execute(db_change("select title from data where data like ? order by title limit ?, 50"),
-                ['%' + name + '%', sql_num]
-            )
+            div += '''
+                <ul class="opennamu_ul">
+                    <li>
+                        <a ''' + link_id + ' href="/w/' + url_pas(name) + '">' + html.escape(name) + '''</a>
+                    </li>
+                </ul>
+                <hr class="main_hr">
+                <ul class="opennamu_ul">
+            '''
 
 
-        all_list = curs.fetchall()
-        for data in all_list:
-            div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+            if search_type == 'title':
+                curs.execute(db_change("select title from data where title like ? collate nocase order by title limit ?, 50"),
+                    ['%' + name + '%', sql_num]
+                )
+            else:
+                curs.execute(db_change("select title from data where data like ? collate nocase order by title limit ?, 50"),
+                    ['%' + name + '%', sql_num]
+                )
 
 
-        div += '</ul>'
-        
-        if search_type == 'title':
-            div += get_next_page_bottom('/search/{}/' + url_pas(name), num, all_list)
-        else:
-            div += get_next_page_bottom('/search_data/{}/' + url_pas(name), num, all_list)
+            all_list = curs.fetchall()
+            for data in all_list:
+                div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+
+            div += '</ul>'
+            
+            if search_type == 'title':
+                div += get_next_page_bottom('/search/{}/' + url_pas(name), num, all_list)
+            else:
+                div += get_next_page_bottom('/search_data/{}/' + url_pas(name), num, all_list)
 
 
-        return easy_minify(flask.render_template(skin_check(),
-            imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('search') + ')', 0])],
-            data = div,
-            menu = 0
-        ))
+            return easy_minify(flask.render_template(skin_check(),
+                imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('search') + ')', 0])],
+                data = div,
+                menu = 0
+            ))

+ 4 - 4
route/main_search_goto.py

@@ -9,9 +9,9 @@ def main_search_goto(name = 'Test'):
         else:
         else:
             data = name
             data = name
 
 
-        curs.execute(db_change("select title from data where title = ?"), [data])
-        t_data = curs.fetchall()
-        if t_data:
-            return redirect('/w/' + url_pas(data))
+        curs.execute(db_change("select title from data where title = ? collate nocase"), [data])
+        db_data = curs.fetchall()
+        if db_data:
+            return redirect('/w/' + url_pas(db_data[0][0]))
         else:
         else:
             return redirect('/search/' + url_pas(data))
             return redirect('/search/' + url_pas(data))

+ 0 - 1
route/main_setting_acl.py

@@ -46,7 +46,6 @@ def main_setting_acl():
                     d_list[i] = sql_d[0][0]
                     d_list[i] = sql_d[0][0]
                 else:
                 else:
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i_list[i], 'normal'])
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i_list[i], 'normal'])
-
                     d_list[i] = 'normal'
                     d_list[i] = 'normal'
 
 
             conn.commit()
             conn.commit()

+ 0 - 1
route/main_setting_external.py

@@ -43,7 +43,6 @@ def main_setting_external():
                     d_list += [sql_d[0][0]]
                     d_list += [sql_d[0][0]]
                 else:
                 else:
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i, ''])
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i, ''])
-
                     d_list += ['']
                     d_list += ['']
 
 
                 x += 1
                 x += 1

+ 26 - 25
route/main_setting_main.py

@@ -35,7 +35,11 @@ def main_setting_main(db_set):
             31 : ['wiki_access_password_need', ''],
             31 : ['wiki_access_password_need', ''],
             32 : ['wiki_access_password', ''],
             32 : ['wiki_access_password', ''],
             33 : ['history_recording_off', ''],
             33 : ['history_recording_off', ''],
-            34 : ['namumark_compatible', '']
+            34 : ['namumark_compatible', ''],
+            35 : ['user_name_view', ''],
+            36 : ['link_case_insensitive', ''],
+            37 : ['move_with_redirect', ''],
+            38 : ['slow_thread', '']
         }
         }
 
 
         if flask.request.method == 'POST':
         if flask.request.method == 'POST':
@@ -85,31 +89,13 @@ def main_setting_main(db_set):
                 else:
                 else:
                     tls_select += '<option value="' + tls_select_one + '">' + tls_select_one + '</option>'
                     tls_select += '<option value="' + tls_select_one + '">' + tls_select_one + '</option>'
 
 
-            check_box_div = ['', '', '', '', '', '', '', '', '', '', '']
+            check_box_div = [7, 8, '', 20, 23, 24, 25, 26, 31, 33, 34, 35, 36, 37]
             for i in range(0, len(check_box_div)):
             for i in range(0, len(check_box_div)):
-                if i == 0:
-                    acl_num = 7
-                elif i == 1:
-                    acl_num = 8
-                elif i == 3:
-                    acl_num = 20
-                elif i == 4:
-                    acl_num = 23
-                elif i == 5:
-                    acl_num = 24
-                elif i == 6:
-                    acl_num = 25
-                elif i == 7:
-                    acl_num = 26
-                elif i == 8:
-                    acl_num = 31
-                elif i == 9:
-                    acl_num = 33
-                elif i == 10:
-                    acl_num = 34
-
-                if d_list[acl_num]:
+                acl_num = check_box_div[i]
+                if acl_num != '' and d_list[acl_num]:
                     check_box_div[i] = 'checked="checked"'
                     check_box_div[i] = 'checked="checked"'
+                else:
+                    check_box_div[i] = ''
 
 
             branch_div = ''
             branch_div = ''
             branch_list = ['stable', 'dev', 'beta']
             branch_list = ['stable', 'dev', 'beta']
@@ -187,8 +173,12 @@ def main_setting_main(db_set):
                         <hr class="main_hr">
                         <hr class="main_hr">
                         <select name="skin">''' + load_skin(d_list[5] if d_list[5] != '' else 'ringo') + '''</select>
                         <select name="skin">''' + load_skin(d_list[5] if d_list[5] != '' else 'ringo') + '''</select>
 
 
-                        <hr class="main_hr">
+                        <h2>''' + load_lang('render_set') + '''</h2>
                         <input type="checkbox" name="namumark_compatible" ''' + check_box_div[10] + '''> ''' + load_lang('namumark_fully_compatible_mode') + '''
                         <input type="checkbox" name="namumark_compatible" ''' + check_box_div[10] + '''> ''' + load_lang('namumark_fully_compatible_mode') + '''
+                        <hr class="main_hr">
+                        
+                        <input type="checkbox" name="link_case_insensitive" ''' + check_box_div[12] + '''> ''' + load_lang('link_case_insensitive') + '''
+                        <hr class="main_hr">
 
 
                         <h2>''' + load_lang('login_set') + '''</h2>
                         <h2>''' + load_lang('login_set') + '''</h2>
                         <input type="checkbox" name="reg" ''' + check_box_div[0] + '''> ''' + load_lang('no_register') + '''
                         <input type="checkbox" name="reg" ''' + check_box_div[0] + '''> ''' + load_lang('no_register') + '''
@@ -197,6 +187,9 @@ def main_setting_main(db_set):
                         <input type="checkbox" name="ip_view" ''' + check_box_div[1] + '''> ''' + load_lang('hide_ip') + '''
                         <input type="checkbox" name="ip_view" ''' + check_box_div[1] + '''> ''' + load_lang('hide_ip') + '''
                         <hr class="main_hr">
                         <hr class="main_hr">
 
 
+                        <input type="checkbox" name="user_name_view" ''' + check_box_div[11] + '''> ''' + load_lang('hide_user_name') + '''
+                        <hr class="main_hr">
+
                         <input type="checkbox" name="requires_approval" ''' + check_box_div[3] + '''> ''' + load_lang('requires_approval') + '''
                         <input type="checkbox" name="requires_approval" ''' + check_box_div[3] + '''> ''' + load_lang('requires_approval') + '''
                         <hr class="main_hr">
                         <hr class="main_hr">
 
 
@@ -261,6 +254,14 @@ def main_setting_main(db_set):
                         <input type="checkbox" name="history_recording_off" ''' + check_box_div[9] + '''> ''' + load_lang('set_history_recording_off') + ''' (''' + load_lang('beta') + ''')
                         <input type="checkbox" name="history_recording_off" ''' + check_box_div[9] + '''> ''' + load_lang('set_history_recording_off') + ''' (''' + load_lang('beta') + ''')
                         <hr class="main_hr">
                         <hr class="main_hr">
 
 
+                        <input type="checkbox" name="move_with_redirect" ''' + check_box_div[13] + '''> ''' + load_lang('move_with_redirect') + '''
+                        <hr class="main_hr">
+
+                        <span>''' + load_lang('slow_thread') + ''' (''' + load_lang('second') + ''') (''' + load_lang('off') + ''' : ''' + load_lang('empty') + ''') (''' + load_lang('not_working') + ''')</span>
+                        <hr class="main_hr">
+                        <input name="slow_thread" value="''' + html.escape(d_list[38]) + '''">
+                        <hr class="main_hr">
+
                         <button id="opennamu_save_button" type="submit">''' + load_lang('save') + '''</button>
                         <button id="opennamu_save_button" type="submit">''' + load_lang('save') + '''</button>
                     </form>
                     </form>
                 '''),
                 '''),

+ 0 - 1
route/main_setting_phrase.py

@@ -52,7 +52,6 @@ def main_setting_phrase():
                     d_list += [sql_d[0][0]]
                     d_list += [sql_d[0][0]]
                 else:
                 else:
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i, ''])
                     curs.execute(db_change('insert into other (name, data, coverage) values (?, ?, "")'), [i, ''])
-
                     d_list += ['']
                     d_list += ['']
 
 
             conn.commit()
             conn.commit()

+ 10 - 1
route/main_setting_skin_set.py

@@ -62,10 +62,19 @@ def main_setting_skin_set():
                         <select name="main_css_category_set">
                         <select name="main_css_category_set">
                             ''' + set_data["main_css_category_set"] + '''
                             ''' + set_data["main_css_category_set"] + '''
                         </select>
                         </select>
-                        <h3>''' + load_lang("footnote") + '''</h3>
+                        <h3>''' + load_lang("footnote") + ''' (''' + load_lang('beta') + ''')</h3>
+                        <h4>''' + load_lang("footnote_render") + '''</h4>
                         <select name="main_css_footnote_set">
                         <select name="main_css_footnote_set">
                             ''' + set_data["main_css_footnote_set"] + '''
                             ''' + set_data["main_css_footnote_set"] + '''
                         </select>
                         </select>
+                        <h4>''' + load_lang("footnote_number") + '''</h4>
+                        <select name="main_css_footnote_number">
+                            ''' + set_data["main_css_footnote_number"] + '''
+                        </select>
+                        <h4>''' + load_lang("footnote_real_num_view") + '''</h4>
+                        <select name="main_css_view_real_footnote_num">
+                            ''' + set_data["main_css_view_real_footnote_num"] + '''
+                        </select>
                         <h3>''' + load_lang("include_link") + '''</h3>
                         <h3>''' + load_lang("include_link") + '''</h3>
                         <select name="main_css_include_link">
                         <select name="main_css_include_link">
                             ''' + set_data["main_css_include_link"] + '''
                             ''' + set_data["main_css_include_link"] + '''

+ 7 - 7
route/main_tool_other.py

@@ -13,7 +13,7 @@ def main_tool_other():
                 <h2>''' + load_lang('list') + '''</h2>
                 <h2>''' + load_lang('list') + '''</h2>
                 <h3>''' + load_lang('admin') + '''</h3>
                 <h3>''' + load_lang('admin') + '''</h3>
                 <ul class="opennamu_ul">               
                 <ul class="opennamu_ul">               
-                    <li><a href="/admin_list">''' + load_lang('admin_list') + '''</a></li>
+                    <li><a href="/list/admin">''' + load_lang('admin_list') + '''</a></li>
                     <li><a href="/list/admin/auth_use">''' + load_lang('authority_use_list') + '''</a></li>
                     <li><a href="/list/admin/auth_use">''' + load_lang('authority_use_list') + '''</a></li>
                 </ul>
                 </ul>
                 <h3>''' + load_lang('discussion') + '''</h3>
                 <h3>''' + load_lang('discussion') + '''</h3>
@@ -24,20 +24,20 @@ def main_tool_other():
                 <ul class="opennamu_ul">
                 <ul class="opennamu_ul">
                     <li><a href="/recent_change">''' + load_lang('recent_change') + '''</a></li>
                     <li><a href="/recent_change">''' + load_lang('recent_change') + '''</a></li>
                     <li><a href="/list/document/all">''' + load_lang('all_document_list') + '''</a></li>
                     <li><a href="/list/document/all">''' + load_lang('all_document_list') + '''</a></li>
-                    <li><a href="/acl_list">''' + load_lang('acl_document_list') + '''</a></li>
-                    <li><a href="/please">''' + load_lang('need_document') + '''</a></li>
-                    <li><a href="/long_page">''' + load_lang('long_page') + '''</a></li>
-                    <li><a href="/short_page">''' + load_lang('short_page') + '''</a></li>
+                    <li><a href="/list/document/acl">''' + load_lang('acl_document_list') + '''</a></li>
+                    <li><a href="/list/document/need">''' + load_lang('need_document') + '''</a></li>
+                    <li><a href="/list/document/long">''' + load_lang('long_page') + '''</a></li>
+                    <li><a href="/list/document/short">''' + load_lang('short_page') + '''</a></li>
                     <li><a href="/list/document/old">''' + load_lang('old_page') + '''</a></li>
                     <li><a href="/list/document/old">''' + load_lang('old_page') + '''</a></li>
                 </ul>
                 </ul>
                 <h3>''' + load_lang('user') + '''</h3>
                 <h3>''' + load_lang('user') + '''</h3>
                 <ul class="opennamu_ul">
                 <ul class="opennamu_ul">
                     <li><a href="/block_log">''' + load_lang('recent_ban') + '''</a></li>
                     <li><a href="/block_log">''' + load_lang('recent_ban') + '''</a></li>
-                    <li><a href="/user_log">''' + load_lang('member_list') + '''</a></li>
+                    <li><a href="/list/user">''' + load_lang('member_list') + '''</a></li>
                 </ul>
                 </ul>
                 <h3>''' + load_lang('other') + '''</h3>
                 <h3>''' + load_lang('other') + '''</h3>
                 <ul class="opennamu_ul">
                 <ul class="opennamu_ul">
-                    <li><a href="/image_file_list">''' + load_lang('image_file_list') + '''</a></li>
+                    <li><a href="/list/file">''' + load_lang('image_file_list') + '''</a></li>
                     <li><a href="/vote">''' + load_lang('vote_list') + '''</a></li>
                     <li><a href="/vote">''' + load_lang('vote_list') + '''</a></li>
                     <li><a href="/bbs/main">''' + load_lang('bbs_main') + '''</a></li>
                     <li><a href="/bbs/main">''' + load_lang('bbs_main') + '''</a></li>
                 </ul>
                 </ul>

+ 19 - 19
route/main_tool_redirect.py

@@ -3,28 +3,28 @@ from .tool.func import *
 def main_tool_redirect(num = 1, add_2 = ''):
 def main_tool_redirect(num = 1, add_2 = ''):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         title_list = {
         title_list = {
-            0 : [load_lang('document_name'), 'acl', load_lang('acl')],
-            1 : [0, 'check', load_lang('check')],
-            2 : [load_lang('file_name'), 'file_filter/add', load_lang('file_filter_add')],
-            3 : [0, 'admin', load_lang('authorize')],
-            4 : [0, 'record', load_lang('edit_record')],
-            5 : [0, 'record/topic', load_lang('discussion_record')],
-            6 : [load_lang('name'), 'admin_plus', load_lang('add_admin_group')],
-            7 : [load_lang('name'), 'edit_filter/add', load_lang('edit_filter_add')],
-            8 : [load_lang('document_name'), 'search', load_lang('search')],
-            9 : [0, 'block_log/user', load_lang('blocked_user')],
-            10 : [0, 'block_log/admin', load_lang('blocked_admin')],
-            11 : [load_lang('document_name'), 'watch_list', load_lang('add_watchlist')],
-            12 : [load_lang('compare_target'), 'check', load_lang('compare_target')],
-            13 : [load_lang('document_name'), 'edit', load_lang('load')],
-            14 : [load_lang('document_name'), 'star_doc', load_lang('add_star_doc')],
-            15 : [load_lang('name_or_ip_or_regex'), 'auth/give/ban', load_lang('release')],
-            16 : [0, 'auth/give/fix', load_lang('user_fix')],
+            0 : [load_lang('document_name'), '/acl', load_lang('acl')],
+            1 : [0, '/check', load_lang('check')],
+            2 : [load_lang('file_name'), '/file_filter/add', load_lang('file_filter_add')],
+            3 : [0, '/auth/give', load_lang('authorize')],
+            4 : [0, '/record', load_lang('edit_record')],
+            5 : [0, '/record/topic', load_lang('discussion_record')],
+            6 : [load_lang('name'), '/admin_plus', load_lang('add_admin_group')],
+            7 : [load_lang('name'), '/edit_filter/add', load_lang('edit_filter_add')],
+            8 : [load_lang('document_name'), '/search', load_lang('search')],
+            9 : [0, '/block_log/user', load_lang('blocked_user')],
+            10 : [0, '/block_log/admin', load_lang('blocked_admin')],
+            11 : [load_lang('document_name'), '/watch_list', load_lang('add_watchlist')],
+            12 : [load_lang('compare_target'), '/check', load_lang('compare_target')],
+            13 : [load_lang('document_name'), '/edit', load_lang('load')],
+            14 : [load_lang('document_name'), '/star_doc', load_lang('add_star_doc')],
+            15 : [load_lang('name_or_ip_or_regex'), '/auth/give/ban', load_lang('release')],
+            16 : [0, '/auth/give/fix', load_lang('user_fix')],
         }
         }
         
         
         if num == 1:
         if num == 1:
             return redirect('/manager')
             return redirect('/manager')
-        elif not num - 1 > len(title_list):
+        elif num - 1 <= len(title_list):
             num -= 2
             num -= 2
 
 
             add_1 = flask.request.form.get('name', 'test')
             add_1 = flask.request.form.get('name', 'test')
@@ -35,7 +35,7 @@ def main_tool_redirect(num = 1, add_2 = ''):
                 elif flask.request.form.get('regex', '') != '':
                 elif flask.request.form.get('regex', '') != '':
                     return redirect('/auth/give/ban_regex/' + url_pas(add_1))
                     return redirect('/auth/give/ban_regex/' + url_pas(add_1))
                 else:
                 else:
-                    return redirect('/' + title_list[num][1] + '/' + url_pas(add_1))
+                    return redirect(title_list[num][1] + '/' + url_pas(add_1))
             else:
             else:
                 if title_list[num][0] == 0:
                 if title_list[num][0] == 0:
                     placeholder = load_lang('user_name')
                     placeholder = load_lang('user_name')

+ 86 - 68
route/tool/func.py

@@ -8,6 +8,7 @@ import zipfile
 import shutil
 import shutil
 import logging
 import logging
 import random
 import random
+import typing
 import ipaddress
 import ipaddress
 
 
 import email.mime.text
 import email.mime.text
@@ -17,7 +18,8 @@ import email.header
 import urllib.request
 import urllib.request
 
 
 # Init-Version
 # Init-Version
-version_list = json.loads(open('version.json', encoding = 'utf8').read())
+with open('version.json', encoding = 'utf8') as file_data:
+    version_list = json.loads(file_data.read())
 
 
 print('Version : ' + version_list['beta']['r_ver'])
 print('Version : ' + version_list['beta']['r_ver'])
 print('DB set version : ' + version_list['beta']['c_ver'])
 print('DB set version : ' + version_list['beta']['c_ver'])
@@ -27,7 +29,9 @@ print('----')
 # Init-PIP_Install
 # Init-PIP_Install
 data_up_date = 1
 data_up_date = 1
 if os.path.exists(os.path.join('data', 'version.json')):
 if os.path.exists(os.path.join('data', 'version.json')):
-    data_load_ver = open(os.path.join('data', 'version.json'), encoding = 'utf8').read()
+    with open(os.path.join('data', 'version.json'), encoding = 'utf8') as file_data:
+        data_load_ver = file_data.read()
+    
     if data_load_ver == version_list['beta']['r_ver']:
     if data_load_ver == version_list['beta']['r_ver']:
         data_up_date = 0
         data_up_date = 0
 
 
@@ -172,14 +176,17 @@ class get_db_connect:
                 port = int(self.db_set['mysql_port']),
                 port = int(self.db_set['mysql_port']),
                 autocommit = True
                 autocommit = True
             )
             )
-            curs = self.conn.cursor()
 
 
-            self.conn.select_db(self.db_set['name'])
+            try:
+                self.conn.select_db(self.db_set['name'])
+            except:
+                pass
 
 
         load_conn(self.conn)
         load_conn(self.conn)
         return self.conn
         return self.conn
     
     
     def __exit__(self, exc_type, exc_value, traceback):
     def __exit__(self, exc_type, exc_value, traceback):
+        self.conn.commit()
         load_conn(self.conn_sub)
         load_conn(self.conn_sub)
         self.conn.close()
         self.conn.close()
 
 
@@ -195,10 +202,9 @@ class class_check_json:
         else:
         else:
             if os.path.exists(os.path.join('data', 'set.json')):
             if os.path.exists(os.path.join('data', 'set.json')):
                 db_set_list = ['db', 'db_type']
                 db_set_list = ['db', 'db_type']
-                set_data = json.loads(open(
-                    os.path.join('data', 'set.json'), 
-                    encoding = 'utf8'
-                ).read())
+                with open(os.path.join('data', 'set.json'), encoding = 'utf8') as file_data:
+                    set_data = json.loads(file_data.read())
+
                 for i in db_set_list:
                 for i in db_set_list:
                     if not i in set_data:
                     if not i in set_data:
                         os.remove(os.path.join('data', 'set.json'))
                         os.remove(os.path.join('data', 'set.json'))
@@ -246,12 +252,9 @@ class class_check_json:
     def do_check_mysql_json(data_db_set):
     def do_check_mysql_json(data_db_set):
         if os.path.exists(os.path.join('data', 'mysql.json')):
         if os.path.exists(os.path.join('data', 'mysql.json')):
             db_set_list = ['user', 'password', 'host', 'port']
             db_set_list = ['user', 'password', 'host', 'port']
-            set_data = json.loads(
-                open(
-                    os.path.join('data', 'mysql.json'),
-                    encoding = 'utf8'
-                ).read()
-            )
+            with open(os.path.join('data', 'mysql.json'), encoding = 'utf8') as file_data:
+                set_data = json.loads(file_data.read())
+
             for i in db_set_list:
             for i in db_set_list:
                 if not i in set_data:
                 if not i in set_data:
                     os.remove(os.path.join('data', 'mysql.json'))
                     os.remove(os.path.join('data', 'mysql.json'))
@@ -705,8 +708,6 @@ def set_init_always(ver_num):
         if db_data:
         if db_data:
             global_wiki_set['wiki_access_password'] = db_data[0][0]
             global_wiki_set['wiki_access_password'] = db_data[0][0]
     
     
-    conn.commit()
-    
 def set_init():
 def set_init():
     curs = conn.cursor()
     curs = conn.cursor()
 
 
@@ -736,8 +737,6 @@ def set_init():
             ['smtp_security', 'starttls']
             ['smtp_security', 'starttls']
         ]:
         ]:
             curs.execute(db_change("insert into other (name, data, coverage) values (?, ?, '')"), [i[0], i[1]])
             curs.execute(db_change("insert into other (name, data, coverage) values (?, ?, '')"), [i[0], i[1]])
-        
-    conn.commit()
 
 
 # Func-simple
 # Func-simple
 ## Func-simple-without_DB
 ## Func-simple-without_DB
@@ -970,23 +969,23 @@ def pw_check(data, data2, type_d = 'no', id_d = ''):
 
 
     curs.execute(db_change('select data from other where name = "encode"'))
     curs.execute(db_change('select data from other where name = "encode"'))
     db_data = curs.fetchall()
     db_data = curs.fetchall()
-
+    load_set_data = db_data[0][0] if db_data and db_data[0][0] != '' else 'sha3'
+    set_data = db_data[0][0] if db_data and db_data[0][0] != '' else 'sha3'
+    
     if type_d != 'no':
     if type_d != 'no':
         if type_d == '':
         if type_d == '':
             set_data = 'sha3'
             set_data = 'sha3'
         else:
         else:
             set_data = type_d
             set_data = type_d
-    else:
-        set_data = db_data[0][0]
 
 
     re_data = 1 if pw_encode(data, set_data) == data2 else 0
     re_data = 1 if pw_encode(data, set_data) == data2 else 0
-    if db_data[0][0] != set_data and re_data == 1 and id_d != '':
+    if load_set_data != set_data and re_data == 1 and id_d != '':
         curs.execute(db_change("update user_set set data = ? where id = ? and name = 'pw'"), [
         curs.execute(db_change("update user_set set data = ? where id = ? and name = 'pw'"), [
             pw_encode(data), 
             pw_encode(data), 
             id_d
             id_d
         ])
         ])
         curs.execute(db_change("update user_set set data = ? where id = ? and name = 'encode'"), [
         curs.execute(db_change("update user_set set data = ? where id = ? and name = 'encode'"), [
-            db_data[0][0], 
+            load_set_data, 
             id_d
             id_d
         ])
         ])
 
 
@@ -1094,7 +1093,7 @@ def wiki_css(data):
     data += ['' for _ in range(0, 3 - len(data))]
     data += ['' for _ in range(0, 3 - len(data))]
     
     
     data_css = ''
     data_css = ''
-    data_css_ver = '173'
+    data_css_ver = '174'
     
     
     # Func JS + Defer
     # Func JS + Defer
     data_css += '<script src="/views/main_css/js/func/func.js?ver=' + data_css_ver + '"></script>'
     data_css += '<script src="/views/main_css/js/func/func.js?ver=' + data_css_ver + '"></script>'
@@ -1108,7 +1107,7 @@ def wiki_css(data):
     data_css += '<script defer src="/views/main_css/js/func/shortcut.js?ver=' + data_css_ver + '"></script>'
     data_css += '<script defer src="/views/main_css/js/func/shortcut.js?ver=' + data_css_ver + '"></script>'
     
     
     # Route JS + Defer
     # Route JS + Defer
-    data_css += '<script defer src="/views/main_css/js/route/thread.js?ver=' + data_css_ver + '"></script>'
+
     
     
     # Route JS
     # Route JS
     data_css += '<script src="/views/main_css/js/route/editor.js?ver=' + data_css_ver + '"></script>'
     data_css += '<script src="/views/main_css/js/route/editor.js?ver=' + data_css_ver + '"></script>'
@@ -1117,13 +1116,6 @@ def wiki_css(data):
     # Main CSS
     # Main CSS
     data_css += '<link rel="stylesheet" href="/views/main_css/css/main.css?ver=' + data_css_ver + '">'
     data_css += '<link rel="stylesheet" href="/views/main_css/css/main.css?ver=' + data_css_ver + '">'
 
 
-    # External
-    data_css += '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.5.0/build/styles/default.min.css">'
-    data_css += '<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.5.0/build/highlight.min.js"></script>'
-    
-    data_css += '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">'
-    data_css += '<script src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>'
-
     data = data[0:2] + ['', data_css] + data[2:]
     data = data[0:2] + ['', data_css] + data[2:]
 
 
     return data
     return data
@@ -1363,10 +1355,6 @@ def render_set(doc_name = '', doc_data = '', data_type = 'view', data_in = '', d
             }
             }
 
 
             get_class_render = class_do_render(conn, render_lang_data).do_render(doc_name, doc_data, data_type, data_in)
             get_class_render = class_do_render(conn, render_lang_data).do_render(doc_name, doc_data, data_type, data_in)
-
-            if data_type == 'backlink':
-                return ''
-
             
             
             if 'include' in get_class_render[2]:
             if 'include' in get_class_render[2]:
                 for_a = 0
                 for_a = 0
@@ -1379,7 +1367,7 @@ def render_set(doc_name = '', doc_data = '', data_type = 'view', data_in = '', d
                         acl_dict[include_data[1]] = acl_result
                         acl_dict[include_data[1]] = acl_result
 
 
                     if acl_result == 0:
                     if acl_result == 0:
-                        include_regex = re.compile('<div id="' + include_data[0] + '"><\/div>')
+                        include_regex = re.compile('<div id="' + include_data[0] + '"><\\/div>')
                         if re.search(include_regex, get_class_render[0]):
                         if re.search(include_regex, get_class_render[0]):
                             include_data_render = class_do_render(conn, render_lang_data).do_render(include_data[1], include_data[2], data_type, include_data[0] + data_in)
                             include_data_render = class_do_render(conn, render_lang_data).do_render(include_data[1], include_data[2], data_type, include_data[0] + data_in)
                             if len(include_data) > 3:
                             if len(include_data) > 3:
@@ -1393,6 +1381,9 @@ def render_set(doc_name = '', doc_data = '', data_type = 'view', data_in = '', d
 
 
                     for_a += 1
                     for_a += 1
 
 
+            if data_type == 'backlink':
+                return ''
+
             get_class_render[0] = '<div class="opennamu_render_complete">' + get_class_render[0] + '</div>'
             get_class_render[0] = '<div class="opennamu_render_complete">' + get_class_render[0] + '</div>'
 
 
             curs.execute(db_change("select data from other where name = 'namumark_compatible'"))
             curs.execute(db_change("select data from other where name = 'namumark_compatible'"))
@@ -1712,7 +1703,6 @@ def admin_check(num = None, what = None, name = ''):
                     curs.execute(db_change(
                     curs.execute(db_change(
                         "insert into re_admin (who, what, time) values (?, ?, ?)"
                         "insert into re_admin (who, what, time) values (?, ?, ?)"
                     ), [ip, what, time_data])
                     ), [ip, what, time_data])
-                    conn.commit()
 
 
                 return 1
                 return 1
 
 
@@ -1754,6 +1744,9 @@ def acl_check(name = 'test', tool = '', topic_num = '1'):
     elif tool in ['document_edit', 'document_move', 'document_delete']:
     elif tool in ['document_edit', 'document_move', 'document_delete']:
         if acl_check(name, '') == 1:
         if acl_check(name, '') == 1:
             return 1
             return 1
+    elif tool in ['bbs_edit', 'bbs_comment']:
+        if acl_check(name, 'bbs_view') == 1:
+            return 1
     elif tool == 'topic':
     elif tool == 'topic':
         curs.execute(db_change("select title from rd where code = ?"), [topic_num])
         curs.execute(db_change("select title from rd where code = ?"), [topic_num])
         name = curs.fetchall()
         name = curs.fetchall()
@@ -1761,7 +1754,7 @@ def acl_check(name = 'test', tool = '', topic_num = '1'):
 
 
     if tool in ['topic']:
     if tool in ['topic']:
         end = 3
         end = 3
-    elif tool in ['render', 'vote', '', 'document_edit', 'document_move', 'document_delete']:
+    elif tool in ['render', 'vote', '', 'document_edit', 'document_move', 'document_delete', 'document_edit', 'bbs_edit', 'bbs_comment']:
         end = 2
         end = 2
     else:
     else:
         end = 1
         end = 1
@@ -1872,6 +1865,24 @@ def acl_check(name = 'test', tool = '', topic_num = '1'):
                 'select data from other where name = "edit_bottom_compulsion_acl"'
                 'select data from other where name = "edit_bottom_compulsion_acl"'
             ))
             ))
 
 
+            num = 'all'
+        elif tool == 'bbs_edit':
+            if i == 0:
+                curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_edit_acl" and set_id = ?'), [name])
+            else:
+                curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_acl" and set_id = ?'), [name])
+
+            num = 'all'
+        elif tool == 'bbs_comment':
+            if i == 0:
+                curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_comment_acl" and set_id = ?'), [name])
+            else:
+                curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_acl" and set_id = ?'), [name])
+
+            num = 'all'
+        elif tool == 'bbs_view':
+            curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_view_acl" and set_id = ?'), [name])
+
             num = 'all'
             num = 'all'
         else:
         else:
             # tool == 'render'
             # tool == 'render'
@@ -2010,7 +2021,6 @@ def ban_check(ip = None, tool = ''):
         "update rb set ongoing = '' " + \
         "update rb set ongoing = '' " + \
         "where end < ? and end != '' and ongoing = '1'"
         "where end < ? and end != '' and ongoing = '1'"
     ), [get_time()])
     ), [get_time()])
-    conn.commit()
 
 
     curs.execute(db_change("" + \
     curs.execute(db_change("" + \
         "select login, block from rb " + \
         "select login, block from rb " + \
@@ -2055,33 +2065,53 @@ def ip_pas(raw_ip, type_data = 0):
         get_ip = raw_ip
         get_ip = raw_ip
 
 
     curs.execute(db_change("select data from other where name = 'ip_view'"))
     curs.execute(db_change("select data from other where name = 'ip_view'"))
-    ip_view = curs.fetchall()
-    ip_view = ip_view[0][0] if ip_view else ''
+    db_data = curs.fetchall()
+    ip_view = db_data[0][0] if db_data else ''
     ip_view = '' if admin_check(1) == 1 else ip_view
     ip_view = '' if admin_check(1) == 1 else ip_view
+
+    curs.execute(db_change("select data from other where name = 'user_name_view'"))
+    db_data = curs.fetchall()
+    user_name_view = db_data[0][0] if db_data else ''
+    user_name_view = '' if admin_check(1) == 1 else user_name_view
     
     
     get_ip = list(set(get_ip))
     get_ip = list(set(get_ip))
     
     
     for raw_ip in get_ip:
     for raw_ip in get_ip:
         change_ip = 0
         change_ip = 0
         is_this_ip = ip_or_user(raw_ip)
         is_this_ip = ip_or_user(raw_ip)
-        if is_this_ip != 0 and ip_view != '':
-            try:
-                ip = ipaddress.ip_address(raw_ip)
-                if type(ip) == ipaddress.IPv6Address:
-                    ip = ip.exploded
-                    ip = re.sub(r':([^:]*):([^:]*)$', ':*:*', ip)
+        if is_this_ip != 0:
+            # ip user
+            if ip_view != '':
+                try:
+                    ip = ipaddress.ip_address(raw_ip)
+                    if type(ip) == ipaddress.IPv6Address:
+                        ip = ip.exploded
+                        ip = re.sub(r':([^:]*):([^:]*)$', ':*:*', ip)
+                    else:
+                        ip = ip.exploded
+                        ip = re.sub(r'\.([^.]*)\.([^.]*)$', '.*.*', ip)
+                    
+                    # ip = hashlib.sha3_224(bytes(raw_ip, 'utf-8')).hexdigest()
+                    # ip = ip[0:4] + '-' + ip[4:8] + '-' + ip[8:12] + '-' + ip[12:16]
+
+                    change_ip = 1
+                except:
+                    ip = raw_ip
+            else:
+                ip = raw_ip
+        else:
+            # not ip user
+            if user_name_view != '':
+                curs.execute(db_change("select data from user_set where id = ? and name = 'sub_user_name'"), [raw_ip])
+                db_data = curs.fetchall()
+                if db_data and db_data[0][0] != '':
+                    ip = db_data[0][0]
                 else:
                 else:
-                    ip = ip.exploded
-                    ip = re.sub(r'\.([^.]*)\.([^.]*)$', '.*.*', ip)
-                
-                # ip = hashlib.sha3_224(bytes(raw_ip, 'utf-8')).hexdigest()
-                # ip = ip[0:4] + '-' + ip[4:8] + '-' + ip[8:12] + '-' + ip[12:16]
+                    ip = load_lang('member')
 
 
                 change_ip = 1
                 change_ip = 1
-            except:
+            else:
                 ip = raw_ip
                 ip = raw_ip
-        else:     
-            ip = raw_ip
             
             
         if type_data == 0 and change_ip == 0:
         if type_data == 0 and change_ip == 0:
             if is_this_ip == 0:
             if is_this_ip == 0:
@@ -2251,8 +2281,6 @@ def do_add_thread(thread_code, thread_data, thread_top = '', thread_id = ''):
         thread_code
         thread_code
     ])
     ])
     
     
-    conn.commit()
-    
 def do_reload_recent_thread(topic_num, date, name = None, sub = None):
 def do_reload_recent_thread(topic_num, date, name = None, sub = None):
     curs = conn.cursor()
     curs = conn.cursor()
 
 
@@ -2272,15 +2300,12 @@ def do_reload_recent_thread(topic_num, date, name = None, sub = None):
             date
             date
         ])
         ])
 
 
-    conn.commit()
-
 def add_alarm(who, context):
 def add_alarm(who, context):
     curs = conn.cursor()
     curs = conn.cursor()
 
 
     curs.execute(db_change(
     curs.execute(db_change(
         'insert into alarm (name, data, date) values (?, ?, ?)'
         'insert into alarm (name, data, date) values (?, ?, ?)'
     ), [who, context, get_time()])
     ), [who, context, get_time()])
-    conn.commit()
     
     
 def add_user(user_name, user_pw, user_email = '', user_encode = ''):
 def add_user(user_name, user_pw, user_email = '', user_encode = ''):
     curs = conn.cursor()
     curs = conn.cursor()
@@ -2323,8 +2348,6 @@ def add_user(user_name, user_pw, user_email = '', user_encode = ''):
             user_name,
             user_name,
             user_email
             user_email
         ])
         ])
-        
-    conn.commit()
     
     
 def ua_plus(u_id, u_ip, u_agent, time):
 def ua_plus(u_id, u_ip, u_agent, time):
     curs = conn.cursor()
     curs = conn.cursor()
@@ -2342,7 +2365,6 @@ def ua_plus(u_id, u_ip, u_agent, time):
             u_agent, 
             u_agent, 
             time
             time
         ])
         ])
-        conn.commit()
 
 
 def ban_insert(name, end, why, login, blocker, type_d = None):
 def ban_insert(name, end, why, login, blocker, type_d = None):
     curs = conn.cursor()
     curs = conn.cursor()
@@ -2396,8 +2418,6 @@ def ban_insert(name, end, why, login, blocker, type_d = None):
             login
             login
         ])
         ])
 
 
-    conn.commit()
-
 def history_plus(title, data, date, ip, send, leng, t_check = '', mode = ''):
 def history_plus(title, data, date, ip, send, leng, t_check = '', mode = ''):
     curs = conn.cursor()
     curs = conn.cursor()
     # 여기 좀 느린 듯
     # 여기 좀 느린 듯
@@ -2501,8 +2521,6 @@ def history_plus(title, data, date, ip, send, leng, t_check = '', mode = ''):
 def re_error(data):
 def re_error(data):
     curs = conn.cursor()
     curs = conn.cursor()
 
 
-    conn.commit()
-
     if data == '/ban':
     if data == '/ban':
         if ban_check() == 1:
         if ban_check() == 1:
             end = '<div id="opennamu_get_user_info">' + ip_check() + '</div>'
             end = '<div id="opennamu_get_user_info">' + ip_check() + '</div>'

+ 6 - 6
route/tool/func_render.py

@@ -67,9 +67,9 @@ class class_do_render:
                 curs.execute(db_change("delete from back where title = ? and type = 'no'"), [doc_name])
                 curs.execute(db_change("delete from back where title = ? and type = 'no'"), [doc_name])
 
 
             self.conn.commit()
             self.conn.commit()
-        else:
-            return [
-                data_end[0], 
-                data_end[1],
-                data_end[2]
-            ]
+
+        return [
+            data_end[0], 
+            data_end[1],
+            data_end[2]
+        ]

+ 55 - 16
route/tool/func_render_namumark.py

@@ -48,8 +48,13 @@ class class_do_render_namumark:
         self.render_data = self.doc_data
         self.render_data = self.doc_data
         self.render_data = html.escape(self.render_data)
         self.render_data = html.escape(self.render_data)
         self.render_data = '<back_br>\n' + self.render_data + '\n<front_br>'
         self.render_data = '<back_br>\n' + self.render_data + '\n<front_br>'
+        self.render_data_cdn = ''
         self.render_data_js = ''
         self.render_data_js = ''
 
 
+        self.curs.execute(db_change('select data from other where name = "link_case_insensitive"'))
+        db_data = self.curs.fetchall()
+        self.link_case_insensitive = ' collate nocase' if db_data and db_data[0][0] != '' else ''
+
     def get_tool_lang(self, name):
     def get_tool_lang(self, name):
         if name in self.lang_data:
         if name in self.lang_data:
             return self.lang_data[name]
             return self.lang_data[name]
@@ -148,6 +153,9 @@ class class_do_render_namumark:
         return data
         return data
 
 
     def get_tool_footnote_make(self):
     def get_tool_footnote_make(self):
+        footnote_number_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_footnote_number', self.ip)
+        footnote_number_view_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_view_real_footnote_num', self.ip)
+    
         data = ''
         data = ''
         for for_a in self.data_footnote:
         for for_a in self.data_footnote:
             if data == '':
             if data == '':
@@ -617,8 +625,6 @@ class class_do_render_namumark:
                 link_main = self.get_tool_data_restore(link_main, do_type = 'slash')
                 link_main = self.get_tool_data_restore(link_main, do_type = 'slash')
                 link_main = html.unescape(link_main)
                 link_main = html.unescape(link_main)
 
 
-                print(link_main)
-
                 self.curs.execute(db_change("select set_data from data_set where doc_name = ? and set_name = 'last_edit'"), [link_main])
                 self.curs.execute(db_change("select set_data from data_set where doc_name = ? and set_name = 'last_edit'"), [link_main])
                 db_data = self.curs.fetchall()
                 db_data = self.curs.fetchall()
                 if db_data:
                 if db_data:
@@ -673,6 +679,10 @@ class class_do_render_namumark:
         def do_render_math_sub(match):
         def do_render_math_sub(match):
             data = match.group(1)
             data = match.group(1)
 
 
+            if self.data_math_count == 0:
+                self.render_data_cdn += '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">'
+                self.render_data_cdn += '<script src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>'
+
             data = re.sub(r'\n', '', data)
             data = re.sub(r'\n', '', data)
             data = self.get_tool_data_revert(data)
             data = self.get_tool_data_revert(data)
 
 
@@ -1010,13 +1020,14 @@ class class_do_render_namumark:
 
 
                     link_exist = ''
                     link_exist = ''
                     if link_main != '':
                     if link_main != '':
-                        self.curs.execute(db_change("select title from data where title = ?"), [link_main])
+                        self.curs.execute(db_change("select title from data where title = ?" + self.link_case_insensitive), [link_main])
                         db_data = self.curs.fetchall()
                         db_data = self.curs.fetchall()
                         if not db_data:
                         if not db_data:
                             self.data_backlink += [[self.doc_name, link_main, 'no']]
                             self.data_backlink += [[self.doc_name, link_main, 'no']]
                             self.data_backlink += [[self.doc_name, link_main, '']]
                             self.data_backlink += [[self.doc_name, link_main, '']]
                             link_exist = 'opennamu_not_exist_link'
                             link_exist = 'opennamu_not_exist_link'
                         else:
                         else:
+                            link_main = db_data[0][0]
                             self.data_backlink += [[self.doc_name, link_main, '']]
                             self.data_backlink += [[self.doc_name, link_main, '']]
 
 
                     link_same = ''
                     link_same = ''
@@ -1186,7 +1197,11 @@ class class_do_render_namumark:
 
 
     def do_redner_footnote(self):
     def do_redner_footnote(self):
         footnote_num = 0
         footnote_num = 0
+
         footnote_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_footnote_set', self.ip)
         footnote_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_footnote_set', self.ip)
+        footnote_number_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_footnote_number', self.ip)
+        footnote_number_view_set = get_main_skin_set(self.curs, self.flask_session, 'main_css_view_real_footnote_num', self.ip)
+
         footnote_regex = re.compile('(?:\[\*((?:(?!\[\*|\]| ).)+)?(?: ((?:(?!\[\*|\]).)+))?\]|\[(각주|footnote)\])', re.I)
         footnote_regex = re.compile('(?:\[\*((?:(?!\[\*|\]| ).)+)?(?: ((?:(?!\[\*|\]).)+))?\]|\[(각주|footnote)\])', re.I)
         footnote_count_all = len(re.findall(footnote_regex, self.render_data)) * 4
         footnote_count_all = len(re.findall(footnote_regex, self.render_data)) * 4
         while 1:
         while 1:
@@ -1227,7 +1242,14 @@ class class_do_render_namumark:
 
 
                         fn = self.doc_include + 'fn_' + footnote_first
                         fn = self.doc_include + 'fn_' + footnote_first
                         rfn = self.doc_include + 'rfn_' + footnote_num_str
                         rfn = self.doc_include + 'rfn_' + footnote_num_str
-                        foot_v_name = footnote_name + ' (' + footnote_num_str + ')'
+
+                        if footnote_number_set == 'only_number':
+                            foot_v_name += footnote_first
+                        else:
+                            foot_v_name += footnote_name
+                            
+                        if footnote_number_view_set != 'off':
+                            foot_v_name += ' (' + footnote_num_str + ')'
                     else:
                     else:
                         self.data_footnote[footnote_name] = {}
                         self.data_footnote[footnote_name] = {}
                         self.data_footnote[footnote_name]['list'] = [footnote_num_str]
                         self.data_footnote[footnote_name]['list'] = [footnote_num_str]
@@ -1235,7 +1257,14 @@ class class_do_render_namumark:
 
 
                         fn = self.doc_include + 'fn_' + footnote_num_str
                         fn = self.doc_include + 'fn_' + footnote_num_str
                         rfn = self.doc_include + 'rfn_' + footnote_num_str
                         rfn = self.doc_include + 'rfn_' + footnote_num_str
-                        foot_v_name = footnote_name + footnote_name_add
+
+                        if footnote_number_set == 'only_number':
+                            foot_v_name += footnote_num_str
+                        else:
+                            foot_v_name += footnote_name
+                            
+                        if footnote_number_view_set != 'off':
+                            foot_v_name += footnote_name_add
 
 
                     if footnote_set == 'spread':
                     if footnote_set == 'spread':
                         data_name = self.get_tool_data_storage(
                         data_name = self.get_tool_data_storage(
@@ -1349,7 +1378,8 @@ class class_do_render_namumark:
                     if table_parameter_name == 'tablebgcolor':
                     if table_parameter_name == 'tablebgcolor':
                         table_parameter_all['table'] += 'background:' + self.get_tool_dark_mode_split(table_parameter_data) + ';'
                         table_parameter_all['table'] += 'background:' + self.get_tool_dark_mode_split(table_parameter_data) + ';'
                     elif table_parameter_name == 'tablewidth':
                     elif table_parameter_name == 'tablewidth':
-                        table_parameter_all['table'] += 'width:' + self.get_tool_px_add_check(table_parameter_data) + ';'
+                        table_parameter_all['div'] += 'width:' + self.get_tool_px_add_check(table_parameter_data) + ';'
+                        table_parameter_all['table'] += 'width:100%;'
                     elif table_parameter_name == 'tableheight':
                     elif table_parameter_name == 'tableheight':
                         table_parameter_all['table'] += 'height:' + self.get_tool_px_add_check(table_parameter_data) + ';'
                         table_parameter_all['table'] += 'height:' + self.get_tool_px_add_check(table_parameter_data) + ';'
                     elif table_parameter_name == 'tablealign':
                     elif table_parameter_name == 'tablealign':
@@ -1567,7 +1597,7 @@ class class_do_render_namumark:
                         data_name = self.get_tool_data_storage('<div id="' + self.doc_include + 'opennamu_wiki_' + str(wiki_count) + '"></div>', '', middle_data_org)
                         data_name = self.get_tool_data_storage('<div id="' + self.doc_include + 'opennamu_wiki_' + str(wiki_count) + '"></div>', '', middle_data_org)
                         wiki_count += 1
                         wiki_count += 1
                     elif middle_name == '#!html':
                     elif middle_name == '#!html':
-                        html_data = re.sub(r'^#!html ', '', middle_data)
+                        html_data = re.sub(r'^#!html( |\n)', '', middle_data)
                         if middle_slash:
                         if middle_slash:
                             html_data += '\\'
                             html_data += '\\'
 
 
@@ -1622,11 +1652,17 @@ class class_do_render_namumark:
                             wiki_data_syntax = wiki_data_syntax.group(1)
                             wiki_data_syntax = wiki_data_syntax.group(1)
                             if not wiki_data_syntax:
                             if not wiki_data_syntax:
                                 wiki_data_syntax = 'python'
                                 wiki_data_syntax = 'python'
+                            else:
+                                if wiki_data_syntax == 'asm' or wiki_data_syntax == 'assembly':
+                                    wiki_data_syntax = 'x86arm'
                         else:
                         else:
                             wiki_data_syntax = 'python'
                             wiki_data_syntax = 'python'
 
 
                         if syntax_count == 0:
                         if syntax_count == 0:
                             self.render_data_js += 'hljs.highlightAll();\n'
                             self.render_data_js += 'hljs.highlightAll();\n'
+                            self.render_data_cdn += '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous" referrerpolicy="no-referrer" />'
+                            self.render_data_cdn += '<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js" integrity="sha512-rdhY3cbXURo13l/WU9VlaRyaIYeJ/KBakckXIvJNAQde8DgpOmE+eZf7ha4vdqVjTtwQt69bD2wH2LXob/LB7Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>'
+                            self.render_data_cdn += '<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/x86asm.min.js" integrity="sha512-HeAchnWb+wLjUb2njWKqEXNTDlcd1QcyOVxb+Mc9X0bWY0U5yNHiY5hTRUt/0twG8NEZn60P3jttqBvla/i2gA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>'
 
 
                         data_name = self.get_tool_data_storage('<pre id="syntax"><code class="' + wiki_data_syntax + '">' + wiki_data, '</code></pre>', middle_data_org)
                         data_name = self.get_tool_data_storage('<pre id="syntax"><code class="' + wiki_data_syntax + '">' + wiki_data, '</code></pre>', middle_data_org)
                         syntax_count += 1
                         syntax_count += 1
@@ -1636,7 +1672,7 @@ class class_do_render_namumark:
                             self.render_data = re.sub(middle_regex, lambda x : middle_data_org, self.render_data, 1)
                             self.render_data = re.sub(middle_regex, lambda x : middle_data_org, self.render_data, 1)
                             continue
                             continue
 
 
-                        wiki_data = re.sub(r'^\+[1-5] ', '', middle_data)
+                        wiki_data = re.sub(r'^\+[1-5]( |\n)', '', middle_data)
                         if middle_name == '+5':
                         if middle_name == '+5':
                             wiki_size = '200'
                             wiki_size = '200'
                         elif middle_name == '+4':
                         elif middle_name == '+4':
@@ -1656,7 +1692,7 @@ class class_do_render_namumark:
                             self.render_data = re.sub(middle_regex, lambda x : middle_data_org, self.render_data, 1)
                             self.render_data = re.sub(middle_regex, lambda x : middle_data_org, self.render_data, 1)
                             continue
                             continue
 
 
-                        wiki_data = re.sub(r'^\-[1-5] ', '', middle_data)
+                        wiki_data = re.sub(r'^\-[1-5]( |\n)', '', middle_data)
                         if middle_name == '-5':
                         if middle_name == '-5':
                             wiki_size = '50'
                             wiki_size = '50'
                         elif middle_name == '-4':
                         elif middle_name == '-4':
@@ -1696,7 +1732,7 @@ class class_do_render_namumark:
                         wiki_color = self.get_tool_css_safe(wiki_color_data)
                         wiki_color = self.get_tool_css_safe(wiki_color_data)
                         wiki_color = self.get_tool_dark_mode_split(wiki_color)
                         wiki_color = self.get_tool_dark_mode_split(wiki_color)
 
 
-                        wiki_data = re.sub(r'^@(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+))(?:,@(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+)))? ?', '', middle_data)
+                        wiki_data = re.sub(r'^@(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+))(?:,@(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+)))?( |\n)', '', middle_data)
 
 
                         middle_data_pass = wiki_data
                         middle_data_pass = wiki_data
                         data_name = self.get_tool_data_storage('<span style="background-color:' + wiki_color + '">', '</span>', middle_data_org)
                         data_name = self.get_tool_data_storage('<span style="background-color:' + wiki_color + '">', '</span>', middle_data_org)
@@ -1726,7 +1762,7 @@ class class_do_render_namumark:
                         wiki_color = self.get_tool_css_safe(wiki_color_data)
                         wiki_color = self.get_tool_css_safe(wiki_color_data)
                         wiki_color = self.get_tool_dark_mode_split(wiki_color)
                         wiki_color = self.get_tool_dark_mode_split(wiki_color)
 
 
-                        wiki_data = re.sub(r'^#(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+))(?:,#(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+)))? ?', '', middle_data)
+                        wiki_data = re.sub(r'^#(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+))(?:,#(?:((?:[0-9a-f-A-F]{3}){1,2})|(\w+)))?( |\n)', '', middle_data)
 
 
                         middle_data_pass = wiki_data
                         middle_data_pass = wiki_data
                         data_name = self.get_tool_data_storage('<span style="color:' + wiki_color + '">', '</span>', middle_data_org)
                         data_name = self.get_tool_data_storage('<span style="color:' + wiki_color + '">', '</span>', middle_data_org)
@@ -1804,15 +1840,16 @@ class class_do_render_namumark:
                 list_len = 1
                 list_len = 1
 
 
             list_style = {
             list_style = {
-                1 : 'list-style: unset;',
-                2 : 'list-style: circle;',
-                3 : 'list-style: square;',
+                1 : 'opennamu_list_1',
+                2 : 'opennamu_list_2',
+                3 : 'opennamu_list_3',
+                4 : 'opennamu_list_4'
             }
             }
-            list_style_data = 'list-style: square;'
+            list_style_data = 'opennamu_list_5'
             if list_len in list_style:
             if list_len in list_style:
                 list_style_data = list_style[list_len]
                 list_style_data = list_style[list_len]
 
 
-            return '<li style="margin-left: ' + str(list_len * 20) + 'px;' + list_style_data + '">' + list_data + '</li>'
+            return '<li style="margin-left: ' + str(list_len * 20) + 'px;" class="' + list_style_data + '">' + list_data + '</li>'
 
 
         list_regex = r'((?:\n *\* ?[^\n]*)+)\n'
         list_regex = r'((?:\n *\* ?[^\n]*)+)\n'
         list_count_max = len(re.findall(list_regex, self.render_data)) * 3
         list_count_max = len(re.findall(list_regex, self.render_data)) * 3
@@ -1956,6 +1993,8 @@ class class_do_render_namumark:
 
 
         self.render_data = re.sub(r'<a fn_target="([^"]+)"', do_render_last_footnote, self.render_data)
         self.render_data = re.sub(r'<a fn_target="([^"]+)"', do_render_last_footnote, self.render_data)
 
 
+        self.render_data = self.render_data_cdn + self.render_data
+
     def __call__(self):
     def __call__(self):
         self.do_render_remark()
         self.do_render_remark()
         self.do_render_include_default()
         self.do_render_include_default()

+ 1 - 0
route/tool/func_tool.py

@@ -25,6 +25,7 @@ def db_change(data):
         data = data.replace('random()', 'rand()')
         data = data.replace('random()', 'rand()')
         data = data.replace('%', '%%')
         data = data.replace('%', '%%')
         data = data.replace('?', '%s')
         data = data.replace('?', '%s')
+        data = data.replace('collate nocase', 'collate utf8mb4_general_ci')
 
 
     return data
     return data
 
 

+ 10 - 5
route/topic.py

@@ -1,9 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 from .api_topic import api_topic
 from .api_topic import api_topic
 
 
-def topic_make(data, ip_first = ''):
-    data = ''
-
 def topic(topic_num = 0, do_type = '', doc_name = 'Test'):
 def topic(topic_num = 0, do_type = '', doc_name = 'Test'):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
@@ -186,14 +183,22 @@ def topic(topic_num = 0, do_type = '', doc_name = 'Test'):
             
             
             shortcut += '</div>'
             shortcut += '</div>'
 
 
+            top_topic = ''
+            json_data = json.loads(api_topic(int(topic_num), 'top', '', 'render').data)
+            top_topic += json_data['data'] if 'data' in json_data else ''
+            
+            main_topic = ''
+            json_data = json.loads(api_topic(int(topic_num), 'normal', '', 'render').data)
+            main_topic += json_data['data'] if 'data' in json_data else ''
+
             return easy_minify(flask.render_template(skin_check(),
             return easy_minify(flask.render_template(skin_check(),
                 imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('discussion') + ')', 0])],
                 imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('discussion') + ')', 0])],
                 data = '''
                 data = '''
                     ''' + shortcut + '''
                     ''' + shortcut + '''
                     <h2 id="topic_top_title">''' + html.escape(sub) + '''</h2>
                     <h2 id="topic_top_title">''' + html.escape(sub) + '''</h2>
                     
                     
-                    <div id="top_topic"></div>
-                    <div id="main_topic"></div>
+                    <div id="top_topic">''' + top_topic + '''</div>
+                    <div id="main_topic">''' + main_topic + '''</div>
                     <div id="plus_topic"></div>
                     <div id="plus_topic"></div>
                     
                     
                     <a href="/thread/''' + topic_num + '/tool">(' + load_lang('topic_tool') + ''')</a>
                     <a href="/thread/''' + topic_num + '/tool">(' + load_lang('topic_tool') + ''')</a>

+ 11 - 7
route/topic_list.py

@@ -1,4 +1,5 @@
 from .tool.func import *
 from .tool.func import *
+from .api_topic import api_topic
 
 
 def topic_list(name = 'Test'):
 def topic_list(name = 'Test'):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
@@ -33,14 +34,17 @@ def topic_list(name = 'Test'):
 
 
         for data in curs.fetchall():
         for data in curs.fetchall():
             curs.execute(db_change("select id from topic where code = ? order by id + 0 desc limit 1"), [data[0]])
             curs.execute(db_change("select id from topic where code = ? order by id + 0 desc limit 1"), [data[0]])
-            t_data = curs.fetchall()
+            db_data = curs.fetchall()
+            last_thread = db_data[0][0] if db_data else '1'
 
 
-            div += '''
-                <h2><a href="/thread/''' + data[0] + '">' + data[0] + '. ' + html.escape(data[1]) + '''</a></h2>
-                <div class="topic_pre" id="opennamu_thread_''' + data[0] + '''"></div>
-                <div class="topic_back_pre" id="opennamu_thread_back_''' + data[0] + '''"></div>
-                <!-- JS : opennamu_do_thread_make -->
-            '''
+            div += '<h2><a href="/thread/' + data[0] + '">' + data[0] + '. ' + html.escape(data[1]) + '</a></h2>'
+
+            first_data = json.loads(api_topic(data[0], 'normal', 1, 'render').data)
+            div += first_data['data'] if 'data' in first_data else ''
+
+            if last_thread != '1':
+                last_data = json.loads(api_topic(data[0], 'normal', int(last_thread), 'render').data)
+                div += last_data['data'] if 'data' in last_data else ''
 
 
         if div == '':
         if div == '':
             plus = re.sub(r'^<br>', '', plus)
             plus = re.sub(r'^<br>', '', plus)

+ 8 - 1
route/user_setting.py

@@ -15,7 +15,8 @@ def user_setting():
                 auto_list = [
                 auto_list = [
                     ['skin', flask.request.form.get('skin', '')], 
                     ['skin', flask.request.form.get('skin', '')], 
                     ['lang', flask.request.form.get('lang', '')],
                     ['lang', flask.request.form.get('lang', '')],
-                    ['user_title', flask.request.form.get('user_title', '')]
+                    ['user_title', flask.request.form.get('user_title', '')],
+                    ['sub_user_name' , flask.request.form.get('sub_user_name', '')]
                 ]
                 ]
 
 
                 twofa_on = flask.request.form.get('2fa', '')
                 twofa_on = flask.request.form.get('2fa', '')
@@ -96,6 +97,10 @@ def user_setting():
                 fa_data_pw = curs.fetchall()
                 fa_data_pw = curs.fetchall()
                 fa_data_pw = load_lang('2fa_password_change') if fa_data_pw else load_lang('2fa_password')
                 fa_data_pw = load_lang('2fa_password_change') if fa_data_pw else load_lang('2fa_password')
 
 
+                curs.execute(db_change('select data from user_set where name = "sub_user_name" and id = ?'), [ip])
+                db_data = curs.fetchall()
+                sub_user_name = db_data[0][0] if db_data else ''
+
                 return easy_minify(flask.render_template(skin_check(),
                 return easy_minify(flask.render_template(skin_check(),
                     imp = [load_lang('user_setting'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
                     imp = [load_lang('user_setting'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
                     data = '''
                     data = '''
@@ -127,6 +132,8 @@ def user_setting():
                             <select name="2fa" id="twofa_check_input">''' + fa_data_select + '''</select>
                             <select name="2fa" id="twofa_check_input">''' + fa_data_select + '''</select>
                             <hr class="main_hr">
                             <hr class="main_hr">
                             <input type="password" name="2fa_pw" placeholder="''' + fa_data_pw + '''">
                             <input type="password" name="2fa_pw" placeholder="''' + fa_data_pw + '''">
+                            <h2>''' + load_lang('sub_user_name') + '''</h2>
+                            <input name="sub_user_name" value="''' + html.escape(sub_user_name) + '''" placeholder="''' + load_lang('sub_user_name') + '''">
                             <hr class="main_hr">
                             <hr class="main_hr">
                             <button type="submit">''' + load_lang('save') + '''</button>
                             <button type="submit">''' + load_lang('save') + '''</button>
                             ''' + http_warning() + '''
                             ''' + http_warning() + '''

+ 2 - 5
route/user_setting_pw.py

@@ -12,8 +12,8 @@ def user_setting_pw():
             return redirect('/login')
             return redirect('/login')
 
 
         if flask.request.method == 'POST':
         if flask.request.method == 'POST':
-            user_pw = flask.request.form.get('password_new', '')
             user_pw_now = flask.request.form.get('password_now', '')
             user_pw_now = flask.request.form.get('password_now', '')
+            user_pw = flask.request.form.get('password_new', '')
             user_repeat = flask.request.form.get('password_new_repeat', '')
             user_repeat = flask.request.form.get('password_new_repeat', '')
         
         
             # PW 검증
             # PW 검증
@@ -48,10 +48,7 @@ def user_setting_pw():
             if pw_check(user_pw_now, db_user_pw, db_user_encode, ip) != 1:
             if pw_check(user_pw_now, db_user_pw, db_user_encode, ip) != 1:
                 return re_error('/error/10')
                 return re_error('/error/10')
 
 
-            curs.execute(db_change("update user_set set data = ? where id = ? and name = 'pw'"), [
-                pw_encode(new_pw), 
-                ip
-            ])
+            curs.execute(db_change("update user_set set data = ? where id = ? and name = 'pw'"), [pw_encode(user_pw), ip])
             
             
             conn.commit()
             conn.commit()
 
 

+ 19 - 0
route/user_setting_skin_set_main.py

@@ -56,6 +56,14 @@ def user_setting_skin_set_main_set_list():
             ['default', load_lang('default')],
             ['default', load_lang('default')],
             ['0', load_lang('off')],
             ['0', load_lang('off')],
             ['1', load_lang('use')]
             ['1', load_lang('use')]
+        ], 'main_css_footnote_number' : [
+            ['default', load_lang('default')],
+            ['all', load_lang('all')],
+            ['only_number', load_lang('only_number')]
+        ], 'main_css_view_real_footnote_num' : [
+            ['default', load_lang('default')],
+            ['off', load_lang('off')],
+            ['on', load_lang('use')]
         ]
         ]
     }
     }
 
 
@@ -145,10 +153,21 @@ def user_setting_skin_set_main():
                             ''' + set_data["main_css_category_set"] + '''
                             ''' + set_data["main_css_category_set"] + '''
                         </select>
                         </select>
                         <h3>''' + load_lang("footnote") + ''' (''' + load_lang('beta') + ''')</h3>
                         <h3>''' + load_lang("footnote") + ''' (''' + load_lang('beta') + ''')</h3>
+                        <h4>''' + load_lang("footnote_render") + '''</h4>
                         ''' + set_data_main["main_css_footnote_set"] + '''
                         ''' + set_data_main["main_css_footnote_set"] + '''
                         <select name="main_css_footnote_set">
                         <select name="main_css_footnote_set">
                             ''' + set_data["main_css_footnote_set"] + '''
                             ''' + set_data["main_css_footnote_set"] + '''
                         </select>
                         </select>
+                        <h4>''' + load_lang("footnote_number") + '''</h4>
+                        ''' + set_data_main["main_css_footnote_number"] + '''
+                        <select name="main_css_footnote_number">
+                            ''' + set_data["main_css_footnote_number"] + '''
+                        </select>
+                        <h4>''' + load_lang("footnote_real_num_view") + '''</h4>
+                        ''' + set_data_main["main_css_view_real_footnote_num"] + '''
+                        <select name="main_css_view_real_footnote_num">
+                            ''' + set_data["main_css_view_real_footnote_num"] + '''
+                        </select>
                         <h3>''' + load_lang("include_link") + '''</h3>
                         <h3>''' + load_lang("include_link") + '''</h3>
                         ''' + set_data_main["main_css_include_link"] + '''
                         ''' + set_data_main["main_css_include_link"] + '''
                         <select name="main_css_include_link">
                         <select name="main_css_include_link">

+ 1 - 1
route/give_acl.py → route/view_acl.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 from .tool.func import *
 
 
-def give_acl_2(name):
+def view_acl(name):
     with get_db_connect() as conn:
     with get_db_connect() as conn:
         curs = conn.cursor()
         curs = conn.cursor()
 
 

+ 53 - 19
route/view_diff.py

@@ -26,32 +26,66 @@ def view_diff(name = 'Test', num_a = 1, num_b = 1):
             if first_raw_data == second_raw_data:
             if first_raw_data == second_raw_data:
                 result = ''
                 result = ''
             else:
             else:
-                i = 1
-                change_count = 0
-                diff_data = diff_match_patch().diff_prettyHtml(
-                    diff_match_patch().diff_main(first_raw_data, second_raw_data)
-                )
-                end_data = ''
+                diff_data = diff_match_patch().diff_main(first_raw_data, second_raw_data)
+                diff_data += [[0, '\n']]
+                
+                diff_data_2 = []
+                temp_list = []
+                line = 1
+                line_change = 0
+                for for_a in diff_data:
+                    line_split = re.findall(r'(.*\n)|(.+$)', for_a[1])
+                    if line_split:
+                        for for_b in line_split:
+                            if for_b[0] != '':
+                                if for_a[0] != 0:
+                                    line_change = 1
+                                
+                                temp_list += [[line, for_a[0], for_b[0].replace('\n', '')]]
 
 
-                diff_data = diff_data.replace('&para;<br>', '\n')
-                diff_data = diff_data.replace('<span>', '')
-                diff_data = diff_data.replace('</span>', '')
+                                if line_change == 1:
+                                    diff_data_2 += temp_list
+                                
+                                temp_list = []
+                                line_change = 0
+                                line += 1
+                            else:
+                                if for_a[0] != 0:
+                                    line_change = 1
 
 
-                re_data = re.findall(r'(?:(?:(?:(?!\n).)*)(?:\n)|(?:(?:(?!\n).)+)$)', diff_data)
-                for re_in_data in re_data:
-                    change_find_start = len(re.findall(r'<(?:del|ins) ', re_in_data))
-                    change_find_end = len(re.findall(r'<\/(?:del|ins)>', re_in_data))
+                                temp_list += [[line, for_a[0], for_b[1]]]
+                    else:
+                        if for_a[0] != 0:
+                            line_change = 1
 
 
-                    change_count += (change_find_start - change_find_end)
-                    if change_count != 0 or change_find_start != 0 or change_find_end != 0:
-                        end_data += str(i) + ' : ' + re_in_data
+                        temp_list += [[line, for_a[0], for_a[1]]]
 
 
-                    i += 1
+                result = '<table style="width: 100%;"><tr><td colspan="2">r' + first + ' ➤ r' + second + '</td></tr>'
+                result += '<tr><td style="width: 40px; user-select: none;">'
 
 
-                result = '<pre>' + end_data + '</pre>'
+                # 개행만 추가된 경우 조정 필요
+                
+                line = 0
+                for for_a in diff_data_2:
+                    if line == 0:
+                        line = for_a[0]
+                        result += str(line) + '</td><td>'
+                    else:
+                        if line != for_a[0]:
+                            line = for_a[0]
+                            result += '</td></tr><tr><td style="width: 40px; user-select: none;">' + str(line) + '</td><td>'
+
+                    if for_a[1] == 1:
+                        result += '<span style="background: #eaf2c2;">' + for_a[2] + '</span>'
+                    elif for_a[1] == 0:
+                        result += for_a[2]
+                    else:
+                        result += '<span style="background: #fadad7;">' + for_a[2] + '</span>'
+
+                result += '</td></tr></table>'
 
 
             return easy_minify(flask.render_template(skin_check(),
             return easy_minify(flask.render_template(skin_check(),
-                imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('compare') + ') (r' + first + ') (r' + second + ')', 0])],
+                imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('compare') + ')', 0])],
                 data = result,
                 data = result,
                 menu = [['history/' + url_pas(name), load_lang('return')]]
                 menu = [['history/' + url_pas(name), load_lang('return')]]
             ))
             ))

+ 1 - 1
route/view_read.py

@@ -213,7 +213,7 @@ def view_read(name = 'Test', doc_rev = '', doc_from = '', do_type = ''):
                 if flask.session and 'lastest_document' in flask.session:
                 if flask.session and 'lastest_document' in flask.session:
                     end_data = '''
                     end_data = '''
                         <div id="redirect">
                         <div id="redirect">
-                            <a href="/w_from/''' + url_pas(flask.session['lastest_document']) + '''">''' + flask.session['lastest_document'] + '''</a>  <b>''' + name + '''</b>
+                            <a href="/w_from/''' + url_pas(flask.session['lastest_document']) + '''">''' + flask.session['lastest_document'] + '''</a>  <b>''' + name + '''</b>
                         </div>
                         </div>
                         <hr class="main_hr">
                         <hr class="main_hr">
                     ''' + end_data
                     ''' + end_data

+ 5 - 1
route/view_xref.py

@@ -21,10 +21,14 @@ def view_xref(name = 'Test', xref_type = 1):
 
 
         div += '<ul class="opennamu_ul">'
         div += '<ul class="opennamu_ul">'
 
 
+        curs.execute(db_change('select data from other where name = "link_case_insensitive"'))
+        db_data = curs.fetchall()
+        link_case_insensitive = ' collate nocase' if db_data and db_data[0][0] != '' else ''
+
         sql_insert = ['link', 'title'] if xref_type == 1 else ['title', 'link']
         sql_insert = ['link', 'title'] if xref_type == 1 else ['title', 'link']
         curs.execute(db_change("" + \
         curs.execute(db_change("" + \
             "select distinct " + sql_insert[0] + ", type from back " + \
             "select distinct " + sql_insert[0] + ", type from back " + \
-            "where " + sql_insert[1] + " = ? and not type = 'no' and not type = 'nothing'" + \
+            "where " + sql_insert[1] + " = ?" + link_case_insensitive + " and not type = 'no' and not type = 'nothing' " + \
             "order by type asc, " + sql_insert[0] + " asc limit ?, 50" + \
             "order by type asc, " + sql_insert[0] + " asc limit ?, 50" + \
         ""), [
         ""), [
             name,
             name,

+ 1 - 1
version.json

@@ -1,6 +1,6 @@
 {
 {
     "beta" : {
     "beta" : {
-        "r_ver" : "v3.4.6-RC3-dev166",
+        "r_ver" : "v3.4.6-RC3-dev181",
         "c_ver" : "3500361",
         "c_ver" : "3500361",
         "s_ver" : "3500111"
         "s_ver" : "3500111"
     }
     }

+ 53 - 1
views/main_css/css/main.css

@@ -93,6 +93,10 @@ summary {
     display: none;
     display: none;
 }
 }
 
 
+.opennamu_comment_blind_admin {
+    background: gainsboro;
+}
+
 .opennamu_comment_scroll {
 .opennamu_comment_scroll {
     max-height: 500px;
     max-height: 500px;
     
     
@@ -201,6 +205,10 @@ pre {
     margin: 0;
     margin: 0;
 }
 }
 
 
+code, pre {
+    font-family: Consolas, Monaco, monospace;
+}
+
 #syntax {
 #syntax {
     padding: 0;
     padding: 0;
 }
 }
@@ -218,6 +226,9 @@ pre {
     background-color: #efefef;
     background-color: #efefef;
     
     
     border: 1px solid #cecece;
     border: 1px solid #cecece;
+
+    font-size: small;
+    font-weight: initial;
 }
 }
 
 
 .opennamu_popup_footnote {
 .opennamu_popup_footnote {
@@ -232,6 +243,9 @@ pre {
     background-color: #efefef;
     background-color: #efefef;
     
     
     border: 1px solid #cecece;
     border: 1px solid #cecece;
+
+    font-size: small;
+    font-weight: initial;
 }
 }
 
 
 @media ( max-width: 768px ) {
 @media ( max-width: 768px ) {
@@ -255,7 +269,7 @@ hr {
 
 
 blockquote {
 blockquote {
     padding: 15px 40px 15px 15px;
     padding: 15px 40px 15px 15px;
-    margin: 15px 0 0;
+    margin: 0;
 
 
     display: inline-block;
     display: inline-block;
 
 
@@ -325,4 +339,42 @@ s:hover, strike:hover, del:hover {
 
 
     overflow-x: scroll;
     overflow-x: scroll;
     overflow-y: hidden;
     overflow-y: hidden;
+}
+
+.opennamu_width_200 {
+    width: 200px;
+}
+
+.opennamu_list_1 {
+    list-style: disc;
+}
+
+.opennamu_list_2 {
+    list-style: circle;
+}
+
+.opennamu_list_3 {
+    list-style: square;
+}
+
+.opennamu_list_4 {
+    list-style: none;
+}
+
+.opennamu_list_4::before {
+    display: inline-block;
+    content: "⬦";
+    width: 1.2em;
+    margin-left: -1.2em;
+}
+
+.opennamu_list_5 {
+    list-style: none;
+}
+
+.opennamu_list_5::before {
+    display: inline-block;
+    content: "⬥";
+    width: 1.2em;
+    margin-left: -1.2em;
 }
 }

+ 3 - 6
views/main_css/js/route/render.js

@@ -121,7 +121,6 @@ function opennamu_do_render_html(name = '') {
 
 
 function opennamu_do_footnote_spread(set_name, load_name) {
 function opennamu_do_footnote_spread(set_name, load_name) {
     if(document.getElementById(set_name + '_load').style.display === 'none') {
     if(document.getElementById(set_name + '_load').style.display === 'none') {
-        console.log(set_name, load_name);
         document.getElementById(set_name).title = '';
         document.getElementById(set_name).title = '';
         document.getElementById(set_name + '_load').innerHTML = '<a href="#' + load_name + '">(Go)</a> ' + document.getElementById(load_name + '_title').innerHTML;
         document.getElementById(set_name + '_load').innerHTML = '<a href="#' + load_name + '">(Go)</a> ' + document.getElementById(load_name + '_title').innerHTML;
         document.getElementById(set_name + '_load').style.display = "inline-block";
         document.getElementById(set_name + '_load').style.display = "inline-block";
@@ -132,7 +131,6 @@ function opennamu_do_footnote_spread(set_name, load_name) {
 
 
 function opennamu_do_footnote_popover(set_name, load_name) {
 function opennamu_do_footnote_popover(set_name, load_name) {
     if(document.getElementById(set_name + '_load').style.display === 'none') {
     if(document.getElementById(set_name + '_load').style.display === 'none') {
-        console.log(set_name, load_name);
         document.getElementById(set_name).title = '';
         document.getElementById(set_name).title = '';
         document.getElementById(set_name + '_load').innerHTML = '<a href="#' + load_name + '">(Go)</a> ' + document.getElementById(load_name + '_title').innerHTML;
         document.getElementById(set_name + '_load').innerHTML = '<a href="#' + load_name + '">(Go)</a> ' + document.getElementById(load_name + '_title').innerHTML;
         document.getElementById(set_name + '_load').style.display = "inline-block";
         document.getElementById(set_name + '_load').style.display = "inline-block";
@@ -141,11 +139,10 @@ function opennamu_do_footnote_popover(set_name, load_name) {
         let screen_width = window.innerWidth;
         let screen_width = window.innerWidth;
         let left = document.getElementById(set_name).getBoundingClientRect().left;
         let left = document.getElementById(set_name).getBoundingClientRect().left;
         let left_org = document.getElementById(set_name + '_load').getBoundingClientRect().left;
         let left_org = document.getElementById(set_name + '_load').getBoundingClientRect().left;
-        let top = document.getElementById(set_name).getBoundingClientRect().top;
-        console.log(width, screen_width, left, left_org);
-        console.log(screen_width - (left + width));
+        let top = window.pageYOffset + document.getElementById(set_name).getBoundingClientRect().top;
+
+        document.getElementById(set_name + '_load').style.top = String(top) + "px";
         if(screen_width - (left + width) < 50) {
         if(screen_width - (left + width) < 50) {
-            console.log("test");
             if(left > 350) {
             if(left > 350) {
                 document.getElementById(set_name + '_load').style.left = String(left - 300) + "px";
                 document.getElementById(set_name + '_load').style.left = String(left - 300) + "px";
             } else {
             } else {

+ 0 - 185
views/main_css/js/route/thread.js

@@ -1,185 +0,0 @@
-// 폐지하고 다시 SSR 방식으로 전환 예정
-function opennamu_do_thread_make(topic_num, type_do = 'top', some = '', where = 'top_topic') {
-    let url = '';
-    if(type_do === 'top') {
-        url = "/api/thread/" + topic_num + "/top";
-    } else if(type_do === 'main') {
-        url = "/api/thread/" + topic_num;
-    } else {
-        url = "/api/thread/" + topic_num + some;
-    }
-
-    let xhr = new XMLHttpRequest();
-    xhr.open("GET", url);
-    xhr.send();
-
-    xhr.onreadystatechange = function() {
-        if(this.readyState === 4 && this.status === 200) {
-            let data_t = JSON.parse(this.responseText);
-            
-            let start = 0;
-            let key_v = '/normal/1';
-            let admin = '';
-            let ip_first = '';
-            
-            let data_all = '';
-            let data_all_js = '';
-            
-            let count = 0;
-            for(let key in data_t) {
-                let data_a = '';
-                
-                if(start === 0) {
-                    admin = data_t['data_main']['admin'];
-                    ip_first = data_t['data_main']['ip_first'];
-                
-                    start = 1;
-                }
-                
-                if(key === 'data_main') {
-                    continue;
-                }
-                
-                key_v = '/normal/' + String(Number(key) + 1);
-                
-                let color_b = '';
-                let color_t = '';
-                
-                let ip = data_t[key]['ip_pas'];
-                let ip_o = data_t[key]['ip'];
-                let blind = data_t[key]['blind'];
-                let data_i_pas = data_t[key]['data_pas'][0];
-                let data_get_list = [];
-
-                if(data_i_pas === '') {
-                    data_i_pas = '<br>';
-                } else {
-                    let load_thread_regex = /&lt;topic_a&gt;((?:(?!&lt;\/topic_a&gt;).)+)&lt;\/topic_a&gt;/g;
-
-                    data_get_list = data_i_pas.match(load_thread_regex);
-
-                    data_i_pas = data_i_pas.replace(load_thread_regex, '<a href="$1">$1</a>');
-                    data_i_pas = data_i_pas.replace(/&lt;topic_call&gt;@((?:(?!&lt;\/topic_call&gt;).)+)&lt;\/topic_call&gt;/g, '<a href="/w/user:$1">@$1</a>');
-                }
-                
-                if(blind === 'O') {
-                    color_b = 'opennamu_comment_blind';
-                } else {
-                    color_b = 'opennamu_comment_blind_not';
-                }
-                
-                if(blind === 'O') {
-                    ip += ' <a href="/list/admin/auth_use/' + opennamu_do_url_encode('blind (code ' + topic_num + '#' + key) + '/1">(B)</a>';
-                    
-                    if(admin === '1') {
-                        ip += ' <a href="javascript:opennamu_do_open_comment(\'' + key + '\');">(O)</a>';
-                    }
-                }
-                
-                if(admin === '1' || blind !== 'O') {
-                    ip += ' <a href="/thread/' + topic_num + '/comment/' + key + '/tool">(T)</a>';
-                }
-                
-                if(type_do === 'top') {
-                    color_t = 'opennamu_comment_color_red';
-                } else if(blind === '1') {
-                    color_t = 'opennamu_comment_color_blue';
-                } else if(blind === 'O') {
-                    color_t = 'opennamu_comment_color_gray';
-                } else if(ip_o === ip_first) {
-                    color_t = 'opennamu_comment_color_green';
-                } else {
-                    color_t = 'opennamu_comment_color_default';
-                }
-                
-                data_a += '' + 
-                    '<table class="opennamu_comment">' + 
-                        '<tr>' + 
-                            '<td class="' + color_t + '">' + 
-                                '<a href="#thread_shortcut" id="' + key + '">#' + key + '</a> ' + 
-                                ip + 
-                                '<span style="float: right;">' + data_t[key]['date'] + '</span>' + 
-                            '</td>' + 
-                        '</tr>' + 
-                        '<tr>' + 
-                            '<td class="' + color_b + '" id="opennamu_comment_data_' + key + '">' + 
-                                '<div class="opennamu_comment_scroll">' + data_i_pas + '</div>' + 
-                            '</td>' + 
-                        '</tr>' +
-                    '</table>' + 
-                    '<hr class="main_hr">' + 
-                ''
-
-                document.getElementById(where).innerHTML += data_a;
-                
-                count += 1;
-                data_all_js += data_t[key]['data_pas'][1] + '\n';
-                
-                if(count > 100) {
-                    eval(data_all_js);
-                    
-                    count = 0;
-                    data_all_js = '';
-                }
-            }
-            
-            eval(data_all_js);
-            
-            if(type_do === 'top') {
-                opennamu_do_thread_make(topic_num, 'main', '', 'main_topic');
-            } else if(type_do === 'main') {
-                let data_url_v = window.location.hash.replace(/^#/, '');
-                if(data_url_v !== '') {
-                    if(document.getElementById(data_url_v)) {
-                        document.getElementById(data_url_v).focus();
-                    }
-                }
-                
-                opennamu_do_thread_make(topic_num, 're', key_v, where);
-            } else if(type_do === 're') {
-                setTimeout(function() {
-                    if(start === 0) {
-                        opennamu_do_thread_make(topic_num, 're', some, where);
-                    } else {
-                        opennamu_do_thread_make(topic_num, 're', key_v, where);
-                    }
-                }, 2000);
-            }
-        }
-    }
-}
-
-function opennamu_do_open_comment(key) {
-    let element_state = document.getElementById('opennamu_comment_data_' + key).style.display;
-    if(!element_state || element_state === 'none') {
-        document.getElementById('opennamu_comment_data_' + key).style.display = 'block';
-    } else {
-        document.getElementById('opennamu_comment_data_' + key).style.display = 'none';
-    }
-}
-
-if(window.location.pathname.match(/^\/(thread|thread_preview)\//)) {
-    let thread_num = window.location.pathname.match(/^\/(?:thread|thread_preview)\/([0-9]+)/)[1];
-
-    opennamu_do_thread_make(thread_num);
-} else if(window.location.pathname.match(/^\/topic\//)) {
-    for(let for_a = 0; document.getElementsByClassName('topic_pre')[for_a]; for_a++) {
-        let thread_num = document.getElementsByClassName('topic_pre')[for_a].id;
-        thread_num = thread_num.match(/^opennamu_thread_([0-9]+)/)[1];
-
-        opennamu_do_thread_make(thread_num, "list", "/normal/1", "opennamu_thread_" + thread_num);
-
-        let xhr = new XMLHttpRequest();
-        xhr.open("GET", "/api/thread/" + thread_num + "/length");
-        xhr.send();
-
-        xhr.onreadystatechange = function() {
-            if(this.readyState === 4 && this.status === 200) {
-                let thread_length = JSON.parse(this.responseText)['length'];
-                if(thread_length !== '1') {
-                    opennamu_do_thread_make(thread_num, "list", "/normal/" + thread_length, "opennamu_thread_back_" + thread_num);
-                }
-            }
-        }
-    }
-}

+ 8 - 0
views/ringo/css/dark.css

@@ -39,4 +39,12 @@ button.search_button#search, button.search_button#search:hover {
 
 
 footer {
 footer {
     background: #393636;
     background: #393636;
+}
+
+#nav_bar {
+    background: #322c33;
+}
+
+#nav_bar a {
+    color: white;
 }
 }

+ 48 - 0
views/ringo/css/main.css

@@ -345,4 +345,52 @@ input, textarea, button, select {
 
 
 #opennamu_save_button {
 #opennamu_save_button {
     background: antiquewhite;
     background: antiquewhite;
+}
+
+/* nav_bar */
+#nav_bar {
+    z-index: 100;
+    
+    font-size: 25px;
+    
+    position: fixed;
+    bottom: 0;
+    right: 0;
+    
+    background: #f7dfff;
+    
+    text-align: center;
+}
+
+#go_toc {
+    display: inline-block;
+
+    padding-right: 10px;
+    padding-left: 10px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    
+    width: 25px;
+}
+
+#go_top {
+    display: inline-block;
+    
+    padding-right: 10px;
+    padding-left: 10px;
+    
+    width: 25px;
+}
+
+#go_bottom {
+    display: inline-block;
+
+    padding-right: 10px;
+    padding-left: 10px;
+    
+    width: 25px;
+}
+
+#nav_bar a {
+    color: black;
 }
 }

+ 21 - 0
views/ringo/index.html

@@ -57,6 +57,10 @@
                             <span class="iconify" data-icon="ic:baseline-how-to-vote" data-inline="true"></span>
                             <span class="iconify" data-icon="ic:baseline-how-to-vote" data-inline="true"></span>
                             {{'vote_list'|load_lang}}
                             {{'vote_list'|load_lang}}
                         </a>
                         </a>
+                        <a href="/bbs/main">
+                            <span class="iconify" data-icon="ic:outline-developer-board" data-inline="true"></span>
+                            {{'bbs_main'|load_lang}}
+                        </a>
                     </div>
                     </div>
                 </div>
                 </div>
                 <div class="top_cel" id="other_cel">
                 <div class="top_cel" id="other_cel">
@@ -231,6 +235,23 @@
             <div id="side_content">
             <div id="side_content">
                 Loading...
                 Loading...
             </div>
             </div>
+            <div id="nav_bar">
+                <div id="go_top">
+                    <a href="#logo">
+                        <span class="iconify" data-icon="ic:baseline-arrow-upward" data-inline="true"></span>
+                    </a>
+                </div>
+                <div id="go_bottom">
+                    <a href="#b_logo">
+                        <span class="iconify" data-icon="ic:baseline-arrow-downward" data-inline="true"></span>
+                    </a>
+                </div>
+                <div id="go_toc">
+                    <a href="#toc">
+                        <span class="iconify" data-icon="ic:baseline-list" data-inline="true"></span>
+                    </a>
+                </div>
+            </div>
         </aside>
         </aside>
         <footer class="only_mobile">
         <footer class="only_mobile">
             {{imp[1][1]|safe}}
             {{imp[1][1]|safe}}

+ 1 - 1
views/ringo/info.json

@@ -1,5 +1,5 @@
 {
 {
     "name" : "Ringo",
     "name" : "Ringo",
-    "skin_ver" : "v1.0.2",
+    "skin_ver" : "v1.0.3",
     "require_ver" : "3500111"
     "require_ver" : "3500111"
 }
 }

+ 7 - 5
views/tenshi/css/main.css

@@ -288,7 +288,7 @@ pre, #toc, #cate, #redirect {
 }
 }
 */
 */
 
 
-#redirect, #cate, #toc, blockquote, button#opennamu_save_button, button#opennamu_preview_button {
+#redirect, #cate, #toc, button#opennamu_save_button, button#opennamu_preview_button {
     border: 0;
     border: 0;
     
     
     padding: 10px;
     padding: 10px;
@@ -296,6 +296,12 @@ pre, #toc, #cate, #redirect {
     box-shadow: 0 2px 4px 0 rgba(0,0,0,0.16), 0 2px 10px 0 rgba(0,0,0,0.12);
     box-shadow: 0 2px 4px 0 rgba(0,0,0,0.16), 0 2px 10px 0 rgba(0,0,0,0.12);
 }
 }
 
 
+blockquote {
+    border: 0;
+    
+    box-shadow: 0 2px 4px 0 rgba(0,0,0,0.16), 0 2px 10px 0 rgba(0,0,0,0.12);
+}
+
 button#opennamu_save_button {
 button#opennamu_save_button {
     background: #92f7f4;
     background: #92f7f4;
 }
 }
@@ -461,11 +467,7 @@ div#last_edit {
 
 
 blockquote {
 blockquote {
     background-color: #ffefff;
     background-color: #ffefff;
-
-    padding: 15px 40px 15px 15px;
     border-left: 4px solid #ffb3ff;
     border-left: 4px solid #ffb3ff;
-    
-    margin-bottom: 20px;
 }
 }
 
 
 #b_logo {
 #b_logo {

+ 6 - 1
views/tenshi/index.html

@@ -8,7 +8,7 @@
             <title>{{imp[0]}} - {{imp[1][0]}}</title>
             <title>{{imp[0]}} - {{imp[1][0]}}</title>
         {% endif %}
         {% endif %}
         {{imp[3][3]|safe}}
         {{imp[3][3]|safe}}
-        <link rel="stylesheet" href="/views/tenshi/css/main.css?ver=20">
+        <link rel="stylesheet" href="/views/tenshi/css/main.css?ver=21">
         {% if request.cookies.get('main_css_darkmode', '') == '1' %}
         {% if request.cookies.get('main_css_darkmode', '') == '1' %}
             <link rel="stylesheet" href="/views/main_css/css/sub/dark.css?ver=1">
             <link rel="stylesheet" href="/views/main_css/css/sub/dark.css?ver=1">
             <link rel="stylesheet" href="/views/tenshi/css/dark.css?ver=9">
             <link rel="stylesheet" href="/views/tenshi/css/dark.css?ver=9">
@@ -60,6 +60,11 @@
                                         <span class="iconify" data-icon="ic:baseline-how-to-vote" data-inline="true"></span>
                                         <span class="iconify" data-icon="ic:baseline-how-to-vote" data-inline="true"></span>
                                         {{'vote_list'|load_lang}}
                                         {{'vote_list'|load_lang}}
                                     </a>
                                     </a>
+                                    <hr>
+                                    <a href="/bbs/main">
+                                        <span class="iconify" data-icon="ic:outline-developer-board" data-inline="true"></span>
+                                        {{'bbs_main'|load_lang}}
+                                    </a>
                                 </div>
                                 </div>
                             </div>
                             </div>

+ 1 - 1
views/tenshi/info.json

@@ -1,5 +1,5 @@
 {
 {
     "name" : "Tenshi",
     "name" : "Tenshi",
-    "skin_ver" : "v2.0.4",
+    "skin_ver" : "v2.0.5",
     "require_ver" : "3500110"
     "require_ver" : "3500110"
 }
 }