Просмотр исходного кода

Merge pull request #1306 from openNAMU/beta

v3.4.2
잉여개발기 (SPDV) 4 лет назад
Родитель
Сommit
9d7e2df671

+ 2 - 0
.gitignore

@@ -18,6 +18,8 @@ robots.txt
 custom.py
 404.html
 
+goorm.manifest
+
 views/liberty
 views/buma
 views/before_namu

+ 414 - 233
app.py

@@ -129,7 +129,9 @@ if data_db_set['type'] == 'mysql':
         data_db_set['mysql_port'] = '3306'
 
 db_data_get(data_db_set['type'])
-conn = get_conn(data_db_set)
+load_db = get_db_connect(data_db_set)
+
+conn = load_db.db_load()
 curs = conn.cursor()
 
 setup_tool = ''
@@ -137,7 +139,7 @@ try:
     curs.execute(db_change('select data from other where name = "ver"'))
 except:
     setup_tool = 'init'
-    
+
 if setup_tool != 'init':
     ver_set_data = curs.fetchall()
     if ver_set_data:
@@ -147,7 +149,7 @@ if setup_tool != 'init':
             setup_tool = 'normal'
     else:
         setup_tool = 'init'
-    
+
 if setup_tool != 'normal':
     # Init-Create_DB
     create_data = {}
@@ -203,18 +205,22 @@ set_init_always(version_list['beta']['c_ver'])
 # Init-Route
 class EverythingConverter(werkzeug.routing.PathConverter):
     regex = '.*?'
-    
+
 class RegexConverter(werkzeug.routing.BaseConverter):
     def __init__(self, url_map, *items):
         super(RegexConverter, self).__init__(url_map)
         self.regex = items[0]
-        
-app = flask.Flask(__name__, template_folder = './')
+
+app = flask.Flask(
+    __name__, 
+    template_folder = './'
+)
 
 app.config['JSON_AS_ASCII'] = False
 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
 
-app.logger.setLevel(logging.ERROR)
+log = logging.getLogger('werkzeug')
+log.setLevel(logging.ERROR)
 
 app.jinja_env.filters['md5_replace'] = md5_replace
 app.jinja_env.filters['load_lang'] = load_lang
@@ -276,30 +282,30 @@ for i in server_set_var:
             print(server_set_var[i]['display'] + ' (' + server_set_var[i]['default'] + ') [' + ', '.join(server_set_var[i]['list']) + ']' + ' : ', end = '')
         else:
             print(server_set_var[i]['display'] + ' (' + server_set_var[i]['default'] + ') : ', end = '')
-            
+
         server_set_val = input()
         if server_set_val == '':
             server_set_val = server_set_var[i]['default']
         elif server_set_var[i]['require'] == 'select':
             if not server_set_val in server_set_var[i]['list']:
                 server_set_val = server_set_var[i]['default']
-                
+
         curs.execute(db_change('insert into other (name, data) values (?, ?)'), [i, server_set_val])
-        
+
     print(server_set_var[i]['display'] + ' : ' + server_set_val)
-    
+
     server_set[i] = server_set_val
 
 print('----')
-    
+
 # Init-DB_care
-if set_data['db_type'] == 'sqlite':
+if data_db_set['type'] == 'sqlite':
     def back_up(back_time, back_up_where):
         print('----')
-        
+
         try:
             shutil.copyfile(
-                set_data['db'] + '.db', 
+                data_db_set['name'] + '.db', 
                 back_up_where
             )
 
@@ -322,211 +328,370 @@ if set_data['db_type'] == 'sqlite':
         if back_up_where and back_up_where[0][0] != '':
             back_up_where = back_up_where[0][0]
         else:
-            back_up_where = 'back_' + set_data['db'] + '.db'
+            back_up_where = 'back_' + data_db_set['name'] + '.db'
 
         print('Back up state : ' + str(back_time) + ' hours')
 
         back_up(back_time, back_up_where)
     else:
         print('Back up state : Turn off')
-else:
-    def mysql_dont_off(port):
-        try:
-            urllib.request.urlopen('http://localhost:' + port + '/')
-        except:
-            pass
-
-        threading.Timer(
-            60 * 60 * 3, 
-            mysql_dont_off,
-            [port]
-        ).start()
-
-    mysql_dont_off(server_set['port'])
 
 print('Now running... http://localhost:' + server_set['port'])
 conn.commit()
-conn.close()
-
-conn = get_conn()
 
 # Init-custom
 if os.path.exists('custom.py'):
     from custom import custom_run
-
-    custom_run(conn, app)
+    custom_run(load_db.db_get(), app)
     
 # Func
 # Func-inter_wiki
-@app.route('/inter_wiki')
-def inter_wiki():
-    return inter_wiki_2(conn, 'inter_wiki')
-
-@app.route('/inter_wiki/del/<name>')
-def inter_wiki_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_inter_wiki', name)
-
-@app.route('/edit_top')
-def inter_wiki_edit_top():
-    return inter_wiki_2(conn, 'edit_top')
-
-@app.route('/edit_top/del/<name>')
-def inter_wiki_edit_top_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_edit_top', name)
-
-@app.route('/image_license')
-def inter_wiki_image_license():
-    return inter_wiki_2(conn, 'image_license')
-
-@app.route('/image_license/del/<name>')
-def inter_wiki_image_license_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_image_license', name)
-
-@app.route('/edit_filter')
-def inter_wiki_edit_filter():
-    return inter_wiki_2(conn, 'edit_filter')
-
-@app.route('/edit_filter/del/<name>')
-def inter_wiki_edit_filter_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_edit_filter', name)
-
-@app.route('/email_filter')
-def inter_wiki_email_filter():
-    return inter_wiki_2(conn, 'email_filter')
-
-@app.route('/email_filter/del/<name>')
-def inter_wiki_email_filter_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_email_filter', name)
-
-@app.route('/file_filter')
-def inter_wiki_file_filter():
-    return inter_wiki_2(conn, 'file_filter')
-
-@app.route('/file_filter/del/<name>')
-def inter_wiki_file_filter_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_file_filter', name)
-
-@app.route('/name_filter')
-def inter_wiki_name_filter():
-    return inter_wiki_2(conn, 'name_filter')
-
-@app.route('/name_filter/del/<name>')
-def inter_wiki_name_filter_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_name_filter', name)
-
-@app.route('/extension_filter')
-def inter_wiki_extension_filter():
-    return inter_wiki_2(conn, 'extension_filter')
-
-@app.route('/extension_filter/del/<name>')
-def inter_wiki_extension_filter_del(name = 'Test'):
-    return inter_wiki_del_2(conn, 'del_extension_filter', name)
-
-@app.route('/<regex("(?:inter_wiki|edit_top|image_license|(?:edit|email|file|name|extension)_filter)"):tools>/add', methods = ['POST', 'GET'])
-@app.route('/<regex("(?:inter_wiki|edit_top|image_license|(?:edit|email|file|name|extension)_filter)"):tools>/add/<name>', methods = ['POST', 'GET'])
-def inter_wiki_plus(tools = None, name = None):
-    return inter_wiki_plus_2(conn, 'plus_' + tools, name)
+app.add_url_rule(
+    rule = '/inter_wiki',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'inter_wiki' 
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/inter_wiki/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_inter_wiki',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/inter_wiki/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_inter_wiki',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/edit_top',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'edit_top'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/edit_top/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_edit_top',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/edit_top/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_edit_top',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/image_license',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'image_license'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/image_license/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_image_license',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/image_license/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_image_license',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/edit_filter',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'edit_filter'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/edit_filter/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_edit_filter',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+# 이거 수정 필요 할 듯
+app.add_url_rule(
+    rule = '/edit_filter/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_edit_filter',
+        'name' : None
+    }, 
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/edit_filter/add/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_edit_filter',
+        'name' : 'Test'
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/email_filter',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'email_filter'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/email_filter/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_email_filter',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/email_filter/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_email_filter',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/file_filter',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'file_filter'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/file_filter/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_file_filter',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/file_filter/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_file_filter',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/name_filter',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'name_filter'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/name_filter/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_name_filter',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/name_filter/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_name_filter',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
+
+app.add_url_rule(
+    rule = '/extension_filter',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'extension_filter'
+    }, 
+    view_func = inter_wiki
+)
+
+app.add_url_rule(
+    rule = '/extension_filter/del/<name>',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'del_extension_filter',
+        'name' : 'Test'
+    }, 
+    view_func = inter_wiki_del
+)
+
+app.add_url_rule(
+    rule = '/extension_filter/add',
+    defaults = { 
+        'conn' : load_db.db_get(), 
+        'tool' : 'plus_extension_filter',
+        'name' : None
+    }, 
+    methods = ['GET', 'POST'],
+    view_func = inter_wiki_add
+)
 
 # Func-list
-# /list/topic/open
-@app.route('/not_close_topic')
-def list_not_close_topic():
-    return list_not_close_topic_2(conn)
-
 # /list/document/old
 @app.route('/old_page')
 def list_old_page():
-    return list_old_page_2(conn)
+    return list_old_page_2(load_db.db_get())
 
 # /list/document/acl
 @app.route('/acl_list')
 def list_acl():
-    return list_acl_2(conn)
+    return list_acl_2(load_db.db_get())
 
 # /list/document/acl/add
 @app.route('/acl/<everything:name>', methods = ['POST', 'GET'])
 def give_acl(name = None):
-    return give_acl_2(conn, name)
+    return give_acl_2(load_db.db_get(), name)
 
 # /list/document/need
 @app.route('/please')
 def list_please():
-    return list_please_2(conn)
+    return list_please_2(load_db.db_get())
 
 # /list/document/all
 @app.route('/title_index')
 def list_title_index():
-    return list_title_index_2(conn)
+    return list_title_index_2(load_db.db_get())
 
 # /list/document/long
 @app.route('/long_page')
 def list_long_page():
-    return list_long_page_2(conn, 'long_page')
+    return list_long_page_2(load_db.db_get(), 'long_page')
 
 # /list/document/short
 @app.route('/short_page')
 def list_short_page():
-    return list_long_page_2(conn, 'short_page')
+    return list_long_page_2(load_db.db_get(), 'short_page')
 
 # /list/file
 @app.route('/image_file_list')
 def list_image_file():
-    return list_image_file_2(conn)
+    return list_image_file_2(load_db.db_get())
 
 # /list/admin
 # /list/admin/list
 @app.route('/admin_list')
 def list_admin():
-    return list_admin_2(conn)
+    return list_admin_2(load_db.db_get())
 
 # /list/admin/auth_use
 @app.route('/admin_log', methods = ['POST', 'GET'])
 def list_admin_use():
-    return list_admin_use_2(conn)
+    return list_admin_use_2(load_db.db_get())
 
 # /list/user
 @app.route('/user_log')
 def list_user():
-    return list_user_2(conn)
+    return list_user_2(load_db.db_get())
 
 # /list/user/check
 @app.route('/check/<name>')
 def give_user_check(name = None):
-    return give_user_check_2(conn, name)
+    return give_user_check_2(load_db.db_get(), name)
     
 # /list/user/check/delete
 @app.route('/check_delete', methods = ['POST', 'GET'])
 def give_user_check_delete():
-    return give_user_check_delete_2(conn)
+    return give_user_check_delete_2(load_db.db_get())
 
 # Func-auth
 # /auth/give
 # /auth/give/<name>
 @app.route('/admin/<name>', methods = ['POST', 'GET'])
 def give_admin(name = None):
-    return give_admin_2(conn, name)
+    return give_admin_2(load_db.db_get(), name)
 
 # /auth/give
 # /auth/give/<name>
 @app.route('/ban', methods = ['POST', 'GET'])
 @app.route('/ban/<name>', methods = ['POST', 'GET'])
 def give_user_ban(name = None):
-    return give_user_ban_2(conn, name)
+    return give_user_ban_2(load_db.db_get(), name)
 
 # /auth/list
 @app.route('/admin_group')
 def list_admin_group():
-    return list_admin_group_2(conn)
+    return list_admin_group_2(load_db.db_get())
 
 # /auth/list/add/<name>
 @app.route('/admin_plus/<name>', methods = ['POST', 'GET'])
 def give_admin_groups(name = None):
-    return give_admin_groups_2(conn, name)
+    return give_admin_groups_2(load_db.db_get(), name)
 
 # /auth/list/delete/<name>
 @app.route('/delete_admin_group/<name>', methods = ['POST', 'GET'])
 def give_delete_admin_group(name = None):
-    return give_delete_admin_group_2(conn, name)
+    return give_delete_admin_group_2(load_db.db_get(), name)
 
 # /auth/history
 # ongoing 반영 필요
@@ -534,223 +699,238 @@ def give_delete_admin_group(name = None):
 @app.route('/block_log/<regex("user"):tool>/<name>')
 @app.route('/block_log/<regex("admin"):tool>/<name>')
 def recent_block(name = 'Test', tool = 'all'):
-    return recent_block_2(conn, name, tool)
+    return recent_block_2(load_db.db_get(), name, tool)
 
 # Func-history
 @app.route('/recent_change')
 @app.route('/recent_changes')
 def recent_change(name = None):
-    return recent_change_2(conn, name, '')
+    return recent_change_2(load_db.db_get(), name, '')
 
 @app.route('/record/<name>')
 def recent_record(name = None):
-    return recent_change_2(conn, name, 'record')
+    return recent_change_2(load_db.db_get(), name, 'record')
 
 @app.route('/history/<everything:name>', methods = ['POST', 'GET'])
 def recent_history(name = None):
-    return recent_change_2(conn, name, 'history')
+    return recent_change_2(load_db.db_get(), name, 'history')
 
 @app.route('/history/tool/<int(signed=True):rev>/<everything:name>')
 def recent_history_tool(name = 'Test', rev = 1):
-    return recent_history_tool_2(conn, name, rev)
+    return recent_history_tool_2(load_db.db_get(), name, rev)
 
 @app.route('/history/delete/<int(signed=True):rev>/<everything:name>', methods = ['POST', 'GET'])
 def recent_history_delete(name = 'Test', rev = 1):
-    return recent_history_delete_2(conn, name, rev)
+    return recent_history_delete_2(load_db.db_get(), name, rev)
 
 @app.route('/history/hidden/<int(signed=True):rev>/<everything:name>')
 def recent_history_hidden(name = 'Test', rev = 1):
-    return recent_history_hidden_2(conn, name, rev)
+    return recent_history_hidden_2(load_db.db_get(), name, rev)
 
 @app.route('/history/send/<int(signed=True):rev>/<everything:name>', methods = ['POST', 'GET'])
 def recent_history_send(name = 'Test', rev = 1):
-    return recent_history_send_2(conn, name, rev)
+    return recent_history_send_2(load_db.db_get(), name, rev)
 
 @app.route('/history/reset/<everything:name>', methods = ['POST', 'GET'])
 def recent_history_reset(name = 'Test'):
-    return recent_history_reset_2(conn, name)
+    return recent_history_reset_2(load_db.db_get(), name)
 
 @app.route('/history/add/<everything:name>', methods = ['POST', 'GET'])
 def recent_history_add(name = 'Test'):
-    return recent_history_add_2(conn, name)
+    return recent_history_add_2(load_db.db_get(), name)
 
 @app.route('/record/reset/<name>', methods = ['POST', 'GET'])
 def recent_record_reset(name = 'Test'):
-    return recent_record_reset_2(conn, name)
+    return recent_record_reset_2(load_db.db_get(), name)
 
 @app.route('/record/topic/<name>')
 def recent_record_topic(name = 'Test'):
-    return recent_record_topic_2(conn, name)
+    return recent_record_topic_2(load_db.db_get(), name)
 
 # 거처를 고심중
 @app.route('/app_submit', methods = ['POST', 'GET'])
 def recent_app_submit():
-    return recent_app_submit_2(conn)
+    return recent_app_submit_2(load_db.db_get())
 
 # Func-search
 @app.route('/search', methods=['POST'])
 def search():
-    return search_2(conn)
+    return search_2(load_db.db_get())
 
 @app.route('/goto', methods=['POST'])
 @app.route('/goto/<everything:name>', methods=['POST'])
 def search_goto(name = 'test'):
-    return search_goto_2(conn, name)
+    return search_goto_2(load_db.db_get(), name)
 
 @app.route('/search/<everything:name>')
 def search_deep(name = 'test'):
-    return search_deep_2(conn, name)
+    return search_deep_2(load_db.db_get(), name)
 
 # Func-view
 @app.route('/xref/<everything:name>')
-def view_xref(name = None):
-    return view_xref_2(conn, name)
+def view_xref(name = 'Test'):
+    return view_xref_2(load_db.db_get(), name)
+
+@app.route('/xref/this/<everything:name>')
+def view_xref_this(name = 'Test'):
+    return view_xref_2(load_db.db_get(), name, xref_type = '2')
 
 @app.route('/raw/<everything:name>')
 @app.route('/thread/<int:topic_num>/raw/<int:num>')
 def view_raw(name = None, topic_num = None, num = None):
-    return view_raw_2(conn, name, topic_num, num)
+    return view_raw_2(load_db.db_get(), name, topic_num, num)
 
 @app.route('/diff/<int:num_a>/<int:num_b>/<everything:name>')
 def view_diff(name = 'Test', num_a = 1, num_b = 1):
-    return view_diff_2(conn, name, num_a, num_b)
+    return view_diff_2(load_db.db_get(), name, num_a, num_b)
 
 @app.route('/down/<everything:name>')
 def view_down(name = None):
-    return view_down_2(conn, name)
+    return view_down_2(load_db.db_get(), name)
 
 @app.route('/w/<everything:name>/doc_rev/<int:doc_rev>')
 @app.route('/w/<everything:name>/doc_from/<everything:doc_from>')
 @app.route('/w/<everything:name>')
 def view_read(name = 'Test', doc_rev = 0, doc_from = ''):
-    return view_read_2(conn, name, doc_rev, doc_from)
+    return view_read_2(load_db.db_get(), name, doc_rev, doc_from)
 
 # Func-edit
 @app.route('/revert/<everything:name>', methods = ['POST', 'GET'])
 def edit_revert(name = None):
-    return edit_revert_2(conn, name)
+    return edit_revert_2(load_db.db_get(), name)
 
 @app.route('/edit/<everything:name>', methods = ['POST', 'GET'])
 @app.route('/edit/<everything:name>/doc_section/<int:section>', methods = ['POST', 'GET'])
 def edit(name = 'Test', section = 0):
-    return edit_2(conn, name, section)
+    return edit_2(load_db.db_get(), name, section)
 
 @app.route('/backlink_reset/<everything:name>')
 def edit_backlink_reset(name = 'Test'):
-    return edit_backlink_reset_2(conn, name)
+    return edit_backlink_reset_2(load_db.db_get(), name)
 
 @app.route('/delete/<everything:name>', methods = ['POST', 'GET'])
 def edit_delete(name = None):
-    return edit_delete_2(conn, name)
+    return edit_delete_2(load_db.db_get(), name)
 
-# 개편 예정
-@app.route('/many_delete', methods = ['POST', 'GET'])
-def edit_delete_many():
-    return edit_delete_many_2(conn)
+@app.route('/delete/doc_file/<everything:name>', methods = ['POST', 'GET'])
+def edit_delete_file(name = 'test.jpg'):
+    return edit_delete_file_2(load_db.db_get(), name)
+
+@app.route('/delete/doc_mutiple', methods = ['POST', 'GET'])
+def edit_delete_mutiple():
+    return edit_delete_mutiple_2(load_db.db_get())
 
 @app.route('/move/<everything:name>', methods = ['POST', 'GET'])
 def edit_move(name = None):
-    return edit_move_2(conn, name)
+    return edit_move_2(load_db.db_get(), name)
 
 # Func-topic
 @app.route('/recent_discuss')
 def recent_discuss():
-    return recent_discuss_2(conn)
+    return recent_discuss_2(load_db.db_get(), 'normal')
+
+@app.route('/recent_discuss/close')
+def recent_discuss_close():
+    return recent_discuss_2(load_db.db_get(), 'close')
+
+@app.route('/recent_discuss/open')
+def recent_discuss_open():
+    return recent_discuss_2(load_db.db_get(), 'open')
 
 @app.route('/thread/<int:topic_num>/b/<int:num>')
 def topic_block(topic_num = 1, num = 1):
-    return topic_block_2(conn, topic_num, num)
+    return topic_block_2(load_db.db_get(), topic_num, num)
 
 @app.route('/thread/<int:topic_num>/notice/<int:num>')
 def topic_top(topic_num = 1, num = 1):
-    return topic_top_2(conn, topic_num, num)
+    return topic_top_2(load_db.db_get(), topic_num, num)
 
 @app.route('/thread/<int:topic_num>/setting', methods = ['POST', 'GET'])
 def topic_stop(topic_num = 1):
-    return topic_stop_2(conn, topic_num)
+    return topic_stop_2(load_db.db_get(), topic_num)
 
 @app.route('/thread/<int:topic_num>/acl', methods = ['POST', 'GET'])
 def topic_acl(topic_num = 1):
-    return topic_acl_2(conn, topic_num)
+    return topic_acl_2(load_db.db_get(), topic_num)
 
 @app.route('/thread/<int:topic_num>/delete', methods = ['POST', 'GET'])
 def topic_delete(topic_num = 1):
-    return topic_delete_2(conn, topic_num)
+    return topic_delete_2(load_db.db_get(), topic_num)
 
 @app.route('/thread/<int:topic_num>/tool')
 def topic_tool(topic_num = 1):
-    return topic_tool_2(conn, topic_num)
+    return topic_tool_2(load_db.db_get(), topic_num)
 
 @app.route('/thread/<int:topic_num>/change', methods = ['POST', 'GET'])
 def topic_change(topic_num = 1):
-    return topic_change_2(conn, topic_num)
+    return topic_change_2(load_db.db_get(), topic_num)
 
 @app.route('/thread/<int:topic_num>/admin/<int:num>')
 def topic_admin(topic_num = 1, num = 1):
-    return topic_admin_2(conn, topic_num, num)
+    return topic_admin_2(load_db.db_get(), topic_num, num)
 
 @app.route('/thread/<int:topic_num>', methods = ['POST', 'GET'])
 def topic(topic_num = 1):
-    return topic_2(conn, topic_num)
+    return topic_2(load_db.db_get(), topic_num)
 
 @app.route('/topic/<everything:name>', methods = ['POST', 'GET'])
 def topic_close_list(name = 'test'):
-    return topic_close_list_2(conn, name)
+    return topic_close_list_2(load_db.db_get(), name)
 
 # Func-user
 @app.route('/change', methods = ['POST', 'GET'])
 def user_setting():
-    return user_setting_2(conn, server_set_var)
+    return user_setting_2(load_db.db_get(), server_set_var)
 
 @app.route('/change/email', methods = ['POST', 'GET'])
 def user_setting_email():
-    return user_setting_email_2(conn)
+    return user_setting_email_2(load_db.db_get())
 
 @app.route('/change/email/check', methods = ['POST', 'GET'])
 def user_setting_email_check():
-    return user_setting_email_check_2(conn)
+    return user_setting_email_check_2(load_db.db_get())
 
 @app.route('/change/pw', methods = ['POST', 'GET'])
 def user_setting_pw_change():
-    return user_setting_pw_change_2(conn)
+    return user_setting_pw_change_2(load_db.db_get())
 
 @app.route('/change/head', methods=['GET', 'POST'])
 def user_setting_head():
-    return user_setting_head_2(conn)
+    return user_setting_head_2(load_db.db_get())
 
 @app.route('/user')
 @app.route('/user/<name>')
 def user_info(name = ''):
-    return user_info_2(conn, name)
+    return user_info_2(load_db.db_get(), name)
 
 @app.route('/count')
 @app.route('/count/<name>')
 def user_count_edit(name = None):
-    return user_count_edit_2(conn, name)
+    return user_count_edit_2(load_db.db_get(), name)
     
 @app.route('/alarm')
 def user_alarm():
-    return user_alarm_2(conn)
+    return user_alarm_2(load_db.db_get())
 
 @app.route('/alarm/delete')
 def user_alarm_del():
-    return user_alarm_del_2(conn)
+    return user_alarm_del_2(load_db.db_get())
     
 @app.route('/watch_list')
 def user_watch_list():
-    return user_watch_list_2(conn, 'watch_list')
+    return user_watch_list_2(load_db.db_get(), 'watch_list')
 
 @app.route('/watch_list/<everything:name>')
 def user_watch_list_name(name = 'Test'):
-    return user_watch_list_name_2(conn, 'watch_list', name)
+    return user_watch_list_name_2(load_db.db_get(), 'watch_list', name)
 
 @app.route('/star_doc')
 def user_star_doc():
-    return user_watch_list_2(conn, 'star_doc')
+    return user_watch_list_2(load_db.db_get(), 'star_doc')
 
 @app.route('/star_doc/<everything:name>')
 def user_star_doc_name(name = 'Test'):
-    return user_watch_list_name_2(conn, 'star_doc', name)
+    return user_watch_list_name_2(load_db.db_get(), 'star_doc', name)
 
 # Func-login
 # 개편 예정
@@ -761,211 +941,212 @@ def user_star_doc_name(name = 'Test'):
 
 @app.route('/login', methods = ['POST', 'GET'])
 def login_login():
-    return login_login_2(conn)
+    return login_login_2(load_db.db_get())
 
 @app.route('/login/2fa', methods = ['POST', 'GET'])
 def login_login_2fa():
-    return login_login_2fa_2(conn)
+    return login_login_2fa_2(load_db.db_get())
 
 '''
 @app.route('/login/2fa/email', methods = ['POST', 'GET'])
 def login_2fa_email():
-    return login_login_2fa_email_2(conn)
+    return login_login_2fa_email_2(load_db.db_get())
 '''
 
 @app.route('/register', methods = ['POST', 'GET'])
 def login_register():
-    return login_register_2(conn)
+    return login_register_2(load_db.db_get())
 
 @app.route('/register/email', methods = ['POST', 'GET'])
 def login_register_email():
-    return login_register_email_2(conn)
+    return login_register_email_2(load_db.db_get())
 
 @app.route('/register/email/check', methods = ['POST', 'GET'])
 def login_register_email_check():
-    return login_register_email_check_2(conn)
+    return login_register_email_check_2(load_db.db_get())
 
 @app.route('/register/submit', methods = ['POST', 'GET'])
 def login_register_submit():
-    return login_register_submit_2(conn)
+    return login_register_submit_2(load_db.db_get())
 
 # 개편 필요
 @app.route('/pass_find', methods = ['POST', 'GET'])
 def login_pass_find():
-    return login_pass_find_2(conn, 'pass_find')
+    return login_pass_find_2(load_db.db_get(), 'pass_find')
 
 @app.route('/pass_find/email', methods = ['POST', 'GET'])
 def login_pass_find_email():
-    return login_pass_find_email_2(conn, 'check_key')
+    return login_pass_find_email_2(load_db.db_get(), 'check_key')
 
 @app.route('/logout')
 def login_logout():
-    return login_logout_2(conn)
+    return login_logout_2(load_db.db_get())
 
 # Func-vote
 @app.route('/vote/<int:num>', methods = ['POST', 'GET'])
 def vote_select(num = 1):
-    return vote_select_2(conn, str(num))
+    return vote_select_2(load_db.db_get(), str(num))
 
 @app.route('/vote/end/<int:num>')
 def vote_end(num = 1):
-    return vote_end_2(conn, str(num))
+    return vote_end_2(load_db.db_get(), str(num))
 
 @app.route('/vote/close/<int:num>')
 def vote_close(num = 1):
-    return vote_close_2(conn, str(num))
+    return vote_close_2(load_db.db_get(), str(num))
 
 @app.route('/vote')
 @app.route('/vote/list')
 @app.route('/vote/list/<int:num>')
 def vote_list(num = 1):
-    return vote_list_2(conn, 'normal', num)
+    return vote_list_2(load_db.db_get(), 'normal', num)
 
 @app.route('/vote/list/close')
 @app.route('/vote/list/close/<int:num>')
 def vote_list_close(num = 1):
-    return vote_list_2(conn, 'close', num)
+    return vote_list_2(load_db.db_get(), 'close', num)
 
 @app.route('/vote/add', methods = ['POST', 'GET'])
 def vote_add():
-    return vote_add_2(conn)
+    return vote_add_2(load_db.db_get())
 
 # Func-api
 @app.route('/api/w/<everything:name>', methods = ['POST', 'GET'])
 def api_w(name = ''):
-    return api_w_2(conn, name)
+    return api_w_2(load_db.db_get(), name)
 
 @app.route('/api/raw/<everything:name>')
 def api_raw(name = ''):
-    return api_raw_2(conn, name)
+    return api_raw_2(load_db.db_get(), name)
 
 @app.route('/api/version')
 def api_version():
-    return api_version_2(conn, version_list)
+    return api_version_2(load_db.db_get(), version_list)
 
 @app.route('/api/skin_info')
 @app.route('/api/skin_info/<name>')
 def api_skin_info(name = ''):
-    return api_skin_info_2(conn, name)
+    return api_skin_info_2(load_db.db_get(), name)
 
 @app.route('/api/markup')
 def api_markup():
-    return api_markup_2(conn)
+    return api_markup_2(load_db.db_get())
 
 @app.route('/api/user_info/<name>')
 def api_user_info(name = ''):
-    return api_user_info_2(conn, name)
+    return api_user_info_2(load_db.db_get(), name)
 
 @app.route('/api/thread/<topic_num>')
 def api_topic_sub(name = '', topic_num = 1):
-    return api_topic_sub_2(conn, topic_num)
+    return api_topic_sub_2(load_db.db_get(), topic_num)
 
 @app.route('/api/search/<name>')
 def api_search(name = ''):
-    return api_search_2(conn, name)
+    return api_search_2(load_db.db_get(), name)
 
 @app.route('/api/recent_changes')
 def api_recent_change():
-    return api_recent_change_2(conn)
+    return api_recent_change_2(load_db.db_get())
 
 @app.route('/api/recent_discuss')
 @app.route('/api/recent_discuss/<int:num>')
 def api_recent_discuss(num = 10):
-    return api_recent_discuss_2(conn, num, 'normal')
+    return api_recent_discuss_2(load_db.db_get(), num, 'normal')
 
 @app.route('/api/recent_discuss/stop')
 @app.route('/api/recent_discuss/<int:num>/stop')
 def api_recent_discuss_stop(num = 10):
-    return api_recent_discuss_2(conn, num, 'stop')
+    return api_recent_discuss_2(load_db.db_get(), num, 'stop')
 
 @app.route('/api/recent_discuss/all')
 @app.route('/api/recent_discuss/<int:num>/all')
 def api_recent_discuss_all(num = 10):
-    return api_recent_discuss_2(conn, num, 'all')
+    return api_recent_discuss_2(load_db.db_get(), num, 'all')
 
 @app.route('/api/sha224/<everything:name>', methods = ['POST', 'GET'])
 def api_sha224(name = 'test'):
-    return api_sha224_2(conn, name)
+    return api_sha224_2(load_db.db_get(), name)
 
 @app.route('/api/title_index')
 def api_title_index():
-    return api_title_index_2(conn)
+    return api_title_index_2(load_db.db_get())
 
 @app.route('/api/image/<everything:name>', methods = ['POST', 'GET'])
 def api_image_view(name = ''):
-    return api_image_view_2(conn, name)
+    return api_image_view_2(load_db.db_get(), name)
 
 @app.route('/api/sitemap.xml')
 def api_sitemap():
-    return api_sitemap_2(conn)
+    return api_sitemap_2(load_db.db_get())
 
 # Func-main
 # 여기도 전반적인 조정 시행 예정
 @app.route('/restart', methods = ['POST', 'GET'])
 def main_restart():
-    return main_restart_2(conn)
+    return main_restart_2(load_db.db_get())
 
 @app.route('/update', methods=['GET', 'POST'])
 def main_update():
-    return main_update_2(conn, version_list['beta']['r_ver'])
+    return main_update_2(load_db.db_get())
 
 @app.route('/random')
 def main_title_random():
-    return main_title_random_2(conn)
+    return main_title_random_2(load_db.db_get())
 
 @app.route('/upload', methods=['GET', 'POST'])
 def main_upload():
-    return main_upload_2(conn)
+    return main_upload_2(load_db.db_get())
 
 @app.route('/setting')
 @app.route('/setting/<int:num>', methods = ['POST', 'GET'])
 def setting(num = 0):
-    return main_setting_2(conn, num, set_data['db_type'])
+    return main_setting_2(load_db.db_get(), num, data_db_set['type'])
 
 @app.route('/other')
 def main_other():
-    return main_other_2(conn)
+    return main_other_2(load_db.db_get())
 
 @app.route('/manager', methods = ['POST', 'GET'])
 @app.route('/manager/<int:num>', methods = ['POST', 'GET'])
 def main_manager(num = 1):
-    return main_manager_2(conn, num)
+    return main_manager_2(load_db.db_get(), num)
 
 @app.route('/image/<everything:name>')
 def main_image_view(name = None):
-    return main_image_view_2(conn, name)
+    return main_image_view_2(load_db.db_get(), name)
 
 @app.route('/skin_set')
 @app.route('/main_skin_set')
 def main_skin_set():
-    return main_skin_set_2(conn)
+    return main_skin_set_2(load_db.db_get())
 
 @app.route('/views/<everything:name>')
 def main_views(name = None):
-    return main_views_2(conn, name)
+    return main_views_2(load_db.db_get(), name)
 
 @app.route('/test_func')
 def main_test_func():
-	return main_test_func_2(conn)
+    return main_test_func_2(load_db.db_get())
 
 @app.route('/shutdown', methods = ['POST', 'GET'])
 def main_shutdown():
-    return main_shutdown_2(conn)
+    return main_shutdown_2(load_db.db_get())
 
 @app.route('/easter_egg.xml')
 def main_easter_egg():
-    return main_easter_egg_2(conn)
+    return main_easter_egg_2(load_db.db_get())
 
 @app.route('/<regex("[^.]+\.(?:txt|xml)"):data>')
 def main_file(data = ''):
-    return main_file_2(conn, data)
+    return main_file_2(load_db.db_get(), data)
 
 @app.errorhandler(404)
 def main_error_404(e):
-    return main_error_404_2(conn)
-	
+    return main_error_404_2(load_db.db_get())
+    
 if __name__ == "__main__":
-    WSGIServer((
-        server_set['host'], 
-        int(server_set['port'])
-    ), app, log = app.logger).serve_forever()
+    do_server = netius.servers.WSGIServer(app = app)
+    do_server.serve(
+        host = server_set['host'],
+        port = int(server_set['port'])
+    )

+ 6 - 2
emergency_tool.py

@@ -123,7 +123,9 @@ if data_db_load == 'Y':
             data_db_set['mysql_port'] = '3306'
 
     db_data_get(data_db_set['type'])
-    conn = get_conn(data_db_set)
+    load_db = get_db_connect(data_db_set)
+
+    conn = load_db.db_load()
     curs = conn.cursor()
 else:
     print('----')
@@ -197,7 +199,9 @@ if what_i_do == '1':
 
         curs.execute(db_change("select data from data where title = ?"), [name[0]])
         data = curs.fetchall()
-        render_do(name[0], data[0][0], 'backlink', '')
+        
+        get_class_render = class_do_render(conn)
+        get_class_render.do_render(name[0], data[0][0], 'backlink', '')
 elif what_i_do == '2':
     curs.execute(db_change("delete from other where name = 'recaptcha'"))
     curs.execute(db_change("delete from other where name = 'sec_re'"))

+ 13 - 13
lang/en-US.json

@@ -384,7 +384,7 @@
             "close_vote" : "Close vote",
             "re_open_vote" : "Reopen vote",
     "_comment_3_" : "Long",
-        "application_submitted": "Applicatied successfully for registration",
+        "application_submitted": "Registration application successful",
         "waiting_for_approval": "Application for registration has been made successfully. Please wait for approval by administrators.",
         "ie_no_data_required" : "Operation cannot continue because all required data has not been collected.",
         "user_reset_sign" : "Your account information has changed like this.",
@@ -401,16 +401,16 @@
             "update_error" : "Auto update is not supported.",
             "inter_error" : "Internal error.",
             "authority_error" : "Insufficient privileges.",
-            "no_login_error" : "Non-login status.",
+            "no_login_error" : "You are not logged in.",
             "no_exist_user_error" : "The account does not exist.",
             "no_admin_block_error" : "You cannot block or check administrators.",
-            "skin_error" : "This skin is not support settings.",
-            "same_id_exist_error" : "There are users with the same username.",
+            "skin_error" : "The skin you are using does not support individual settings.",
+            "same_id_exist_error" : "There are users using the same username.",
             "long_id_error" : "Username must be shorter than 20 characters.",
-            "id_char_error" : "Only Korean letters, alphabets are allowed for Username.",
+            "id_char_error" : "Only Korean letters and alphabets are allowed for Username.",
             "file_exist_error" : "The file does not exist.",
-            "password_error" : "The password is different.",
-            "recaptcha_error" : "Go through the reCAPTCHA.",
+            "password_error" : "Password does not match.",
+            "recaptcha_error" : "Pass the reCAPTCHA.",
             "file_extension_error" : "Only files with the specified extension can be uploaded.",
             "edit_record_error" : "Edit reason can not be more than 500 characters.",
             "same_file_error" : "A file with the same name exists.",
@@ -428,15 +428,15 @@
             "application_not_found" : "Application not found",
             "invalid_password_error" : "The Password or ID is invalid.",
             "watchlist_overflow_error": "You cannot add more than ten documents.",
-            "copyright_disagreed" : "You have to agree copyright noticement to contribute",
+            "copyright_disagreed" : "You have to agree to the copyright noticement to contribute.",
             "email_send_error" : "Email transfer failed.",
-            "restart_fail_error" : "Restart failed. Please use manual restart.",
+            "restart_fail_error" : "Restart failed. Please try restarting manually.",
             "same_email_error" : "There are users using the same email.",
             "input_email_error" : "There is a problem with the input value.",
         "_comment_3.2_" : "Warning",
-            "http_warning" : "Warning: If you are not on HTTPS connection, Your information can be leaked. We won't response to that.",
+            "http_warning" : "Warning: If you are not on HTTPS connection, your information can be leaked. The users themselves have responsibility to any problems that happen because of this.",
             "user_head_warning" : "User data will be deleted if you close the browser or when you sign in.",
-            "no_login_warning" : "You are not logged in. The IP address will be logged when editing or discussing with non-login.",
-            "update_warning" : "Manual updates are recommended if your version is 0.2 or lower than the latest version. For Windows, the contents of the route folder disappear.",
-            "history_delete_warning" : "If you erase history, it's hard to restore it, so make a careful decision."
+            "no_login_warning" : "You are not logged in. Your current IP address will be logged within editing or discussing until you log in.",
+            "update_warning" : "Manual updates are recommended if your version is 0.2 or lower than the latest version. For Windows, the contents of the route folder will be deleted.",
+            "history_delete_warning" : "If you erase history, it's hard to restore it, so please be careful."
 }

+ 3 - 1
requirements.txt

@@ -1,5 +1,7 @@
 flask
-gevent
+
+waitress
+netius
 
 requests
 

+ 2 - 1
route/api_w.py

@@ -10,7 +10,8 @@ def api_w_2(conn, name):
             data_pas = render_set(
                 doc_name = name, 
                 doc_data = data_org, 
-                data_type = 'api_view'
+                data_type = 'api_view',
+                data_in = 'preview'
             )
 
             return flask.jsonify({

+ 4 - 0
route/edit_delete.py

@@ -47,6 +47,7 @@ def edit_delete_2(conn, name):
 
         file_check = re.search(r'^file:(.+)\.(.+)$', name)
         if file_check:
+            '''
             file_check = file_check.groups()
             file_directory = os.path.join(
                 load_image_url(), 
@@ -54,6 +55,9 @@ def edit_delete_2(conn, name):
             )
             if os.path.exists(file_directory):
                 os.remove(file_directory)
+            '''
+            
+            pass
         else:
             curs.execute(db_change('select data from other where name = "count_all_title"'))
             curs.execute(db_change("update other set data = ? where name = 'count_all_title'"), [str(int(curs.fetchall()[0][0]) - 1)])

+ 43 - 0
route/edit_delete_file.py

@@ -0,0 +1,43 @@
+from .tool.func import *
+
+def edit_delete_file_2(conn, name):
+    curs = conn.cursor()
+
+    ip = ip_check()
+    if admin_check() == 0:
+        return re_error('/ban')
+
+    mime_type = re.search(r'([^.]+)$', name)
+    if mime_type:
+        mime_type = mime_type.group(1).lower()
+    else:
+        mime_type = 'jpg'
+
+    file_name = re.sub(r'\.([^.]+)$', '', 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)
+    
+    if not os.path.exists(file_directory):
+        return redirect('/w/' + url_pas(name))
+
+    if flask.request.method == 'POST':
+        admin_check(None, 'file del (' + name + ')')
+        os.remove(file_directory)
+
+        return redirect('/w/' + url_pas(name))
+    else:
+        return easy_minify(flask.render_template(skin_check(),
+            imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('file_delete') + ')', 0])],
+            data = '''
+                <form method="post">
+                    <img src="/image/''' + url_pas(file_all_name) + '''">
+                    <hr class="main_hr">
+                    <a href="/image/''' + url_pas(file_all_name) + '''">/image/''' + url_pas(file_all_name) + '''</a>
+                    <hr class="main_hr">
+                    <button type="submit">''' + load_lang('file_delete') + '''</button>
+                </form>
+            ''',
+            menu = [['w/' + url_pas(name), load_lang('return')]]
+        ))

+ 1 - 1
route/edit_delete_many.py → route/edit_delete_mutiple.py

@@ -1,7 +1,7 @@
 from .tool.func import *
 from . import edit_delete
 
-def edit_delete_many_2(conn):
+def edit_delete_mutiple_2(conn):
     curs = conn.cursor()
 
     ip = ip_check()

+ 16 - 25
route/inter_wiki.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 
-def inter_wiki_2(conn, tools):
+def inter_wiki(conn, tool):
     curs = conn.cursor()
 
     div = '<table id="main_table_set">'
@@ -14,48 +14,39 @@ def inter_wiki_2(conn, tools):
     
     admin = admin_check()
 
-    if tools == 'inter_wiki':
-        plus_link = 'plus_inter_wiki'
+    if tool == 'inter_wiki':
         title = load_lang('interwiki_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'inter_wiki'"))
-    elif tools == 'email_filter':
-        plus_link = 'plus_email_filter'
+    elif tool == 'email_filter':
         title = load_lang('email_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'email'"))
-    elif tools == 'name_filter':
-        plus_link = 'plus_name_filter'
+    elif tool == 'name_filter':
         title = load_lang('id_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'name'"))
-    elif tools == 'edit_filter':
-        plus_link = 'plus_edit_filter'
+    elif tool == 'edit_filter':
         title = load_lang('edit_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'regex_filter'"))
-    elif tools == 'file_filter':
-        plus_link = 'plus_file_filter'
+    elif tool == 'file_filter':
         title = load_lang('file_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'file'"))
-    elif tools == 'file_filter':
-        plus_link = 'plus_file_filter'
+    elif tool == 'file_filter':
         title = load_lang('file_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'file'"))
-    elif tools == 'image_license':
-        plus_link = 'plus_image_license'
+    elif tool == 'image_license':
         title = load_lang('image_license_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'image_license'"))
-    elif tools == 'extension_filter':
-        plus_link = 'plus_extension_filter'
+    elif tool == 'extension_filter':
         title = load_lang('extension_filter_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'extension'"))
     else:
-        plus_link = 'plus_edit_top'
         title = load_lang('edit_tool_list')
 
         curs.execute(db_change("select html, plus, plus_t from html_filter where kind = 'edit_top'"))
@@ -67,24 +58,24 @@ def inter_wiki_2(conn, tools):
 
         div += data[0]
         if admin == 1:
-            div += ' <a href="/' + tools + '/add/' + url_pas(data[0]) + '">(' + load_lang('edit') + ')</a>'
-            div += ' <a href="/' + tools + '/del/' + url_pas(data[0]) + '">(' + load_lang('delete') + ')</a>'
+            div += ' <a href="/' + tool + '/add/' + url_pas(data[0]) + '">(' + load_lang('edit') + ')</a>'
+            div += ' <a href="/' + tool + '/del/' + url_pas(data[0]) + '">(' + load_lang('delete') + ')</a>'
         
         div += '</td>'
 
-        if tools == 'inter_wiki':
-            div += '<td><a id="out_link" href="' + data[1] + '">' + data[1] + '</a></td>'
+        if tool == 'inter_wiki':
+            div += '<td><a id="out_link" href="' + data[1] + '">' + html.escape(data[1]) + '</a></td>'
         else:
-            div += '<td>' + data[1] + '</td>'
+            div += '<td>' + html.escape(data[1]) + '</td>'
             
-        div += '<td>' + data[2] + '</td>'
+        div += '<td>' + html.escape(data[2]) + '</td>'
         div += '</tr>'
         
     div += '</table>'
             
     if admin == 1:
         div += '<hr class="main_hr">'
-        div += '<a href="/' + tools + '/add">(' + load_lang('add') + ')</a>'
+        div += '<a href="/' + tool + '/add">(' + load_lang('add') + ')</a>'
 
     return easy_minify(flask.render_template(skin_check(),
         imp = [title, wiki_set(), wiki_custom(), wiki_css([0, 0])],

+ 18 - 18
route/inter_wiki_plus.py → route/inter_wiki_add.py

@@ -1,14 +1,14 @@
 from .tool.func import *
 
-def inter_wiki_plus_2(conn, tools, name):
+def inter_wiki_add(conn, tool, name):
     curs = conn.cursor()
     
     if not name:
-        if tools == 'plus_edit_filter':
+        if tool == 'plus_edit_filter':
             return redirect('/manager/9')
 
     if flask.request.method == 'POST':
-        if tools == 'plus_inter_wiki':
+        if tool == 'plus_inter_wiki':
             if name:
                 curs.execute(db_change("delete from html_filter where html = ? and kind = 'inter_wiki'"), [name])
 
@@ -22,7 +22,7 @@ def inter_wiki_plus_2(conn, tools, name):
             ])
 
             admin_check(None, 'inter_wiki_plus')
-        elif tools == 'plus_edit_filter':
+        elif tool == 'plus_edit_filter':
             if admin_check(None, 'edit_filter edit') != 1:
                 return re_error('/error/3')
 
@@ -45,7 +45,7 @@ def inter_wiki_plus_2(conn, tools, name):
         else:
             plus_d = ''
 
-            if tools == 'plus_name_filter':
+            if tool == 'plus_name_filter':
                 try:
                     re.compile(flask.request.form.get('title', 'test'))
                 except:
@@ -54,7 +54,7 @@ def inter_wiki_plus_2(conn, tools, name):
                 admin_check(None, 'name_filter edit')
 
                 type_d = 'name'
-            elif tools == 'plus_file_filter':
+            elif tool == 'plus_file_filter':
                 try:
                     re.compile(flask.request.form.get('title', 'test'))
                 except:
@@ -63,15 +63,15 @@ def inter_wiki_plus_2(conn, tools, name):
                 admin_check(None, 'file_filter edit')
 
                 type_d = 'file'
-            elif tools == 'plus_email_filter':
+            elif tool == 'plus_email_filter':
                 admin_check(None, 'email_filter edit')
 
                 type_d = 'email'
-            elif tools == 'plus_image_license':
+            elif tool == 'plus_image_license':
                 admin_check(None, 'image_license edit')
 
                 type_d = 'image_license'
-            elif tools == 'plus_extension_filter':
+            elif tool == 'plus_extension_filter':
                 admin_check(None, 'extension_filter edit')
 
                 type_d = 'extension'
@@ -95,7 +95,7 @@ def inter_wiki_plus_2(conn, tools, name):
 
         conn.commit()
 
-        return redirect('/' + re.sub(r'^plus_', '', tools))
+        return redirect('/' + re.sub(r'^plus_', '', tool))
     else:
         get_sub = 0
         if admin_check() != 1:
@@ -103,7 +103,7 @@ def inter_wiki_plus_2(conn, tools, name):
         else:
             stat = ''
 
-        if tools == 'plus_inter_wiki':
+        if tool == 'plus_inter_wiki':
             if name:
                 curs.execute(db_change("select html, plus, plus_t from html_filter where html = ? and kind = 'inter_wiki'"), [name])
                 exist = curs.fetchall()
@@ -128,7 +128,7 @@ def inter_wiki_plus_2(conn, tools, name):
                 <hr class="main_hr">
                 <input value="''' + html.escape(value[2]) + '''" type="text" name="icon">
             '''
-        elif tools == 'plus_edit_filter':            
+        elif tool == 'plus_edit_filter':            
             curs.execute(db_change("select plus, plus_t from html_filter where html = ? and kind = 'regex_filter'"), [name])
             exist = curs.fetchall()
             if exist:
@@ -166,35 +166,35 @@ def inter_wiki_plus_2(conn, tools, name):
                 <hr class="main_hr">
                 <input ''' + stat + ''' placeholder="''' + load_lang('regex') + '''" name="content" value="''' + html.escape(textarea) + '''" type="text">
             '''
-        elif tools == 'plus_name_filter':
+        elif tool == 'plus_name_filter':
             title = load_lang('id_filter_add')
             form_data = '' + \
                 load_lang('regex') + \
                 '<hr class="main_hr">' + \
                 '<input value="' + html.escape(name if name else '') + '" type="text" name="title">' + \
             ''
-        elif tools == 'plus_file_filter':
+        elif tool == 'plus_file_filter':
             title = load_lang('file_filter_add')
             form_data = '' + \
                 load_lang('regex') + \
                 '<hr class="main_hr">' + \
                 '<input value="' + html.escape(name if name else '') + '" type="text" name="title">' + \
             ''
-        elif tools == 'plus_email_filter':
+        elif tool == 'plus_email_filter':
             title = load_lang('email_filter_add')
             form_data = '' + \
                 load_lang('email') + \
                 '<hr class="main_hr">' + \
                 '<input value="' + html.escape(name if name else '') + '" type="text" name="title">' + \
             ''
-        elif tools == 'plus_image_license':
+        elif tool == 'plus_image_license':
             title = load_lang('image_license_add')
             form_data = '' + \
                 load_lang('license') + \
                 '<hr class="main_hr">' + \
                 '<input value="' + html.escape(name if name else '') + '" type="text" name="title">' + \
             ''
-        elif tools == 'plus_extension_filter':
+        elif tool == 'plus_extension_filter':
             title = load_lang('extension_filter_add')
             form_data = '' + \
                 load_lang('extension') + \
@@ -232,5 +232,5 @@ def inter_wiki_plus_2(conn, tools, name):
                         <button ''' + stat + ''' type="submit">''' + load_lang('add') + '''</button>
                     </form>
                     ''',
-            menu = [[re.sub('^plus_', '', tools), load_lang('return')]]
+            menu = [[re.sub('^plus_', '', tool), load_lang('return')]]
         ))

+ 10 - 10
route/inter_wiki_del.py

@@ -1,28 +1,28 @@
 from .tool.func import *
 
-def inter_wiki_del_2(conn, tools, name):
+def inter_wiki_del(conn, tool, name):
     curs = conn.cursor()
 
-    if admin_check(None, tools) == 1:
-        if tools == 'del_inter_wiki':
+    if admin_check(None, tool) == 1:
+        if tool == 'del_inter_wiki':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'inter_wiki'"), [name])
-        elif tools == 'del_edit_filter':
+        elif tool == 'del_edit_filter':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'regex_filter'"), [name])
-        elif tools == 'del_name_filter':
+        elif tool == 'del_name_filter':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'name'"), [name])
-        elif tools == 'del_file_filter':
+        elif tool == 'del_file_filter':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'file'"), [name])
-        elif tools == 'del_email_filter':
+        elif tool == 'del_email_filter':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'email'"), [name])
-        elif tools == 'del_image_license':
+        elif tool == 'del_image_license':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'image_license'"), [name])
-        elif tools == 'del_extension_filter':
+        elif tool == 'del_extension_filter':
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'extension'"), [name])
         else:
             curs.execute(db_change("delete from html_filter where html = ? and kind = 'edit_top'"), [name])
 
         conn.commit()
 
-        return redirect('/' + re.sub(r'^del_', '', tools))
+        return redirect('/' + re.sub(r'^del_', '', tool))
     else:
         return re_error('/error/3')

+ 1 - 1
route/list_acl.py

@@ -22,7 +22,7 @@ def list_acl_2(conn):
             div += '' + \
                 '<li>' + \
                     time_data + \
-                    '<a href="/acl/' + url_pas(data[0]) + '">' + data[0] + '</a>' + \
+                    '<a href="/acl/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a>' + \
                     why_data + \
                 '</li>' + \
             ''

+ 1 - 1
route/list_admin_group.py

@@ -16,7 +16,7 @@ def list_admin_group_2(conn):
 
         list_data += '' + \
             '<li>' + \
-                '<a href="/admin_plus/' + url_pas(data[0]) + '">' + data[0] + '</a>' + \
+                '<a href="/admin_plus/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a>' + \
                 delete_admin_group + \
             '</li>' + \
         ''

+ 1 - 1
route/list_image_file.py

@@ -15,7 +15,7 @@ def list_image_file_2(conn):
     curs.execute(db_change("select title from data where title like 'file:%' limit ?, 50"), [sql_num])
     data_list = curs.fetchall()
     for data in data_list:
-        list_data += '<li><a href="/w/' + url_pas(data[0]) + '">' + 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)
 

+ 1 - 1
route/list_long_page.py

@@ -13,7 +13,7 @@ def list_long_page_2(conn, tool):
 
     curs.execute(db_change("select title, length(data) from data order by length(data) " + select_data + " limit 50"))
     for data in curs.fetchall():
-        div += '<li>' + str(data[1]) + ' : <a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+        div += '<li>' + str(data[1]) + ' : <a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a></li>'
 
     div += '</ul>'
 

+ 0 - 19
route/list_not_close_topic.py

@@ -1,19 +0,0 @@
-from .tool.func import *
-
-def list_not_close_topic_2(conn):
-    curs = conn.cursor()
-
-    div = '<ul class="inside_ul">'
-
-    curs.execute(db_change('select title, sub, date, code from rd where stop != "O" order by date desc'))
-    n_list = curs.fetchall()
-    for data in n_list:
-        div += '<li>' + data[2] + ' | <a href="/thread/' + data[3] + '">' + html.escape(data[1]) + '</a> (' + html.escape(data[0]) + ')</li>'
-
-    div += '</ul>'
-
-    return easy_minify(flask.render_template(skin_check(),
-        imp = [load_lang('open_discussion_list'), wiki_set(), wiki_custom(), wiki_css([0, 0])],
-        data = div,
-        menu = [['manager', load_lang('return')]]
-    ))

+ 7 - 2
route/list_please.py

@@ -12,10 +12,15 @@ def list_please_2(conn):
 
     div = '<ul class="inside_ul">'
 
-    curs.execute(db_change("select distinct title from back where type = 'no' order by title asc limit ?, 50"), [sql_num])
+    curs.execute(db_change("select distinct title, link from back where type = 'no' order by title asc limit ?, 50"), [sql_num])
     data_list = curs.fetchall()
     for data in data_list:
-        div += '<li><a id="not_thing" href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+        div += '' + \
+            '<li>' + \
+                '<a id="not_thing" href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a> ' + \
+                '<a href="/w/' + url_pas(data[1]) + '">(' + html.escape(data[1]) + ')</a>' + \
+            '</li>' + \
+        ''
 
     div += '</ul>' + next_fix('/please?num=', num, data_list)
 

+ 1 - 1
route/list_title_index.py

@@ -20,7 +20,7 @@ def list_title_index_2(conn):
         data += '<hr class="main_hr"><ul class="inside_ul">'
 
     for list_data in title_list:
-        data += '<li>' + str(all_list) + '. <a href="/w/' + url_pas(list_data[0]) + '">' + list_data[0] + '</a></li>'
+        data += '<li>' + str(all_list) + '. <a href="/w/' + url_pas(list_data[0]) + '">' + html.escape(list_data[0]) + '</a></li>'
         all_list += 1
 
     if page == 1:

+ 4 - 3
route/main_manager.py

@@ -6,12 +6,12 @@ def main_manager_2(conn, num):
     title_list = {
         0 : [load_lang('document_name'), 'acl', load_lang('acl')],
         1 : [0, 'check', load_lang('check')],
-        2 : [load_lang('file_name'), 'plus_file_filter', load_lang('file_filter_add')],
+        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'), 'plus_edit_filter', load_lang('edit_filter_add')],
+        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')],
@@ -38,7 +38,7 @@ def main_manager_2(conn, num):
                     <h2>2. ''' + load_lang('owner') + '''</h2>
                     <ul class="inside_ul">
                         <li><a href="/admin_group">''' + load_lang('admin_group_list') + '''</a></li>
-                        <li><a href="/many_delete">''' + load_lang('many_delete') + '''</a></li>
+                        <li><a href="/delete/doc_mutiple">''' + load_lang('many_delete') + '''</a></li>
                         <li><a href="/app_submit">''' + load_lang('application_list') + '''</a></li>
                         <li><a href="/api/sitemap.xml">''' + load_lang('get_sitemap') + '''</a></li>
                         <li><a href="/register">''' + load_lang('add_user') + '''</a></li>
@@ -54,6 +54,7 @@ def main_manager_2(conn, num):
                         <li><a href="/name_filter">''' + load_lang('id_filter_list') + '''</a></li>
                         <li><a href="/file_filter">''' + load_lang('file_filter_list') + '''</a></li>
                         <li><a href="/extension_filter">''' + load_lang('extension_filter_list') + '''</a></li>
+                        <li><a href="/doc_filter">''' + load_lang('doc_filter_list') + '''</a></li>
                     </ul>
                     <h3>2.2. ''' + load_lang('server') + '''</h2>
                     <ul class="inside_ul">

+ 0 - 1
route/main_other.py

@@ -21,7 +21,6 @@ def main_other_2(conn):
                 <h3>2.2. ''' + load_lang('discussion') + '''</h3>
                 <ul class="inside_ul">
                     <li><a href="/recent_discuss">''' + load_lang('recent_discussion') + '''</a></li>
-                    <li><a href="/not_close_topic">''' + load_lang('open_discussion_list') + '''</a></li>
                 </ul>
                 <h3>2.3. ''' + load_lang('document') + '''</h3>
                 <ul class="inside_ul">

+ 3 - 0
route/main_test_func.py

@@ -2,6 +2,9 @@ import time
 from .tool.func import *
 
 def main_test_func_2(conn):
+    if admin_check() != 1:
+        return re_error('/error/3')
+    
     test_start = time.time()
 
     for _ in range(0, 10000):

+ 2 - 2
route/main_update.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 
-def main_update_2(conn, r_ver):
+def main_update_2(conn):
     curs = conn.cursor()
 
     if admin_check() != 1:
@@ -47,7 +47,7 @@ def main_update_2(conn, r_ver):
             data = load_lang('update_warning') + '''
                 <hr class=\"main_hr\">
                 <ul class="inside_ul">
-                    <li>''' + load_lang('version') + ' : ' + r_ver + '''</li>
+                    <li>''' + load_lang('version') + ''' : <span id="ver_send_2"></span></li>
                     <li id="ver_send" style="display: none;">''' + load_lang('lastest') + ''' : </li>
                 </ul>
                 <a href="https://github.com/openNAMU/openNAMU">(Beta)</a> <a href="https://github.com/openNAMU/openNAMU/tree/stable">(Stable)</a>

+ 1 - 10
route/main_upload.py

@@ -61,8 +61,7 @@ def main_upload_2(conn):
 
             data_url_image = load_image_url()
             if os.path.exists(os.path.join(data_url_image, e_data)):
-                os.remove(os.path.join(data_url_image, e_data))
-                data.save(os.path.join(data_url_image, e_data))
+                return re_error('/error/16')
             else:
                 data.save(os.path.join(data_url_image, e_data))
 
@@ -75,21 +74,13 @@ def main_upload_2(conn):
             db_data = curs.fetchall()
             if db_data and db_data[0][0] == 'namumark':
                 file_d = '' + \
-                    '[[file:' + name + ']]\n' + \
-                    '{{{[[file:' + name + ']]}}}\n\n' + \
                     flask.request.form.get('f_lice_sel', 'direct_input') + '\n' + \
-                    (ip if ip_or_user(ip) != 0 else '[[user:' + ip + ']]') + '\n' + \
-                    file_size + 'KB\n' + \
                     '[[category:' + re.sub(r'\]', '_', flask.request.form.get('f_lice_sel', '')) + ']]\n' + \
                     (g_lice if g_lice != '' else '') + \
                 ''
             else:
                 file_d = '' + \
-                    'file:' + name + '\n' + \
-                    '/image/' + e_data + '\n\n' + \
                     flask.request.form.get('f_lice_sel', 'direct_input') + '\n' + \
-                    ip + \
-                    file_size + 'KB\n\n' + \
                     (g_lice if g_lice != '' else '') + \
                 ''
 

+ 5 - 6
route/recent_change.py

@@ -87,11 +87,7 @@ def recent_change_2(conn, name, tool):
         all_ip = ip_pas([i[3] for i in data_list])
         for data in data_list:
             select += '<option value="' + data[0] + '">' + data[0] + '</option>'
-            send = '<br>'
-
-            if data[4]:
-                if not re.search(r"^(?: +)$", data[4]):
-                    send = data[4]
+            send = data[4]
 
             if re.search(r"\+", data[5]):
                 leng = '<span style="color:green;">(' + data[5] + ')</span>'
@@ -114,6 +110,7 @@ def recent_change_2(conn, name, tool):
                     ip = ''
                     ban = ''
                     date = ''
+                    send = ''
 
                     style[0] = 'style="display: none;"'
                     style[1] = 'id="toron_color_grey"'
@@ -134,7 +131,9 @@ def recent_change_2(conn, name, tool):
                     <td>''' + date + '''</td>
                 </tr>
                 <tr ''' + style[1] + '''>
-                    <td class="send_content" colspan="3">''' + html.escape(send) + '''</td>
+                    <td class="send_content" colspan="3">
+                        ''' + (html.escape(send) if send != '' else '<br>') + '''
+                    </td>
                 </tr>
             '''
 

+ 18 - 11
route/recent_discuss.py

@@ -1,18 +1,23 @@
 from .tool.func import *
 
-def recent_discuss_2(conn):
+def recent_discuss_2(conn, tool):
     curs = conn.cursor()
 
     div = ''
 
-    if flask.request.args.get('what', 'normal') == 'normal':
-        div += '<a href="/recent_discuss?what=close">(' + load_lang('close_discussion') + ')</a>'
+    if tool == 'normal':
+        div += '<a href="/recent_discuss/close">(' + load_lang('close_discussion') + ')</a> '
+        div += '<a href="/recent_discuss/open">(' + load_lang('open_discussion_list') + ')</a>'
 
         m_sub = 0
-    else:
-        div += '<a href="/recent_discuss">(' + load_lang('open_discussion') + ')</a>'
+    elif tool == 'close':
+        div += '<a href="/recent_discuss">(' + load_lang('normal') + ')</a>'
 
         m_sub = ' (' + load_lang('closed') + ')'
+    else:
+        div += '<a href="/recent_discuss">(' + load_lang('normal') + ')</a>'
+        
+        m_sub = ' (' + load_lang('open_discussion_list') + ')'
 
     div +=  '''
             <hr class="main_hr">
@@ -24,18 +29,20 @@ def recent_discuss_2(conn):
                     </tr>
             '''
 
-    if m_sub == 0:
+    if tool == 'normal':
         curs.execute(db_change("select title, sub, date, code from rd where not stop = 'O' order by date desc limit 50"))
-    else:
+    elif tool == 'close':
         curs.execute(db_change("select title, sub, date, code from rd where stop = 'O' order by date desc limit 50"))
+    else:
+        curs.execute(db_change('select title, sub, date, code from rd where stop != "O" order by date asc limit 50'))
 
     for data in curs.fetchall():
-        title = html.escape(data[0])
-        sub = html.escape(data[1])
-
         div += '' + \
             '<tr>' + \
-                '<td><a href="/thread/' + data[3] + '">' + sub + '</a> <a href="/topic/' + url_pas(title) + '">(' + title + ')</a></td>' + \
+                '<td>' + \
+                    '<a href="/thread/' + data[3] + '">' + html.escape(data[1]) + '</a> ' + \
+                    '<a href="/topic/' + url_pas(data[0]) + '">(' + html.escape(data[0]) + ')</a>' + \
+                '</td>' + \
                 '<td>' + data[2] + '</td>' + \
             '</tr>' + \
         ''

+ 172 - 98
route/tool/func.py

@@ -64,7 +64,7 @@ from .func_mark import *
 
 from diff_match_patch import diff_match_patch
 
-from gevent.pywsgi import WSGIServer
+import netius.servers
 
 import werkzeug.routing
 import werkzeug.debug
@@ -84,59 +84,60 @@ global_wiki_set = {}
 
 global_db_set = ''
 
-data_css_ver = '116'
+data_css_ver = '118'
 data_css = ''
 
 conn = ''
-curs = ''
 
 # Func
 # Func-main
 def load_conn(data):
     global conn
-    global curs
 
     conn = data
-    curs = conn.cursor()
-
-    load_conn2(data)
     
 # Func-init
-def get_conn(db_set = ''):
-    global global_db_set
-    if db_set != '':
-        global_db_set = db_set
-    else:
-        db_set = global_db_set
-    
-    if db_set['type'] == 'sqlite':
-        conn = sqlite3.connect(db_set['name'] + '.db')
-        curs = conn.cursor()
-    else:
-        conn = pymysql.connect(
-            host = db_set['mysql_host'],
-            user = db_set['mysql_user'],
-            password = db_set['mysql_pw'],
-            charset = 'utf8mb4',
-            port = int(db_set['mysql_port'])
-        )
-        curs = conn.cursor()
-    
-        try:
-            curs.execute(db_change(
-                'create database ' + db_set['name'] + ' ' + \
-                'default character set utf8mb4;'
-            ))
-        except:
-            pass
-        
-        conn.select_db(db_set['name'])
+class get_db_connect:
+    def __init__(self, db_set):
+        self.db_set = db_set
+        self.conn = ''
         
-    load_conn(conn)
-        
-    return conn
+    def db_load(self):
+        if self.db_set['type'] == 'sqlite':
+            self.conn = sqlite3.connect(self.db_set['name'] + '.db')
+        else:
+            self.conn = pymysql.connect(
+                host = self.db_set['mysql_host'],
+                user = self.db_set['mysql_user'],
+                password = self.db_set['mysql_pw'],
+                charset = 'utf8mb4',
+                port = int(self.db_set['mysql_port']),
+            )
+            curs = self.conn.cursor()
+
+            try:
+                curs.execute(db_change(
+                    'create database ' + self.db_set['name'] + ' ' + \
+                    'default character set utf8mb4;'
+                ))
+            except:
+                pass
+
+            self.conn.select_db(self.db_set['name'])
+
+        load_conn(self.conn)
+
+        return self.conn
+    
+    def db_get(self):
+        # if self.db_set['type'] != 'sqlite':
+        #     self.conn.ping(reconnect = True)
+            
+        return self.conn
 
 def update(ver_num, set_data):
+    curs = conn.cursor()
+
     print('----')
     # 업데이트 하위 호환 유지 함수
 
@@ -352,6 +353,8 @@ def update(ver_num, set_data):
     print('Update completed')
 
 def set_init_always(ver_num):
+    curs = conn.cursor()
+
     curs.execute(db_change('delete from other where name = "ver"'))
     curs.execute(db_change('insert into other (name, data) values ("ver", ?)'), [ver_num])
     
@@ -364,6 +367,8 @@ def set_init_always(ver_num):
     conn.commit()
     
 def set_init():
+    curs = conn.cursor()
+
     # 초기값 설정 함수    
     curs.execute(db_change("select html from html_filter where kind = 'email'"))
     if not curs.fetchall():
@@ -405,15 +410,16 @@ def set_init():
     conn.commit()
 
 # Func-simple
+## Func-simple-without_DB
 def get_default_admin_group():
     return ['owner', 'ban']
 
-def load_image_url():
-    curs.execute(db_change('select data from other where name = "image_where"'))
-    image_where = curs.fetchall()
-    image_where = image_where[0][0] if image_where else 'data/images'
-    
-    return image_where
+def load_random_key(long = 64):
+    return ''.join(
+        random.choice(
+            "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        ) for i in range(long)
+    )
 
 def http_warning():
     return '''
@@ -428,21 +434,71 @@ def http_warning():
         </script>
     '''
 
+def next_fix(link, num, page, end = 50):
+    list_data = ''
+
+    if num == 1:
+        if len(page) == end:
+            list_data += '' + \
+                '<hr class="main_hr">' + \
+                '<a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>' + \
+            ''
+    elif len(page) != end:
+        list_data += '' + \
+            '<hr class="main_hr">' + \
+            '<a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a>' + \
+        ''
+    else:
+        list_data += '' + \
+            '<hr class="main_hr">' + \
+            '<a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a> <a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>' + \
+        ''
+
+    return list_data
+
+def leng_check(A, B):
+    # B -> new
+    # A -> old
+    return '0' if A == B else (('-' + str(A - B)) if A > B else ('+' + str(B - A)))
+
+def number_check(data):
+    try:
+        int(data)
+        return data
+    except:
+        return '1'
+
+def redirect(data = '/'):
+    return flask.redirect(flask.request.host_url[:-1] + data)
+    
+def get_acl_list(type_d = 'normal'):
+    if type_d == 'user':
+        return ['', 'user', 'all']
+    else:
+        return ['', 'all', 'user', 'admin', 'owner', '50_edit', 'email', 'ban', 'before', '30_day', 'ban_admin']
+
+## Func-simple-with_DB
+def load_image_url():
+    curs = conn.cursor()
+
+    curs.execute(db_change('select data from other where name = "image_where"'))
+    image_where = curs.fetchall()
+    image_where = image_where[0][0] if image_where else os.path.join('data', 'images')
+    
+    return image_where
+
 def load_domain():
+    curs = conn.cursor()
+
     curs.execute(db_change("select data from other where name = 'domain'"))
     domain = curs.fetchall()
     domain = domain[0][0] if domain and domain[0][0] != '' else flask.request.host_url
 
     return domain
 
-def load_random_key(long = 64):
-    return ''.join(
-        random.choice(
-            "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-        ) for i in range(long)
-    )
-
 def edit_button(editor_display = '0'):
+    curs = conn.cursor()
+
     insert_list = []
 
     curs.execute(db_change("select html, plus from html_filter where kind = 'edit_top'"))
@@ -464,6 +520,8 @@ def edit_button(editor_display = '0'):
     return data
 
 def ip_warning():
+    curs = conn.cursor()
+
     if ip_or_user() != 0:
         curs.execute(db_change('select data from other where name = "no_login_warning"'))
         data = curs.fetchall()
@@ -481,52 +539,11 @@ def ip_warning():
         text_data = ''
 
     return text_data
-
-def next_fix(link, num, page, end = 50):
-    list_data = ''
-
-    if num == 1:
-        if len(page) == end:
-            list_data += '' + \
-                '<hr class="main_hr">' + \
-                '<a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>' + \
-            ''
-    elif len(page) != end:
-        list_data += '' + \
-            '<hr class="main_hr">' + \
-            '<a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a>' + \
-        ''
-    else:
-        list_data += '' + \
-            '<hr class="main_hr">' + \
-            '<a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a> <a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>' + \
-        ''
-
-    return list_data
-
-def leng_check(A, B):
-    # B -> new
-    # A -> old
-    return '0' if A == B else (('-' + str(A - B)) if A > B else ('+' + str(B - A)))
-
-def number_check(data):
-    try:
-        int(data)
-        return data
-    except:
-        return '1'
-
-def redirect(data = '/'):
-    return flask.redirect(flask.request.host_url[:-1] + data)
-    
-def get_acl_list(type_d = 'normal'):
-    if type_d == 'user':
-        return ['', 'user', 'all']
-    else:
-        return ['', 'all', 'user', 'admin', 'owner', '50_edit', 'email', 'ban', 'before', '30_day', 'ban_admin']
     
 # Func-login    
 def pw_encode(data, type_d = ''):
+    curs = conn.cursor()
+
     if type_d == '':
         curs.execute(db_change('select data from other where name = "encode"'))
         set_data = curs.fetchall()
@@ -542,6 +559,8 @@ def pw_encode(data, type_d = ''):
             return hashlib.sha3_256(bytes(data, 'utf-8')).hexdigest()
 
 def pw_check(data, data2, type_d = 'no', id_d = ''):
+    curs = conn.cursor()
+
     curs.execute(db_change('select data from other where name = "encode"'))
     db_data = curs.fetchall()
 
@@ -568,9 +587,13 @@ def pw_check(data, data2, type_d = 'no', id_d = ''):
         
 # Func-skin
 def easy_minify(data, tool = None):
+    # without_DB
+
     return data
 
 def load_lang(data, safe = 0):
+    curs = conn.cursor()
+
     global global_lang
 
     ip = ip_check()
@@ -614,6 +637,8 @@ def load_lang(data, safe = 0):
     return html.escape(data + ' (' + lang_name + ')')
 
 def skin_check(set_n = 0):
+    curs = conn.cursor()
+
     # 개편 필요?
     skin_list = load_skin('tenshi', 1)
     skin = skin_list[0]
@@ -644,6 +669,8 @@ def skin_check(set_n = 0):
         return skin
     
 def wiki_css(data):
+    # without_DB
+
     global data_css
     global data_css_ver
 
@@ -674,6 +701,8 @@ def wiki_css(data):
     return data
 
 def cut_100(data):
+    # without_DB
+
     data = re.search(r'<pre style="display: none;" id="render_content_load">([^<>]+)<\/pre>', data)
     if data:
         data = data.group(1)
@@ -685,6 +714,8 @@ def cut_100(data):
         return ''
 
 def wiki_set(num = 1):
+    curs = conn.cursor()
+
     if num == 1:
         skin_name = skin_check(1)
         data_list = []
@@ -732,7 +763,9 @@ def wiki_set(num = 1):
 
     return data_list
 
-def wiki_custom():    
+def wiki_custom():
+    curs = conn.cursor()
+
     ip = ip_check()
     if ip_or_user(ip) == 0:
         user_icon = 1
@@ -799,6 +832,8 @@ def wiki_custom():
     ]
 
 def load_skin(data = '', set_n = 0, default = 0):
+    # without_DB
+
     # data -> 가장 앞에 있을 스킨 이름
     # set_n == 0 -> 스트링으로 반환
     # set_n == 1 -> 리스트로 반환
@@ -844,6 +879,8 @@ def load_skin(data = '', set_n = 0, default = 0):
 
 # Func-markup
 def render_set(doc_name = '', doc_data = '', data_type = 'view', data_in = '', doc_acl = ''):
+    # without_DB
+
     # data_type in ['view', 'raw', 'api_view', 'backlink']
     doc_acl = acl_check(doc_name, 'render') if doc_acl == '' else doc_acl
     doc_data = 0 if doc_data == None else doc_data
@@ -855,12 +892,15 @@ def render_set(doc_name = '', doc_data = '', data_type = 'view', data_in = '', d
             return doc_data
         else:
             if doc_data != 0:
-                return render_do(doc_name, doc_data, data_type, data_in)
+                get_class_render = class_do_render(conn)
+                return get_class_render.do_render(doc_name, doc_data, data_type, data_in)
             else:
                 return 'HTTP Request 404'
 
 # Func-request
 def send_email(who, title, data):
+    curs = conn.cursor()
+
     try:
         curs.execute(db_change('' + \
             'select name, data from other ' + \
@@ -919,6 +959,8 @@ def send_email(who, title, data):
         return 0
 
 def captcha_get():
+    curs = conn.cursor()
+
     data = ''
     
     if ip_or_user() != 0:
@@ -954,6 +996,8 @@ def captcha_get():
     return data
 
 def captcha_post(re_data, num = 1):
+    curs = conn.cursor()
+
     if num == 1:
         curs.execute(db_change('select data from other where name = "sec_re"'))
         sec_re = curs.fetchall()
@@ -972,6 +1016,8 @@ def captcha_post(re_data, num = 1):
 
 # Func-user
 def ip_or_user(data = ''):
+    # without_DB
+
     # 1 == ip
     # 0 == reg
     
@@ -984,6 +1030,8 @@ def ip_or_user(data = ''):
         return 0
 
 def admin_check(num = None, what = None, name = ''):
+    curs = conn.cursor()
+
     ip = ip_check() if name == '' else name
     time_data = get_time()
     pass_ok = 0
@@ -1044,6 +1092,8 @@ def admin_check(num = None, what = None, name = ''):
     return 0
 
 def acl_check(name = 'test', tool = '', topic_num = '1'):
+    curs = conn.cursor()
+
     ip = ip_check()
     get_ban = ban_check()
     acl_c = re.search(r"^user:((?:(?!\/).)*)", name) if name else None
@@ -1236,6 +1286,8 @@ def acl_check(name = 'test', tool = '', topic_num = '1'):
     return 1
 
 def ban_check(ip = None, tool = ''):
+    curs = conn.cursor()
+
     ip = ip_check() if not ip else ip
     tool = '' if not tool else tool
 
@@ -1278,6 +1330,8 @@ def ban_check(ip = None, tool = ''):
     return 0
 
 def ip_pas(raw_ip, type_d = 0):
+    curs = conn.cursor()
+
     hide = 0
     end_ip = {}
     i = 0
@@ -1324,6 +1378,8 @@ def ip_pas(raw_ip, type_d = 0):
         
 # Func-edit
 def slow_edit_check():
+    curs = conn.cursor()
+
     curs.execute(db_change("select data from other where name = 'slow_edit'"))
     slow_edit = curs.fetchall()
     if slow_edit and slow_edit != '0' and admin_check(5) != 1:
@@ -1347,6 +1403,8 @@ def slow_edit_check():
     return 0
 
 def edit_filter_do(data):
+    curs = conn.cursor()
+
     if admin_check(1) != 1:
         curs.execute(db_change(
             "select plus, plus_t from html_filter where kind = 'regex_filter' and plus != ''"
@@ -1368,11 +1426,16 @@ def edit_filter_do(data):
 
 # Func-insert
 def add_alarm(who, context):
+    curs = conn.cursor()
+
     curs.execute(db_change(
         'insert into alarm (name, data, date) values (?, ?, ?)'
     ), [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()
+
     if user_encode == '':
         user_pw_hash = pw_encode(user_pw)
 
@@ -1415,6 +1478,8 @@ def add_user(user_name, user_pw, user_email = '', user_encode = ''):
     conn.commit()
     
 def ua_plus(u_id, u_ip, u_agent, time):
+    curs = conn.cursor()
+
     curs.execute(db_change("select data from other where name = 'ua_get'"))
     rep_data = curs.fetchall()
     if rep_data and rep_data[0][0] != '':
@@ -1428,8 +1493,11 @@ def ua_plus(u_id, u_ip, u_agent, time):
             u_agent, 
             time
         ])
+        conn.commit()
 
 def ban_insert(name, end, why, login, blocker, type_d = None):
+    curs = conn.cursor()
+
     now_time = get_time()
     band = type_d if type_d else ''
 
@@ -1482,6 +1550,8 @@ def ban_insert(name, end, why, login, blocker, type_d = None):
     conn.commit()
 
 def rd_plus(topic_num, date, name = None, sub = None):
+    curs = conn.cursor()
+
     curs.execute(db_change("select code from rd where code = ?"), [topic_num])
     if curs.fetchall():
         curs.execute(db_change("update rd set date = ? where code = ?"), [date, topic_num])
@@ -1493,6 +1563,8 @@ def rd_plus(topic_num, date, name = None, sub = None):
     conn.commit()
 
 def history_plus(title, data, date, ip, send, leng, t_check = '', mode = ''):
+    curs = conn.cursor()
+
     if mode == 'add':
         curs.execute(db_change(
             "select id from history where title = ? order by id + 0 asc limit 1"
@@ -1576,6 +1648,8 @@ def history_plus(title, data, date, ip, send, leng, t_check = '', mode = ''):
 
 # Func-error
 def re_error(data):
+    curs = conn.cursor()
+
     conn.commit()
 
     if data == '/ban':

+ 175 - 153
route/tool/func_mark.py

@@ -2,161 +2,183 @@ from .func_tool import *
 
 # 커스텀 마크 언젠간 다시 추가 예정
 
-conn = ''
-curs = ''
+class class_do_render:
+    def __init__(self, conn):
+        self.conn = conn
+    
+    def do_backlink_generate(self, data_markup, doc_data, doc_name):
+        conn = self.conn
+        curs = self.conn.cursor()
 
-def load_conn2(data):
-    global conn
-    global curs
+        if data_markup == 'namumark':
+            # Link
+            link_re = re.compile(r'\[\[(?!https?:\/\/|inter:|외부:|out:|#)((?:(?!\[\[|\]\]|\|).)+)(?:\]\]|\|)', re.I)
 
-    conn = data
-    curs = conn.cursor()
-    
-def backlink_generate(data_markup, doc_data, doc_name):
-    if data_markup == 'namumark':
-        # Link
-        link_re = re.compile(r'\[\[(?!https?:\/\/|inter:|외부:|out:|#)((?:(?!\[\[|\]\]|\|).)+)(?:\]\]|\|)', re.I)
-        
-        data_link = link_re.findall(doc_data)
-        data_link = list(set(data_link))
-        
-        data_link_end = {}
-        data_link_end['cat'] = []
-        data_link_end['file'] = []
-        data_link_end['link'] = []
-        
-        data_link_end_all = []
-        
-        for i in data_link:
-            data_link_in = i
-            if re.search(r'^(?:분류|category):', data_link_in):
-                data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
-                data_link_end['cat'] += [re.sub(r'^분류:', 'category:', data_link_in)]
-            elif re.search(r'^(?:파일|file):', data_link_in):
-                data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
-                data_link_end['file'] += [re.sub(r'^파일:', 'file:', data_link_in)]
-            else:
-                data_link_in = re.sub(r'([^\\])#(?:[^#]*)$', r'\1', data_link_in)
-                
-                if data_link_in[0] == ':':
-                    data_link_in = re.sub(r'^:', '', data_link_in)
-                elif data_link_in[0] == '/':
-                    data_link_in = doc_name + data_link_in
-                elif len(data_link_in) >= 3 and data_link_in[0:3] == '../':
-                    data_link_in = data_link_in[3:len(data_link_in)]
-                    data_link_in = '' + \
-                        re.sub('\/[^/]+$', '', doc_name) + \
-                        (('/' + data_link_in) if data_link_in != '' else '') + \
-                    ''
-
-                data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
-                data_link_end['link'] += [data_link_in]
-                
-        if data_link_end != {}:
-            data_link_end['cat'] = list(set(data_link_end['cat']))
-            data_link_end['file'] = list(set(data_link_end['file']))
-            data_link_end['link'] = list(set(data_link_end['link']))
-
-            data_link_end_all += [[doc_name, i, 'cat'] for i in data_link_end['cat']]
-            data_link_end_all += [[doc_name, i, 'file'] for i in data_link_end['file']]
-            data_link_end_all += [[doc_name, i, ''] for i in data_link_end['link']]
-            
-            data_link_no = []
-            for i in data_link_end['link']:
-                curs.execute(db_change("select title from data where title = ?"), [i])
-                if not curs.fetchall():
-                    data_link_no += [[doc_name, i, 'no']]
-                    
-            data_link_end_all += data_link_no
-            
-        # Include
-        include_re = re.compile(r'\[include\(((?:(?!\)\]).)+)\)\]', re.I)
-        
-        data_include = include_re.findall(doc_data)
-        data_include = list(set(data_include))
-        
-        for i in data_include:
-            data_include_in = i
-            data_include_in = re.sub(r'([^\\]),.*$', r'\1', data_include_in)
-            
-            data_link_end_all += [[doc_name, data_include_in, 'include']]
-        
-        # Redirect
-        redirect_re = re.compile(r'^#(?:redirect|넘겨주기) ([^\n]+)', re.I)
-        
-        data_redirect = redirect_re.search(doc_data)
-        if data_redirect:
-            data_redirect = data_redirect.group(1)
-            
-            data_redirect = re.sub(r'([^\\])#(?:[^#]*)$', r'\1', data_redirect)
-            
-            data_link_end_all += [[doc_name, data_redirect, 'redirect']]
-    else:
-        # markup == null
-        data_link_end_all = []
-            
-    return data_link_end_all
-
-def render_do(doc_name, doc_data, data_type, data_in):
-    data_in = None if data_in == '' else data_in
-    
-    curs.execute(db_change('select data from other where name = "markup"'))
-    rep_data = curs.fetchall()
-    rep_data = rep_data[0][0] if rep_data else 'namumark'
-    
-    curs.execute(db_change('select html, plus, plus_t from html_filter where kind = "inter_wiki"'))
-    inter_wiki_data = curs.fetchall()
-    wiki_set_data = {
-        "inter_wiki" : {}
-    }
-    for i in inter_wiki_data:
-        wiki_set_data['inter_wiki'][i[0]] = {
-            "logo" : i[2],
-            "link" : i[1]
+            data_link = link_re.findall(doc_data)
+            data_link = list(set(data_link))
+
+            data_link_end = {}
+            data_link_end['cat'] = []
+            data_link_end['file'] = []
+            data_link_end['link'] = []
+
+            data_link_end_all = []
+
+            for i in data_link:
+                data_link_in = i
+                if  data_link_in.startswith('분류:') or \
+                    data_link_in.startswith('category:'):
+                    data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
+                    data_link_end['cat'] += [re.sub(r'^분류:', 'category:', data_link_in)]
+                elif data_link_in.startswith('파일:') or \
+                    data_link_in.startswith('file:'):
+                    data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
+                    data_link_end['file'] += [re.sub(r'^파일:', 'file:', data_link_in)]
+                else:
+                    data_link_in = re.sub(r'([^\\])#(?:[^#]*)$', r'\1', data_link_in)
+
+                    if data_link_in[0] == ':':
+                        data_link_in = re.sub(r'^:분류:', 'category:', data_link_in)
+                        data_link_in = re.sub(r'^:category:', 'category:', data_link_in)
+
+                        data_link_in = re.sub(r'^:file:', 'file:', data_link_in)
+                        data_link_in = re.sub(r'^:파일:', 'file:', data_link_in)
+                    elif data_link_in[0] == '/':
+                        data_link_in = doc_name + data_link_in
+                    elif len(data_link_in) >= 3 and data_link_in[0:3] == '../':
+                        data_link_in = data_link_in[3:len(data_link_in)]
+                        data_link_in = '' + \
+                            re.sub('\/[^/]+$', '', doc_name) + \
+                            (('/' + data_link_in) if data_link_in != '' else '') + \
+                        ''
+
+                    data_link_in = re.sub(r'\\(.)', r'\1', data_link_in)
+                    data_link_end['link'] += [data_link_in]
+
+            if data_link_end != {}:
+                data_link_end['cat'] = list(set(data_link_end['cat']))
+                data_link_end['file'] = list(set(data_link_end['file']))
+                data_link_end['link'] = list(set(data_link_end['link']))
+
+                data_link_end_all += [[doc_name, i, 'cat'] for i in data_link_end['cat']]
+                data_link_end_all += [[doc_name, i, 'file'] for i in data_link_end['file']]
+                data_link_end_all += [[doc_name, i, ''] for i in data_link_end['link']]
+
+                data_link_no = []
+                for i in data_link_end['link']:
+                    curs.execute(db_change("select title from data where title = ?"), [i])
+                    if not curs.fetchall():
+                        data_link_no += [[doc_name, i, 'no']]
+
+                data_link_end_all += data_link_no
+
+            # Include
+            include_re = re.compile(r'\[include\(((?:(?!\)\]).)+)\)\]', re.I)
+
+            data_include = include_re.findall(doc_data)
+            data_include = list(set(data_include))
+
+            for i in data_include:
+                data_include_in = i
+                data_include_in = re.sub(r'([^\\]),.*$', r'\1', data_include_in)
+
+                data_link_end_all += [[doc_name, data_include_in, 'include']]
+
+            # Redirect
+            redirect_re = re.compile(r'^#(?:redirect|넘겨주기) ([^\n]+)', re.I)
+
+            data_redirect = redirect_re.search(doc_data)
+            if data_redirect:
+                data_redirect = data_redirect.group(1)
+
+                data_redirect = re.sub(r'([^\\])#(?:[^#]*)$', r'\1', data_redirect)
+
+                data_link_end_all += [[doc_name, data_redirect, 'redirect']]
+        else:
+            # markup == null
+            data_link_end_all = []
+
+        return data_link_end_all
+
+    def do_render(self, doc_name, doc_data, data_type, data_in):
+        conn = self.conn
+        curs = self.conn.cursor()
+
+        data_in = None if data_in == '' else data_in
+
+        curs.execute(db_change('select data from other where name = "markup"'))
+        rep_data = curs.fetchall()
+        rep_data = rep_data[0][0] if rep_data else 'namumark'
+
+        curs.execute(db_change('select html, plus, plus_t from html_filter where kind = "inter_wiki"'))
+        inter_wiki_data = curs.fetchall()
+        wiki_set_data = {
+            "inter_wiki" : {}
         }
-        
-    wiki_set_data = json.dumps(wiki_set_data, ensure_ascii = False)
-    
-    if data_type != 'backlink':
-        if rep_data == 'namumark':
-            data_in = (data_in + '_') if data_in else ''
-            data_end = [
-                '<pre style="display: none;" id="' + data_in + 'render_content_set">' + html.escape(wiki_set_data) + '</pre>' + \
-                '<pre style="display: none;" id="' + data_in + 'render_content_load">' + html.escape(doc_data) + '</pre>' + \
-                '<div class="render_content" id="' + data_in + 'render_content"></div>', 
-                '''
-                    do_onmark_render(
-                        test_mode = "normal", 
-                        name_id = "''' + data_in + '''render_content",
-                        name_include = "''' + data_in + '''",
-                        name_doc = "''' + doc_name.replace('"', '//"') + '''"
-                    );
-                ''',
-                []
-            ]
+        for i in inter_wiki_data:
+            wiki_set_data['inter_wiki'][i[0]] = {
+                "logo" : i[2],
+                "link" : i[1]
+            }
+
+        wiki_set_data = json.dumps(wiki_set_data, ensure_ascii = False)
+
+        if data_type != 'backlink':
+            if rep_data == 'namumark':
+                data_in = (data_in + '_') if data_in else ''
+                data_end = [
+                    '<pre style="display: none;" id="' + data_in + 'render_content_set">' + html.escape(wiki_set_data) + '</pre>' + \
+                    '<pre style="display: none;" id="' + data_in + 'render_content_load">' + html.escape(doc_data) + '</pre>' + \
+                    '<div class="render_content" id="' + data_in + 'render_content"></div>', 
+                    '''
+                        do_onmark_render(
+                            test_mode = "normal", 
+                            name_id = "''' + data_in + '''render_content",
+                            name_include = "''' + data_in + '''",
+                            name_doc = "''' + doc_name.replace('"', '\\"') + '''"
+                        );
+                    ''',
+                    []
+                ]
+            elif rep_data == 'markdown':
+                data_in = (data_in + '_') if data_in else ''
+                data_end = [
+                    '<pre style="display: none;" id="' + data_in + 'render_content_set">' + html.escape(wiki_set_data) + '</pre>' + \
+                    '<pre style="display: none;" id="' + data_in + 'render_content_load">' + html.escape(doc_data) + '</pre>' + \
+                    '<div class="render_content" id="' + data_in + 'render_content"></div>', 
+                    '''
+                        do_onmark_render(
+                            test_mode = "normal", 
+                            name_id = "''' + data_in + '''render_content",
+                            name_include = "''' + data_in + '''",
+                            name_doc = "''' + doc_name.replace('"', '\\"') + '''"
+                        );
+                    ''',
+                    []
+                ]
+            else:
+                data_end = [
+                    doc_data, 
+                    '', 
+                    []
+                ]
+
+            if data_type == 'api_view':
+                return [
+                    data_end[0], 
+                    data_end[1]
+                ]
+            else:
+                return data_end[0] + '<script>' + data_end[1] + '</script>'
         else:
-            data_end = [
+            backlink = self.do_backlink_generate(
+                rep_data, 
                 doc_data, 
-                '', 
-                []
-            ]
-
-        if data_type == 'api_view':
-            return [
-                data_end[0], 
-                data_end[1]
-            ]
-        else:
-            return data_end[0] + '<script>' + data_end[1] + '</script>'
-    else:
-        backlink = backlink_generate(
-            rep_data, 
-            doc_data, 
-            doc_name
-        )
-        
-        if backlink != []:
-            curs.executemany(db_change("insert into back (link, title, type) values (?, ?, ?)"), backlink)
-            curs.execute(db_change("delete from back where title = ? and type = 'no'"), [doc_name])
-
-        conn.commit()
+                doc_name
+            )
+
+            if backlink != []:
+                curs.executemany(db_change("insert into back (link, title, type) values (?, ?, ?)"), backlink)
+                curs.execute(db_change("delete from back where title = ? and type = 'no'"), [doc_name])
+
+            conn.commit()

+ 1 - 1
route/topic.py

@@ -106,7 +106,7 @@ def topic_2(conn, topic_num):
                 <a href="/thread/''' + topic_num + '/tool">(' + load_lang('topic_tool') + ''')</a>
                 <hr class="main_hr">
                 <form style="''' + display + '''" method="post">
-                    <textarea id="content" class="topic_content" placeholder="''' + load_lang('content') + '''" name="content"></textarea>
+                    <textarea id="textarea_edit_view" class="topic_content" placeholder="''' + load_lang('content') + '''" name="content"></textarea>
                     <hr class="main_hr">
                     ''' + captcha_get() + (ip_warning() if display == '' else '') + '''
                     <input style="display: none;" name="topic" value="''' + name + '''">

+ 1 - 1
route/user_alarm.py

@@ -14,7 +14,7 @@ def user_alarm_2(conn):
         data = '<a href="/alarm/delete">(' + load_lang('delete') + ')</a><hr class=\"main_hr\">' + data
 
         for data_one in data_list:
-            data += '<li>' + data_one[0] + ' (' + data_one[1] + ')</li>'
+            data += '<li>' + html.escape(data_one[0]) + ' (' + data_one[1] + ')</li>'
 
     data += '</ul>' + next_fix('/alarm?num=', num, data_list)
 

+ 2 - 2
route/user_setting_pw_change.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 
-def login_pw_change_2(conn):
+def user_setting_pw_change_2(conn):
     curs = conn.cursor()
 
     if ban_check() == 1:
@@ -63,4 +63,4 @@ def login_pw_change_2(conn):
                 </form>
             ''',
             menu = [['change', load_lang('return')]]
-        ))
+        ))

+ 1 - 1
route/view_down.py

@@ -7,7 +7,7 @@ def view_down_2(conn, name):
 
     curs.execute(db_change("select title from data where title like ?"), [name + '/%'])
     for data in curs.fetchall():
-        div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+        div += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a></li>'
 
     div += '</ul>'
 

+ 51 - 21
route/view_read.py

@@ -4,8 +4,14 @@ def view_read_2(conn, name, doc_rev, doc_from):
     curs = conn.cursor()
 
     sub = ''
-    div = ''
+    menu = []
+    
+    user_doc = ''
+    category_doc = ''
+    file_data = ''
+    
     ip = ip_check()
+    
     name_doc_pass = doc_from
     uppage = re.sub(r"/([^/]+)$", '', name)
     num = str(doc_rev)        
@@ -23,19 +29,54 @@ def view_read_2(conn, name, doc_rev, doc_from):
         curs.execute(db_change("select link from back where title = ? and type = 'cat' order by link asc"), [name])
         category_sql = curs.fetchall()
         for data in category_sql:
-            if re.search(r'^category:', data[0]):
-                category_sub += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
+            if data[0].startswith('category:'):
+                category_sub += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a></li>'
             else:
-                category_doc += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a> <a id="inside" href="/xref/' + url_pas(data[0]) + '">(' + load_lang('backlink') + ')</a></li>'
+                category_doc += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a> <a id="inside" href="/xref/' + url_pas(data[0]) + '">(' + load_lang('backlink') + ')</a></li>'
 
         if category_doc != '':
             category_doc = '<h2 id="cate_normal">' + load_lang('category_title') + '</h2><ul class="inside_ul">' + category_doc + '</ul>'
 
         if category_sub != '':
             category_doc += '<h2 id="cate_under">' + load_lang('under_category') + '</h2><ul class="inside_ul">' + category_sub + '</ul>'
+    elif re.search(r"^user:([^/]*)", name):
+        match = re.search(r"^user:([^/]*)", name)
+        user_name = html.escape(match.group(1))
+        user_doc = '''
+            <div id="get_user_info"></div>
+            <script>load_user_info("''' + user_name + '''");</script>
+            <hr class="main_hr">
+        '''
+        if name == 'user:' + user_name:
+            menu += [['w/' + url_pas(name) + '/' + url_pas(get_time().split()[0]), load_lang('today_doc')]]
+    elif re.search(r"^file:", name):
+        mime_type = re.search(r'([^.]+)$', name)
+        if mime_type:
+            mime_type = mime_type.group(1).lower()
+        else:
+            mime_type = 'jpg'
+            
+        file_name = re.sub(r'\.([^.]+)$', '', name)
+        file_name = re.sub(r'^file:', '', file_name)
+        
+        file_all_name = sha224_replace(file_name) + '.' + mime_type
+        file_path_name = os.path.join(load_image_url(), file_all_name)
+        if os.path.exists(file_path_name):
+            file_size = str(round(os.path.getsize(file_path_name) / 1000, 1))
+            file_data = '''
+                <img src="/image/''' + url_pas(file_all_name) + '''">
+                <h2>DATA</h2>
+                <table>
+                    <tr><td>URL</td><td><a href="/image/''' + url_pas(file_all_name) + '''">LINK</a></td></tr>
+                    <tr><td>VOLUME</td><td>''' + file_size + '''KB</td></tr>
+                </table>
+                <h2>CONTENT</h2>
+            '''
+
+            menu += [['delete/doc_file/' + url_pas(name), load_lang('file_delete')]]
+        else:
+            file_data = ''
             
-        div += category_doc
-
     if num != '0':
         curs.execute(db_change("select title from history where title = ? and id = ? and hide = 'O'"), [name, num])
         if curs.fetchall() and admin_check(6) != 1:
@@ -92,7 +133,7 @@ def view_read_2(conn, name, doc_rev, doc_from):
         response_data = 200
 
     if num != '0':
-        menu = [['history/' + url_pas(name), load_lang('history')]]
+        menu += [['history/' + url_pas(name), load_lang('history')]]
         sub = ' (r' + str(num) + ')'
         acl = 0
         r_date = 0
@@ -101,9 +142,9 @@ def view_read_2(conn, name, doc_rev, doc_from):
         acl = 1 if curs.fetchall() else 0
         menu_acl = 1 if acl_check(name) == 1 else 0
         if response_data == 404:
-            menu = [['edit/' + url_pas(name), load_lang('create'), menu_acl]] 
+            menu += [['edit/' + url_pas(name), load_lang('create'), menu_acl]] 
         else:
-            menu = [['edit/' + url_pas(name), load_lang('edit'), menu_acl]]
+            menu += [['edit/' + url_pas(name), load_lang('edit'), menu_acl]]
             
         menu += [
             ['topic/' + url_pas(name), load_lang('discussion'), topic], 
@@ -131,18 +172,7 @@ def view_read_2(conn, name, doc_rev, doc_from):
         r_date = curs.fetchall()
         r_date = r_date[0][0] if r_date else 0
 
-    div = end_data + div
-
-    match = re.search(r"^user:([^/]*)", name)
-    if match:
-        user_name = html.escape(match.group(1))
-        div = '''
-            <div id="get_user_info"></div>
-            <script>load_user_info("''' + user_name + '''");</script>
-            <hr class="main_hr">
-        ''' + div
-        if name == 'user:' + user_name:
-            menu += [['w/' + url_pas(name) + '/' + url_pas(get_time().split()[0]), load_lang('today_doc')]]
+    div = file_data + user_doc + end_data + category_doc
 
     curs.execute(db_change("select data from other where name = 'body'"))
     body = curs.fetchall()

+ 10 - 7
route/view_xref.py

@@ -1,6 +1,6 @@
 from .tool.func import *
 
-def view_xref_2(conn, name):
+def view_xref_2(conn, name, xref_type = '1'):
     curs = conn.cursor()
 
     if acl_check(name, 'render') == 1:
@@ -9,18 +9,21 @@ def view_xref_2(conn, name):
     num = int(number_check(flask.request.args.get('num', '1')))
     sql_num = (num * 50 - 50) if num * 50 > 0 else 0
     
-    xref_type = flask.request.args.get('change', '1')
     if xref_type == '1':
-        div = '<a href="?change=2">(' + load_lang('link_in_this') + ')</a><hr class="main_hr">'
+        div = '<a href="/xref/this/' + url_pas(name) + '">(' + load_lang('link_in_this') + ')</a><hr class="main_hr">'
+        
+        data_sub = '(' + load_lang('backlink') + ')'
     else:
-        div = '<a href="?change=1">(' + load_lang('normal') + ')</a><hr class="main_hr">'
+        div = '<a href="/xref/' + url_pas(name) + '">(' + load_lang('normal') + ')</a><hr class="main_hr">'
+        
+        data_sub = '(' + load_lang('link_in_this') + ')'
 
     div += '<ul class="inside_ul">'
 
     sql_insert = ['link', 'title'] if xref_type == '1' else ['title', 'link']
     curs.execute(db_change("" + \
         "select distinct " + sql_insert[0] + ", type from back " + \
-        "where " + sql_insert[1] + " = ? and not type = 'cat' and not type = 'no' and not type = 'nothing'" + \
+        "where " + sql_insert[1] + " = ? and not type = 'no' and not type = 'nothing'" + \
         "order by type asc, title asc limit ?, 50" + \
     ""), [
         name,
@@ -29,7 +32,7 @@ def view_xref_2(conn, name):
 
     data_list = curs.fetchall()
     for data in data_list:
-        div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a>'
+        div += '<li><a href="/w/' + url_pas(data[0]) + '">' + html.escape(data[0]) + '</a>'
 
         if data[1]:
             div += ' (' + data[1] + ')'
@@ -44,7 +47,7 @@ def view_xref_2(conn, name):
     div += '</ul>' + next_fix('/xref/' + url_pas(name) + '?change=' + xref_type + '&num=', num, data_list)
 
     return easy_minify(flask.render_template(skin_check(),
-        imp = [name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('backlink') + ')', 0])],
+        imp = [name, wiki_set(), wiki_custom(), wiki_css([data_sub, 0])],
         data = div,
         menu = [['w/' + url_pas(name), load_lang('return')], ['backlink_reset/' + url_pas(name), load_lang('reset_backlink')]]
     ))

+ 2 - 2
version.json

@@ -1,7 +1,7 @@
 {
     "beta" : {
-        "r_ver" : "v3.4.1-stable (stable1) (beta6) (dev8)",
+        "r_ver" : "v3.4.2-stable (stable1) (beta12) (dev18)",
         "c_ver" : "3500101",
-        "s_ver" : "3500101"
+        "s_ver" : "3500110"
     }
 }

+ 2 - 2
views/main_css/js/load_skin_set.js

@@ -153,8 +153,8 @@ function main_css_skin_load() {
     }
     
     if(
-        document.cookie.match(regex_data('main_css_darkmode')) &&
-        document.cookie.match(regex_data('main_css_darkmode'))[1] === '1'
+        document.cookie.match(main_css_regex_data('main_css_darkmode')) &&
+        document.cookie.match(main_css_regex_data('main_css_darkmode'))[1] === '1'
     ) {
         head_data.innerHTML += '' +
             '<link rel="stylesheet" href="/views/main_css/css/sub/dark.css?ver=5">' +

+ 1 - 2
views/main_css/js/render_html.js

@@ -11,8 +11,7 @@ function render_html(name = '') {
                 'b', 'i', 's', 'del', 'strong', 'bold', 'em', 'sub', 'sup', 
                 'div', 'span', 
                 'a',
-                'iframe',
-                'video'
+                'iframe'
             ];
             for(var key in t_data) {
                 patt = new RegExp(

+ 17 - 9
views/main_css/js/render_onmark.js

@@ -361,6 +361,7 @@ function do_onmark_link_render(data, data_js, name_doc, name_include, data_nowik
                             'href="">' + link_out + '</a>';
             } else if(link_real.match(inter_re)) {
                 let data_inter = link_real.match(inter_re);
+                
                 let data_inter_link = '';
                 let data_inter_logo = '';
                 if(data_inter) {
@@ -377,6 +378,10 @@ function do_onmark_link_render(data, data_js, name_doc, name_include, data_nowik
                             ''
                         );
                     }
+                    
+                    var data_inter_var = do_link_change(link_real, data_nowiki, 1);
+                    var data_inter_link_main = data_inter_var[0];
+                    var data_inter_link_sub = data_inter_var[1];
                         
                     let data_inter_get = data_wiki_set['inter_wiki'][data_inter[1]];
                     if(data_inter_get) {
@@ -398,7 +403,7 @@ function do_onmark_link_render(data, data_js, name_doc, name_include, data_nowik
                     '';
                     data_js += '' +
                         'document.getElementsByName("' + name_include + 'set_link_' + num_link_str + '")[0].href = ' + 
-                        '"' + data_inter_link + do_url_change(link_real) + '";' +
+                        '"' + data_inter_link + do_url_change(data_inter_link_main) + data_inter_link_sub + '";' +
                             '\n' +
                     '';
 
@@ -503,7 +508,7 @@ function do_onmark_footnote_render(data, name_include) {
             
             footnote_end_data += '' +
                 '<li>' +
-                    '<a href="javascript:do_open_foot(\'' + name_include + 'fn-' + String(i) + '\', 1);" ' +
+                    '<a href="javascript:do_open_foot(\'' + name_include + '\', \'fn-' + String(i) + '\', 1);" ' +
                         'id="' + name_include + 'cfn-' + String(i) + '">' +
                         '(' + footnote_name + ')' +
                     '</a> <span id="' + name_include + 'fn-' + String(i) + '">' + footnote_line_data + '</span>' +
@@ -511,7 +516,7 @@ function do_onmark_footnote_render(data, name_include) {
             '';
             data = data.replace(footnote_re, '' +
                 '<sup>' +
-                    '<a href="javascript:do_open_foot(\'' + name_include + 'fn-' + String(i) + '\', 0);" ' +
+                    '<a href="javascript:do_open_foot(\'' + name_include + '\', \'fn-' + String(i) + '\', 0);" ' +
                         'id="' + name_include + 'rfn-' + String(i) + '">' +
                         '(' + footnote_name + ')' +
                     '</a>' +
@@ -529,7 +534,7 @@ function do_onmark_footnote_render(data, name_include) {
         }
     }
     
-    if(name_include === '' && footnote_end_data !== '') {
+    if(footnote_end_data !== '') {
         data = do_end_br_replace(data) + '<ul id="footnote_data">' + footnote_end_data + '</ul>';
     }
     
@@ -862,7 +867,7 @@ function do_onmark_include_render(data, data_js, name_include, data_nowiki) {
 
 function do_onmark_nowiki_before_render(data, data_js, name_include, data_nowiki) {   
     var num_nowiki = 0;
-    data = data.replace(/\\(.)/g, function(x, x_1) {
+    data = data.replace(/\\(&gt;|&lt;|.)/g, function(x, x_1) {
         num_nowiki += 1;
         data_nowiki[name_include + 'nowiki_one_' + String(num_nowiki)] = x_1;
         data_js += do_data_try_insert(name_include + 'nowiki_one_' + String(num_nowiki), do_js_safe_change(x_1));
@@ -1245,8 +1250,9 @@ function do_onmark_redirect_render(data, data_js, name_doc) {
         var link_sub = link_data_var[1];
         
         if(
+            name_include == '' &&
             window.location.search === '' &&
-            window.location.pathname.match(/^\/w\//)
+            !window.location.pathname.match(/\/doc_from\//)
         ) {
             window.location.href = '/w/' + do_url_change(link_main) + '/doc_from/' + do_url_change(name_doc) + link_sub;
         }
@@ -1268,6 +1274,8 @@ function do_onmark_remark_render(data) {
 }
 
 // Main
+// var 쓰인 부분 전부 let으로 변경하기 (호이스팅 혼용 방지)
+// 중첩 함수 구조로 개편하기
 function do_onmark_render(
     test_mode = 'test', 
     name_id = '', 
@@ -1294,7 +1302,7 @@ function do_onmark_render(
     var data_backlink = [];
     var data_nowiki = {};
 
-    var data_var = do_onmark_redirect_render(data, data_js, name_doc);
+    var data_var = do_onmark_redirect_render(data, data_js, name_doc, name_include);
     data = data_var[0];
     data_js = data_var[1];
     var passing = data_var[2];
@@ -1349,9 +1357,9 @@ function do_onmark_render(
     data_js += '' + 
         'get_link_state("' + name_include + '");\n' + 
         'get_file_state("' + name_include + '");\n' + 
-		'get_heading_name();'
+		'get_heading_name();' +
+        'render_html("' + name_include + 'nowiki_html");\n' +
     ''
-    data_js += 'render_html("' + name_include + 'nowiki_html");\n'
     
     if(test_mode === 'normal') {
         document.getElementById(name_id).innerHTML = data + '<script>' + data_js + '</script>';

+ 12 - 21
views/main_css/js/render_wiki.js

@@ -296,38 +296,29 @@ function do_open_folding(data, element = '') {
     }
 }
 
-function do_open_foot(name, num = 0) {
-    var found_include = name.match(/^(include_(?:[0-9]+)\-)/);
-    if(found_include) {
-        var include_name = name.replace(/^(?:include_(?:[0-9]+)\-)/, '');
-        var front_data = found_include[1];
-    } else {
-        var include_name = name;
-        var front_data = '';
-    }
-
+function do_open_foot(front_data, name, num = 0) {    
     if(
         document.cookie.match(main_css_regex_data('main_css_footnote_set')) &&
         document.cookie.match(main_css_regex_data('main_css_footnote_set'))[1] === '1'
     ) {
         if(num === 1) {
-            document.getElementById(front_data + 'r' + include_name).focus();
+            document.getElementById(front_data + 'r' + name).focus();
         } else {
-            var get_data = document.getElementById(front_data + include_name).innerHTML;
-            var org_data = document.getElementById(front_data + 'd' + include_name).innerHTML;
+            var get_data = document.getElementById(front_data + name).innerHTML;
+            var org_data = document.getElementById(front_data + 'd' + name).innerHTML;
             if(org_data === '') {
-                document.getElementById(front_data + 'd' + include_name).innerHTML = '' +
-                    '<a href="#' + front_data + 'c' + include_name + '">(Go)</a> ' + get_data +
+                document.getElementById(front_data + 'd' + name).innerHTML = '' +
+                    '<a href="#' + front_data + 'c' + name + '">(Go)</a> ' + get_data +
                 '';
-                document.getElementById(front_data + 'd' + include_name).className = 'spead_footnote';
+                document.getElementById(front_data + 'd' + name).className = 'spead_footnote';
             } else {
-                document.getElementById(front_data + 'd' + include_name).innerHTML = '';
-                document.getElementById(front_data + 'd' + include_name).className = '';
+                document.getElementById(front_data + 'd' + name).innerHTML = '';
+                document.getElementById(front_data + 'd' + name).className = '';
             }
         }
     } else {
-        document.getElementById(front_data + 'r' + include_name).style.color = 'red';
-        document.getElementById(front_data + 'c' + include_name).style.color = (num === 1 ? 'inherit' : 'red');
-        document.getElementById(front_data + (num === 1 ? 'r' : 'c') + include_name).focus();
+        document.getElementById(front_data + 'r' + name).style.color = 'red';
+        document.getElementById(front_data + 'c' + name).style.color = (num === 1 ? 'inherit' : 'red');
+        document.getElementById(front_data + (num === 1 ? 'r' : 'c') + name).focus();
     }
 }

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

@@ -0,0 +1,186 @@
+body {
+    margin: 0;
+}
+
+html {
+    background: #eee;
+}
+
+header#main {
+    border-bottom: 0;
+    
+    line-height: 50px;
+    
+    padding-left: 20px;
+    padding-right: 20px;
+    
+    background-color: #99ddff;
+}
+
+header#main a {
+    color: black;
+}
+
+header#main span#right {
+    float: right;
+}
+
+header#main form.not_mobile input.search {
+    display: inline-block;
+    
+    width: 200px;
+}
+
+header#main form.not_mobile {
+    display: inline-block;
+}
+
+input.search {
+    height: 35px;
+    
+    vertical-align: middle;
+    
+    margin-top: -5px;
+    
+    border: 0;
+    
+    padding: 10px;
+}
+
+input.only_mobile.search {
+    width: calc(100% - 70px);
+    
+    display: inline-block;
+}
+
+input.search:focus-visible {
+    outline: none;
+}
+
+button.search_button {
+    width: 35px;
+    height: 35px;
+    
+    vertical-align: middle;
+    
+    margin-top: -5px;
+    margin-left: -5px;
+    
+    border: 0;
+    
+    font-size: 20px;
+    
+    line-height: 0px;
+}
+
+button.search_button#goto {
+    background-color: #ccffbb;
+}
+
+button.search_button#search {
+    background-color: #ffeecc;
+}
+
+aside {
+    width: 250px;
+    
+    float: left;
+    
+    display: inline-block;
+    
+    padding-top: 10px;
+    padding-left: 20px;
+    padding-right: 20px;
+    
+    background-color: #ffeaee;
+    
+    height: calc(100vh - (50px + 20px));
+}
+
+aside button {
+    width: 25%;
+}
+
+section {
+    width: calc(100% - (250px + 40px));
+    
+    display: inline-block;
+    
+    border-left: 0px solid;
+    
+    background-color: white;
+}
+
+header#section {
+    padding-top: 11px;
+    padding-bottom: 11px;
+    
+    border-bottom: 0px solid;
+    
+    background-color: #cceeff;
+}
+
+article.main {
+    max-width: 1000px;
+    
+    padding-left: 20px;
+    padding-right: 20px;
+    
+    margin: auto;
+}
+
+article.main#content {
+    padding-top: 20px;
+    
+    min-height: 400px;
+}
+
+article.main#title h1 {
+    margin: 0;
+}
+
+.only_mobile, header#main form.only_mobile {
+    display: none;
+}
+
+@media screen and (max-width: 1000px) {    
+    aside {        
+        float: none;
+        
+        border-top: 0px solid;
+        
+        width: calc(100vw - 40px);
+        height: 100%;
+        
+        padding: 20px;
+    }
+    
+    section {
+        width: 100vw;
+        
+        padding-bottom: 20px;
+        
+        border-left: 0;
+    }
+    
+    .not_mobile, header#main form.not_mobile {
+        display: none;
+    }
+    
+    .only_mobile, header#main form.only_mobile {
+        display: block;
+    }
+}
+
+footer {
+    border-top: 0px solid;
+    
+    margin-top: 20px;
+    background: #eee;
+    
+    padding: 20px;
+}
+
+footer.only_mobile {
+    margin-top: 0px;
+}

+ 107 - 0
views/ringo/index.html

@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        {% if imp[3][0] != 0 %}
+            <title>{{imp[0]}} {{imp[3][0]}} - {{imp[1][0]}}</title>
+        {% else %}
+            <title>{{imp[0]}} - {{imp[1][0]}}</title>
+        {% endif %}
+        {{imp[3][3]|safe}}
+        <script src="https://code.iconify.design/1/1.0.3/iconify.min.js"></script>
+        <link rel="stylesheet" href="/views/ringo/css/main.css?ver=1">
+        <link rel="shortcut icon" href="/views/main_css/file/favicon.ico?ver=1">
+        {{imp[1][5]|safe}}
+        {{imp[2][3]|safe}}
+        {% if imp[3][0] != 0 %}
+            <meta name="title" content="{{imp[0]}}{{imp[3][0]}} - {{imp[1][0]}}">
+        {% else %}
+            <meta name="title" content="{{imp[0]}} - {{imp[1][0]}}">
+        {% endif %}
+        <meta name="keywords" content="{{imp[0]}}">
+        {% if imp[2][12] != 0 and imp[2][12] == 'w' %}
+            <meta name="description" content="{{data|cut_100}}">
+        {% endif %}
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+    </head>
+    <body>
+        <header id="main">
+            <span id="left">
+                <span id="logo"><a href="/">{{imp[1][4]|safe}}</a></span>
+            </span>
+            <span id="right">
+                <span class="top_cel" id="">
+                    <span class="iconify" data-icon="ic:baseline-access-time" data-inline="true"></span>
+                    <span class="not_mobile">{{'list'|load_lang}}</span>
+                    <span class="iconify" data-icon="ic:baseline-arrow-drop-down" data-inline="true"></span>
+                </span>
+                <span class="top_cel" id="">
+                    <span class="iconify" data-icon="ic:baseline-archive" data-inline="true"></span>
+                    <span class="not_mobile">{{'tool'|load_lang}}</span>
+                    <span class="iconify" data-icon="ic:baseline-arrow-drop-down" data-inline="true"></span>
+                </span>
+                <span class="top_cel" id="">
+                    {% if imp[2][2] == 1 %}
+                        {% if imp[2][8] != '0' %}
+                            <span class="iconify" data-icon="ic:baseline-add-alert" data-inline="true"></span>
+                        {% else %}
+                            <span class="iconify" data-icon="ic:baseline-person-add" data-inline="true"></span>
+                        {% endif %}
+                    {% else %}
+                        <span class="iconify" data-icon="ic:baseline-person" data-inline="true"></span>
+                    {% endif %}
+                    <span class="not_mobile">{{'tool'|load_lang}}</span>
+                    <span class="iconify" data-icon="ic:baseline-arrow-drop-down" data-inline="true"></span>
+                </span>
+                <form class="not_mobile" method="post" action="/search" role="search">
+                    <input class="not_mobile search" name="search" placeholder="{{'search'|load_lang}}" autocomplete="off" type="search">
+                    <button type="submit" id="goto" formaction="/goto" class="search_button">
+                        <span class="iconify" data-icon="ic:round-find-in-page" data-inline="true"></span>
+                    </button>
+                    <button type="submit" id="search" formaction="/search" class="search_button">
+                        <span class="iconify" data-icon="ic:baseline-search" data-inline="true"></span>
+                    </button>
+                </form>
+            </span>
+            <form class="only_mobile" method="post" action="/search" role="search">
+                <input class="only_mobile search" name="search" placeholder="{{'search'|load_lang}}" autocomplete="off" type="search">
+                <button type="submit" id="goto" formaction="/goto" class="search_button">
+                    <span class="iconify" data-icon="ic:round-find-in-page" data-inline="true"></span>
+                </button>
+                <button type="submit" id="search" formaction="/search" class="search_button">
+                    <span class="iconify" data-icon="ic:baseline-search" data-inline="true"></span>
+                </button>
+            </form>
+        </header>
+        <section>
+            <header id="section">
+                <article class="main" id="title">
+                    <h1><span class="change_space">{{imp[0]}}</span></h1>
+                </article>
+            </header>
+            <article class="main" id="content">
+                {{data|safe}}
+            </article>
+            <footer class="not_mobile">
+                <article class="main" id="footer">
+                    {{imp[1][1]|safe}}
+                    <br>
+                    <br>
+                    <a href="https://github.com/openNAMU/openNAMU"><img id="b_logo" src="/views/main_css/file/s_logo.png"></a>
+                </article>
+            </footer>
+        </section>
+        <aside>
+            <button class="side_button selected">A</button><!--
+         --><button class="side_button">B</button><!--
+         --><button class="side_button">C</button><!--
+         --><button class="side_button">D</button>
+        </aside>
+        <footer class="only_mobile">
+            {{imp[1][1]|safe}}
+            <br>
+            <br>
+            <a href="https://github.com/openNAMU/openNAMU"><img id="b_logo" src="/views/main_css/file/s_logo.png"></a>
+        </footer>
+    </body>
+</html>

+ 26 - 11
views/tenshi/index.html

@@ -131,18 +131,33 @@
                 <div id="main_top">
                     {% if menu != 0 %}
                         <div id="tool" class="not_mobile">
-                            {% for sub_d in menu %}
-                                <div id="tool_cel">
-                                    {% if sub_d|length > 2 and sub_d[2] == 1 %}
-                                        <a class="menu-item" href="/{{sub_d[0]}}" id="topic_color">{{sub_d[1]}}</a>
-                                    {% else %}
-                                        <a class="menu-item" href="/{{sub_d[0]}}">{{sub_d[1]}}</a>
+                            {% if menu[0] == 1 %}
+                                {% for sub_d in menu %}
+                                    <div id="tool_cel">
+                                        {% if sub_d|length > 2 and sub_d[2] == 1 %}
+                                            <a class="menu-item" href="{{sub_d[0]}}" id="topic_color">{{sub_d[1]}}</a>
+                                        {% else %}
+                                            <a class="menu-item" href="{{sub_d[0]}}">{{sub_d[1]}}</a>
+                                        {% endif %}
+                                    </div>
+                                    {% if menu[loop.index] %}
+                                        |
                                     {% endif %}
-                                </div>
-                                {% if menu[loop.index] %}
-                                    |
-                                {% endif %}
-                            {% endfor %}
+                                {% endfor %}
+                            {% else %}
+                                {% for sub_d in menu %}
+                                    <div id="tool_cel">
+                                        {% if sub_d|length > 2 and sub_d[2] == 1 %}
+                                            <a class="menu-item" href="/{{sub_d[0]}}" id="topic_color">{{sub_d[1]}}</a>
+                                        {% else %}
+                                            <a class="menu-item" href="/{{sub_d[0]}}">{{sub_d[1]}}</a>
+                                        {% endif %}
+                                    </div>
+                                    {% if menu[loop.index] %}
+                                        |
+                                    {% endif %}
+                                {% endfor %}
+                            {% endif %}
                         </div>
                     {% endif %}
                     <h1 id="title">