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

Merge pull request #1966 from openNAMU/dev

중간 병합
잉여개발기 2 лет назад
Родитель
Сommit
619248cfeb

+ 8 - 7
app.py

@@ -524,7 +524,7 @@ app.route('/vote/list/close/<int:num>', defaults = { 'list_type' : 'close' })(vo
 app.route('/vote/add', methods = ['POST', 'GET'])(vote_add)
 
 # Func-bbs
-app.route('/bbs/main')(bbs_main)
+app.route('/bbs/main', defaults = { 'tool' : 'main' })(bbs_w)
 app.route('/bbs/make', methods = ['POST', 'GET'])(bbs_make)
 # app.route('/bbs/main/set')
 app.route('/bbs/w/<int:bbs_num>')(bbs_w)
@@ -539,14 +539,15 @@ app.route('/bbs/raw/<int:bbs_num>/<int:post_num>/<comment_num>')(view_raw_2)
 app.route('/bbs/edit/<int:bbs_num>/<int:post_num>/<comment_num>', methods = ['POST', 'GET'])(bbs_w_edit)
 
 # Func-api
-app.route('/api/w/<everything:name>/doc_tool/<tool>/doc_rev/<int(signed = True):rev>')(api_w)
-app.route('/api/w/<everything:name>/doc_tool/<tool>', methods = ['POST', 'GET'])(api_w)
+# 폐지 예정
+app.route('/api/w_rev/<int(signed = True):rev>/<tool>/<everything:name>', methods = ['GET', 'POST'])(api_w)
+app.route('/api/w_tool/<tool>/<everything:name>', methods = ['GET', 'POST'])(api_w)
 app.route('/api/w/<everything:name>', methods = ['GET', 'POST'])(api_w)
 
-app.route('/api/render_tool/<tool>/<everything:name>', methods = ['POST'])(api_w_render)
-app.route('/api/render_tool/<tool>', methods = ['POST'])(api_w_render)
-app.route('/api/render/<everything:name>', methods = ['POST'])(api_w_render)
-app.route('/api/render', methods = ['POST'])(api_w_render)
+# app.route('/api/render_tool/<tool>/<everything:name>', methods = ['POST'])(api_w_render)
+# app.route('/api/render_tool/<tool>', methods = ['POST'])(api_w_render)
+# app.route('/api/render/<everything:name>', methods = ['POST'])(api_w_render)
+# app.route('/api/render', methods = ['POST'])(api_w_render)
 
 app.route('/api/raw_exist/<everything:name>', defaults = { 'exist_check' : 'on' })(api_w_raw)
 app.route('/api/raw_rev/<int(signed = True):rev>/<everything:name>')(api_w_raw)

+ 1 - 0
requirements-optional.txt

@@ -0,0 +1 @@
+mysqlclient

+ 1 - 5
requirements.txt

@@ -4,10 +4,6 @@ flask
 waitress
 
 requests
-
-pymysql
-whoosh
-
 diff-match-patch
 
-pysha3; python_version < "3.6"
+pymysql

+ 0 - 1
route/__init__.py

@@ -18,7 +18,6 @@ from route.api_bbs_w_comment import api_bbs_w_comment
 from route.api_bbs_w_comment_one import api_bbs_w_comment_one
 
 from route.bbs_w_edit import bbs_w_edit
-from route.bbs_main import bbs_main
 from route.bbs_make import bbs_make
 from route.bbs_w import bbs_w
 from route.bbs_w_post import bbs_w_post

+ 0 - 42
route/bbs_main.py

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

+ 73 - 42
route/bbs_w.py

@@ -1,18 +1,51 @@
 from .tool.func import *
 
-def bbs_w(bbs_num = ''):
+def bbs_w(bbs_num = '', tool = 'bbs'):
     with get_db_connect() as conn:
         curs = conn.cursor()
+        
+        data = ''
+        title_name = ''
 
-        curs.execute(db_change('select set_data from bbs_set where set_id = ? and set_name = "bbs_name"'), [bbs_num])
-        db_data = curs.fetchall()
-        if not db_data:
-            return redirect('/bbs/main')
+        if tool == 'bbs':
+            curs.execute(db_change('select set_data from bbs_set where set_id = ? and set_name = "bbs_name"'), [bbs_num])
+            db_data = curs.fetchall()
+            if not db_data:
+                return redirect('/bbs/main')
         
-        bbs_name = db_data[0][0]
-        bbs_num_str = str(bbs_num)
+            bbs_name = db_data[0][0]
+            bbs_num_str = str(bbs_num)
+
+            title_name = bbs_name
+            menu = [['bbs/main', load_lang('return')], ['bbs/edit/' + bbs_num_str, load_lang('add')], ['bbs/set/' + bbs_num_str, load_lang('bbs_set')]]
+        else:
+            curs.execute(db_change('select set_data, set_id from bbs_set where set_name = "bbs_name"'))
+            db_data = curs.fetchall()
+            if db_data:
+                data += '<ul class="opennamu_ul">'
+                for for_a in db_data:
+                    curs.execute(db_change('select set_data from bbs_set where set_name = "bbs_type" and set_id = ?'), [for_a[1]])
+                    db_data_2 = curs.fetchall()
+                    bbs_type = db_data_2[0][0] if db_data_2 else 'comment'
+
+                    if bbs_type == 'thread':
+                        bbs_type = load_lang('thread_base')
+                    else:
+                        bbs_type = load_lang('comment_base')
+                    
+                    curs.execute(db_change('select set_data from bbs_data where set_id = ? and set_name = "date" order by set_code + 0 desc limit 1'), [for_a[1]])
+                    db_data_2 = curs.fetchall()
+                    last_date = ('(' + db_data_2[0][0] + ')') if db_data_2 else ''
+
+                    data += '<li><a href="/bbs/w/' + for_a[1] + '">' + html.escape(for_a[0]) + ' (' + bbs_type + ') ' + last_date + '</a></li>'
+
+                data += '</ul>'
+            
+            data += '<hr class="main_hr">'
+
+            title_name = load_lang('bbs_main')
+            menu = [['other', load_lang('return')]] + ([['bbs/make', load_lang('add')]] if admin_check() == 1 else [])
 
-        data = ''
         data += '''
             <table id="main_table_set">
                 <tr id="main_table_top_tr">
@@ -21,48 +54,46 @@ def bbs_w(bbs_num = ''):
                     <td id="main_table_width">''' + load_lang('last_comment_time') + '''</td>
                 </tr>
         '''
-        
-        temp_id = ''
-        temp_dict = {}
 
-        curs.execute(db_change('select set_name, set_data, set_code, set_id from bbs_data where set_id like ? order by set_code + 0 desc'), [bbs_num])
+        if tool == 'bbs':
+            curs.execute(db_change('select set_code, set_id from bbs_data where set_name = "title" and set_id like ? order by set_code + 0 desc'), [bbs_num])
+        else:
+            curs.execute(db_change('select set_code, set_id, set_data from bbs_data where set_name = "date" order by set_data desc limit 50'))
+        
         db_data = curs.fetchall()
-        db_data = list(db_data) if db_data else []
-
-        for for_a in db_data + [['', '', '']]:
-            if temp_id != for_a[2]:
-                if temp_id != '':
-                    curs.execute(db_change('select count(*) from bbs_data where set_name = "comment_date" and (set_id = ? or set_id like ?) order by set_code + 0 desc'), [bbs_num_str + '-' + temp_dict['code'], bbs_num_str + '-' + temp_dict['code'] + '-%'])
-                    db_data = curs.fetchall()
-                    comment_count = str(db_data[0][0]) if db_data else '0'
+        for for_b in db_data:
+            curs.execute(db_change('select set_name, set_data, set_code, set_id from bbs_data where set_code = ? and set_id = ?'), [for_b[0], for_b[1]])
+            db_data = curs.fetchall()
+            db_data = list(db_data) if db_data else []
 
-                    curs.execute(db_change('select set_data from bbs_data where set_name = "comment_date" and (set_id = ? or set_id like ?) order by set_data desc limit 1'), [bbs_num_str + '-' + temp_dict['code'], bbs_num_str + '-' + temp_dict['code'] + '-%'])
-                    db_data = curs.fetchall()
-                    last_comment_date = db_data[0][0] if db_data else '0'
+            temp_dict = { for_a[0] : for_a[1] for for_a in db_data }
 
-                    data += '''
-                        <tr>
-                            <td>''' + ip_pas(temp_dict['user_id']) + '''</td>
-                            <td>''' + temp_dict['date'] + '''</td>
-                            <td>''' + last_comment_date + '''</td>
-                        </tr>
-                        <tr>
-                            <td colspan="3">
-                                <a href="/bbs/w/''' + bbs_num_str + '/' + temp_dict['code'] + '">' + html.escape(temp_dict['title']) + '''</a> 
-                                (''' + comment_count + ''') 
-                            </td>
-                        </tr>
-                    '''
+            curs.execute(db_change('select count(*) from bbs_data where set_name = "comment_date" and (set_id = ? or set_id like ?) order by set_code + 0 desc'), [for_b[1] + '-' + for_b[0], for_b[1] + '-' + for_b[0] + '-%'])
+            db_data = curs.fetchall()
+            comment_count = str(db_data[0][0]) if db_data else '0'
 
-                temp_id = for_a[2]
-                temp_dict['code'] = for_a[2]
-
-            temp_dict[for_a[0]] = for_a[1]
+            curs.execute(db_change('select set_data from bbs_data where set_name = "comment_date" and (set_id = ? or set_id like ?) order by set_data desc limit 1'), [for_b[1] + '-' + for_b[0], for_b[1] + '-' + for_b[0] + '-%'])
+            db_data = curs.fetchall()
+            last_comment_date = db_data[0][0] if db_data else '0'
 
+            data += '''
+                <tr>
+                    <td>''' + ip_pas(temp_dict['user_id']) + '''</td>
+                    <td>''' + temp_dict['date'] + '''</td>
+                    <td>''' + last_comment_date + '''</td>
+                </tr>
+                <tr>
+                    <td colspan="3">
+                        <a href="/bbs/w/''' + for_b[1] + '/' + for_b[0] + '">' + html.escape(temp_dict['title']) + '''</a> 
+                        (''' + comment_count + ''') 
+                    </td>
+                </tr>
+            '''
+                
         data += '</table>'
 
         return easy_minify(flask.render_template(skin_check(),
-            imp = [bbs_name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('bbs') + ')', 0])],
+            imp = [title_name, wiki_set(), wiki_custom(), wiki_css(['(' + load_lang('bbs') + ')', 0])],
             data = data,
-            menu = [['bbs/main', load_lang('return')], ['bbs/edit/' + bbs_num_str, load_lang('add')], ['bbs/set/' + bbs_num_str, load_lang('bbs_set')]]
+            menu = menu
         ))

+ 1 - 0
route/edit.py

@@ -324,6 +324,7 @@ def edit(name = 'Test', section = 0, do_type = ''):
                         <textarea style="display: none;" name="doc_section_data_where">''' + data_section_where + '''</textarea>
                         <input style="display: none;" name="doc_section_edit_apply" value="''' + doc_section_edit_apply + '''">
 
+                        <input style="display: none;" id="opennamu_editor_doc_name" value="''' + html.escape(name) + '''">
                         <input style="display: none;" name="ver" value="''' + doc_ver + '''">
                         
                         <input placeholder="''' + load_lang('why') + '''" name="send">

+ 1 - 1
route/main_func_error_404.py

@@ -11,4 +11,4 @@ def main_func_error_404(e = ''):
             db_data = curs.fetchall()
             db_data = db_data[0][0] if db_data and db_data[0][0] != '' else 'FrontPage'
             
-            return redirect('/w/' + db_data)
+            return '<script>window.location.href = "/w/' + url_pas(db_data) + '";</script>'

+ 8 - 6
route/tool/func.py

@@ -85,7 +85,12 @@ import flask
 
 import requests
 
-import pymysql
+try:
+    import mysqlclient as pymysql
+except:
+    import pymysql
+
+import sqlite3
 
 if sys.version_info < (3, 6):
     import sha3
@@ -2111,11 +2116,11 @@ def ip_pas(raw_ip, type_data = 0):
         curs = conn.cursor()
 
         end_ip = {}
+        my_ip = ip_check()
 
         return_data = 0
         if type(raw_ip) != type([]):
             get_ip = [raw_ip]
-            
             return_data = 1
         else:
             get_ip = raw_ip
@@ -2139,7 +2144,7 @@ def ip_pas(raw_ip, type_data = 0):
             is_this_ip = ip_or_user(raw_ip)
             if is_this_ip != 0:
                 # ip user
-                if ip_view != '':
+                if ip_view != '' and my_ip != raw_ip:
                     try:
                         ip = ipaddress.ip_address(raw_ip)
                         if type(ip) == ipaddress.IPv6Address:
@@ -2148,9 +2153,6 @@ def ip_pas(raw_ip, type_data = 0):
                         else:
                             ip = ip.exploded
                             ip = re.sub(r'\.([^.]*)\.([^.]*)$', '.*.*', ip)
-                        
-                        # ip = hashlib.sha3_224(bytes(raw_ip, 'utf-8')).hexdigest()
-                        # ip = ip[0:4] + '-' + ip[4:8] + '-' + ip[8:12] + '-' + ip[12:16]
 
                         change_ip = 1
                     except:

+ 66 - 47
route/tool/func_render_namumark.py

@@ -34,7 +34,7 @@ class class_do_render_namumark:
         self.data_temp_storage = {}
         self.data_temp_storage_count = 0
 
-        self.data_backlink = []
+        self.data_backlink = {}
         self.data_include = []
 
         self.data_math_count = 0
@@ -149,8 +149,8 @@ class class_do_render_namumark:
 
             storage_count -= 1
 
-        data = re.sub(r'<front_br>', '', data)
-        data = re.sub(r'<back_br>', '', data)
+        data = data.replace('<front_br>', '')
+        data = data.replace('<back_br>', '')
 
         return data
 
@@ -239,6 +239,7 @@ class class_do_render_namumark:
         self.render_data_js += data_end[1]
         self.data_include += data_end[2]['include']
         self.data_category_list += data_end[2]['category']
+        self.data_backlink = dict(self.data_backlink, **data_end[2]['backlink_dict'])
         self.data_temp_storage = dict(self.data_temp_storage, **data_end[2]['temp_storage'][0])
         self.data_temp_storage_count += data_end[2]['temp_storage'][1]
 
@@ -771,14 +772,14 @@ class class_do_render_namumark:
         self.render_data = re.sub(r'\[([^[\]]+)\]', do_render_macro_single, self.render_data)
 
         # macro safe restore
-        self.render_data = re.sub(r'<macro>', '[', self.render_data)
-        self.render_data = re.sub(r'<\/macro>', ']', self.render_data)
+        self.render_data = self.render_data.replace('<macro>', '[')
+        self.render_data = self.render_data.replace('</macro>', ']')
 
     def do_render_math(self):
         def do_render_math_sub(match):
             data = match.group(1)
 
-            data = re.sub(r'\n', '', data)
+            data = data.replace('\n', '')
             data = self.get_tool_data_revert(data)
 
             data_html = self.get_tool_js_safe(data)
@@ -879,7 +880,7 @@ class class_do_render_namumark:
 
                         link_main = self.get_tool_data_restore(link_main, do_type = 'slash')
                         link_main = html.unescape(link_main)
-                        link_main = re.sub(r'"', '&quot;', link_main)
+                        link_main = link_main.replace('"', '&quot;')
                         
                         link_exist = ''
                         file_out = 1
@@ -889,15 +890,18 @@ class class_do_render_namumark:
                         link_main = self.get_tool_data_restore(link_main, do_type = 'slash')
                         link_main = html.unescape(link_main)
 
+                        if not ('file:' + link_main) in self.data_backlink:
+                            self.data_backlink['file:' + link_main] = {}
+
                         self.curs.execute(db_change("select title from data where title = ?"), ['file:' + link_main])
                         db_data = self.curs.fetchall()
                         if db_data:
                             link_exist = ''
                         else:
                             link_exist = 'opennamu_not_exist_link'
-                            self.data_backlink += [[self.doc_name, 'file:' + link_main, 'no', '']]
+                            self.data_backlink['file:' + link_main]['no'] = ''
 
-                        self.data_backlink += [[self.doc_name, 'file:' + link_main, 'file', '']]
+                        self.data_backlink['file:' + link_main]['file'] = ''
 
                         link_extension_regex = r'\.([^.]+)$'
                         link_extension = re.search(link_extension_regex, link_main)
@@ -997,21 +1001,24 @@ class class_do_render_namumark:
                     if not link_main in self.data_category_list:
                         self.data_category_list += [link_main]
                         
+                        if not ('category:' + link_main) in self.data_backlink:
+                            self.data_backlink['category:' + link_main] = {}
+
                         self.curs.execute(db_change("select title from data where title = ?"), ['category:' + link_main])
                         db_data = self.curs.fetchall()
                         if db_data:
                             link_exist = ''
                         else:
                             link_exist = 'opennamu_not_exist_link'
-                            self.data_backlink += [[self.doc_name, 'category:' + link_main, 'no', '']]
+                            self.data_backlink['category:' + link_main]['no'] = ''
 
-                        self.data_backlink += [[self.doc_name, 'category:' + link_main, 'cat', '']]
+                        self.data_backlink['category:' + link_main]['cat'] = ''
                         
                         if link_view != '':
-                            self.data_backlink += [[self.doc_name, 'category:' + link_main, 'cat_view', link_view]]
+                            self.data_backlink['category:' + link_main]['cat_view'] = link_view
                         
                         if category_blur != '':
-                            self.data_backlink += [[self.doc_name, 'category:' + link_main, 'cat_blur', '']]
+                            self.data_backlink['category:' + link_main]['cat_blur'] = ''
 
                         link_main = url_pas(link_main)
 
@@ -1088,9 +1095,9 @@ class class_do_render_namumark:
                     link_title = link_main
                     link_main = html.unescape(link_main)
 
-                    link_main = re.sub(r'"', '&quot;', link_main)
-                    link_main = re.sub(r'<', '&lt;', link_main)
-                    link_main = re.sub(r'>', '&gt;', link_main)
+                    link_main = link_main.replace('"', '&quot;')
+                    link_main = link_main.replace('<', '&lt;')
+                    link_main = link_main.replace('>', '&gt;')
 
                     # sub not exist -> sub = main
                     if link_data[1]:
@@ -1135,12 +1142,17 @@ class class_do_render_namumark:
                         self.curs.execute(db_change("select title from data where title = ?" + self.link_case_insensitive), [link_main])
                         db_data = self.curs.fetchall()
                         if not db_data:
-                            self.data_backlink += [[self.doc_name, link_main, 'no', '']]
+                            if not link_main in self.data_backlink:
+                                self.data_backlink[link_main] = {}
+
+                            self.data_backlink[link_main]['no'] = ''
                             link_exist = 'opennamu_not_exist_link'
                         else:
                             link_main = db_data[0][0]
+                            if not link_main in self.data_backlink:
+                                self.data_backlink[link_main] = {}
                         
-                        self.data_backlink += [[self.doc_name, link_main, '', '']]
+                        self.data_backlink[link_main][''] = ''
 
                     link_same = ''
                     if link_main == self.doc_name:
@@ -1272,7 +1284,10 @@ class class_do_render_namumark:
                     include_name = self.get_tool_data_restore(include_name, do_type = 'slash')
                     include_name = html.unescape(include_name)
 
-                    self.data_backlink += [[self.doc_name, include_name, 'include', '']]
+                    if not include_name in self.data_backlink:
+                        self.data_backlink[include_name] = {}
+
+                    self.data_backlink[include_name]['include'] = ''
 
                     # load include db data
                     self.curs.execute(db_change("select data from data where title = ?"), [include_name])
@@ -1299,7 +1314,7 @@ class class_do_render_namumark:
                             '<div id="' + self.doc_include + 'opennamu_include_' + str(include_num) + '"></div>' + \
                         '', '', match_org)
                     else:
-                        self.data_backlink += [[self.doc_name, include_name, 'no', '']]
+                        self.data_backlink[include_name]['no'] = ''
 
                         include_link = '<div><a class="opennamu_not_exist_link" href="/w/' + url_pas(include_name) + '">(' + include_name_org + ')</a></div>'
 
@@ -1443,9 +1458,7 @@ class class_do_render_namumark:
                 # under page & fix url
                 link_main = self.get_tool_link_fix(link_main, 'redirect')
             else:
-                link_inter_name = re.search(link_inter_regex, link_main)
-                link_inter_name = link_inter_name.group(1)
-
+                link_inter_name = inter_check.group(1)
                 link_main = re.sub(link_inter_regex, '', link_main)
 
             # sharp
@@ -1473,12 +1486,17 @@ class class_do_render_namumark:
                 self.curs.execute(db_change("select title from data where title = ?" + self.link_case_insensitive), [link_main])
                 db_data = self.curs.fetchall()
                 if not db_data:
-                    self.data_backlink += [[self.doc_name, link_main, 'no', '']]
+                    if not link_main in self.data_backlink:
+                        self.data_backlink[link_main] = {}
+
+                    self.data_backlink[link_main]['no'] = ''
                     link_exist = 0
                 else:
                     link_main = db_data[0][0]
+                    if not link_main in self.data_backlink:
+                        self.data_backlink[link_main] = {}
 
-                self.data_backlink += [[self.doc_name, link_main, 'redirect', '']]
+                self.data_backlink[link_main]['redirect'] = ''
 
                 link_main = url_pas(link_main)
                 if link_main != '':
@@ -1782,7 +1800,7 @@ class class_do_render_namumark:
                         data_revert = self.get_tool_data_revert(html_data)
                         data_revert = re.sub(r'^\n', '', data_revert)
                         data_revert = re.sub(r'\n$', '', data_revert)
-                        data_revert = re.sub(r'&amp;nbsp;', '&nbsp;', data_revert)
+                        data_revert = data_revert.replace('&amp;nbsp;', '&nbsp;')
 
                         self.render_data_js += 'opennamu_do_render_html("' + self.doc_include + 'opennamu_wiki_' + str(html_count) + '");\n'
 
@@ -2220,8 +2238,8 @@ class class_do_render_namumark:
         self.render_data = re.sub(r'\n##[^\n]+', '\n<front_br>', self.render_data)
 
     def do_render_last(self):
-        self.render_data = re.sub(r'<no_br>', '\n', self.render_data)
-        self.render_data = re.sub(r'<no_td>', '||', self.render_data)
+        self.render_data = self.render_data.replace('<no_br>', '\n')
+        self.render_data = self.render_data.replace('<no_td>', '||')
 
         # add category
         if self.doc_include == '':
@@ -2231,23 +2249,23 @@ class class_do_render_namumark:
                 category_set_data = get_main_skin_set(self.curs, self.flask_session, 'main_css_category_set', self.ip)
                 if category_set_data == 'bottom':
                     if re.search(r'<footnote_category>', self.render_data):
-                        self.render_data = re.sub(r'<footnote_category>', '<hr><' + data_name + '></' + data_name + '>', self.render_data, 1)
+                        self.render_data = self.render_data.replace('<footnote_category>', '<hr><' + data_name + '></' + data_name + '>', 1)
                     else:
                         self.render_data += '<hr><' + data_name + '></' + data_name + '>'
                 else:
-                    self.render_data = re.sub(r'<footnote_category>', '', self.render_data, 1)
+                    self.render_data = self.render_data.replace('<footnote_category>', '', 1)
                     self.render_data = '<' + data_name + '></' + data_name + '><hr class="main_hr">' + self.render_data
             else:
-                self.render_data = re.sub(r'<footnote_category>', '', self.render_data, 1)
+                self.render_data = self.render_data.replace(r'<footnote_category>', '', 1)
         else:
-            self.render_data = re.sub(r'<footnote_category>', '', self.render_data, 1)
+            self.render_data = self.render_data.replace(r'<footnote_category>', '', 1)
 
         # remove front_br and back_br
         self.render_data = re.sub(r'\n?<front_br>', '', self.render_data)
         self.render_data = re.sub(r'<back_br>\n?', '', self.render_data)
         
         # \n to <br>
-        self.render_data = re.sub(r'\n', '<br>', self.render_data)
+        self.render_data = self.render_data.replace('\n', '<br>')
 
         # <render_n> restore
         self.render_data = self.get_tool_data_restore(self.render_data)
@@ -2300,7 +2318,8 @@ class class_do_render_namumark:
             toc_data_on = 0
 
             toc_data = re.search(toc_search_regex, self.render_data)
-            toc_data = toc_data.group(1)
+            toc_data = toc_data.group(1) if toc_data else ''
+
             self.data_toc = toc_data
             self.data_toc = re.sub(r'<toc_inside>((?:(?!<toc_inside>|<\/toc_inside>).)*)<\/toc_inside>', do_render_last_toc, self.data_toc)
 
@@ -2308,25 +2327,21 @@ class class_do_render_namumark:
 
             self.render_data = re.sub(toc_search_regex, '', self.render_data)
             if toc_set_data == 'off':
-                self.render_data = re.sub(r'<toc_need_part>', '', self.render_data)
+                self.render_data = self.render_data.replace('<toc_need_part>', '')
             else:
                 if re.search(r'<toc_need_part>', self.render_data):
                     toc_data_on = 1
 
-                self.render_data = re.sub(r'<toc_need_part>', lambda x : (self.data_toc), self.render_data, 20)
-                self.render_data = re.sub(r'<toc_need_part>', '', self.render_data)
+                self.render_data = self.render_data.replace('<toc_need_part>', self.data_toc, 20)
+                self.render_data = self.render_data.replace('<toc_need_part>', '')
 
-            if  self.doc_include != '' or \
-                re.search(r'<toc_no_auto>', self.render_data) or \
-                toc_set_data == 'half_off' or \
-                toc_set_data == 'off' or \
-                toc_data_on == 1:
-                self.render_data = re.sub(r'<toc_no_auto>', '', self.render_data)
+            if self.doc_include != '' or re.search(r'<toc_no_auto>', self.render_data) or toc_set_data == 'half_off' or toc_set_data == 'off' or toc_data_on == 1:
+                self.render_data = self.render_data.replace('<toc_no_auto>', '')
             else:
                 self.render_data = re.sub(r'(?P<in><h[1-6] id="[^"]*">)', '<br>' + self.data_toc + '\\g<in>', self.render_data, 1)
         else:
-            self.render_data = re.sub(r'<toc_need_part>', '', self.render_data)
-            self.render_data = re.sub(r'<toc_no_auto>', '', self.render_data)
+            self.render_data = self.render_data.replace('<toc_need_part>', '')
+            self.render_data = self.render_data.replace('<toc_no_auto>', '')
 
         def do_render_last_footnote(match):
             match = match.group(1)
@@ -2370,14 +2385,18 @@ class class_do_render_namumark:
             self.do_render_last()
             self.data_include = list(reversed(self.data_include))
         else:
-            self.render_data = re.sub(r'\|\|', '<no_td>', self.render_data)
-            self.render_data = re.sub(r'\n', '<no_br>', self.render_data)
+            self.render_data = self.render_data.replace(r'\|\|', '<no_td>')
+            self.render_data = self.render_data.replace('\n', '<no_br>')
+
+        data_backlink_dict = self.data_backlink
+        self.data_backlink = [[self.doc_name, for_a, for_b, self.data_backlink[for_a][for_b]] for for_a in self.data_backlink for for_b in self.data_backlink[for_a]]
 
         return [
             self.render_data, # html
             self.render_data_js, # js
             {
                 'backlink' : self.data_backlink, # backlink
+                'backlink_dict' : data_backlink_dict,
                 'include' : self.data_include, # include data
                 'footnote' : self.data_footnote_all, # footnote
                 'category' : self.data_category_list,

+ 0 - 1
route/tool/func_tool.py

@@ -8,7 +8,6 @@ import re
 import os
 import html
 import json
-import sqlite3
 import threading
 
 set_data = ''

+ 24 - 9
route/view_read.py

@@ -219,19 +219,34 @@ def view_read(name = 'Test', doc_rev = '', doc_from = '', do_type = ''):
                 ['acl/' + url_pas(name), load_lang('setting'), acl],
             ]
 
+            if flask.session and 'lastest_document' in flask.session:
+                if type(flask.session['lastest_document']) != type([]):
+                    flask.session['lastest_document'] = []
+            else:
+                flask.session['lastest_document'] = []
+
             if do_type == 'from':
                 menu += [['w/' + url_pas(name), load_lang('pass')]]
-                if flask.session and 'lastest_document' in flask.session:
-                    end_data = '''
-                        <div id="redirect">
-                            <a href="/w_from/''' + url_pas(flask.session['lastest_document']) + '''">''' + flask.session['lastest_document'] + '''</a> ➤ <b>''' + name + '''</b>
-                        </div>
-                        <hr class="main_hr">
-                    ''' + end_data
+                
+                last_page = ''
+                for for_a in reversed(range(0, len(flask.session['lastest_document']))):
+                    last_page = flask.session['lastest_document'][for_a]
+
+                    curs.execute(db_change("select link from back where (title = ? or link = ?) and type = 'redirect' limit 1"), [last_page, last_page])
+                    if curs.fetchall():
+                        break
+
+                end_data = '''
+                    <div id="redirect">
+                        <a href="/w_from/''' + url_pas(last_page) + '''">''' + html.escape(last_page) + '''</a> ➤ <b>''' + html.escape(name) + '''</b>
+                    </div>
+                    <hr class="main_hr">
+                ''' + end_data
                     
-                flask.session['lastest_document'] = name
+            if len(flask.session['lastest_document']) >= 10:
+                flask.session['lastest_document'] = flask.session['lastest_document'][-9:] + [name]
             else:
-                flask.session['lastest_document'] = name
+                flask.session['lastest_document'] += [name]
 
             if uppage != 0:
                 menu += [['w/' + url_pas(uppage), load_lang('upper')]]

+ 1 - 1
version.json

@@ -1,6 +1,6 @@
 {
     "beta" : {
-        "r_ver" : "v3.4.6-RC5-dev19",
+        "r_ver" : "v3.4.6-RC5-dev24",
         "c_ver" : "3500373",
         "s_ver" : "3500112"
     }

+ 6 - 1
views/main_css/js/route/editor_sub.js

@@ -1,7 +1,12 @@
 function opennamu_do_editor_preview() {
     var input = document.querySelector('#opennamu_edit_textarea');
     if (input !== null) {
-        fetch("/api/w/test/doc_tool/preview", {
+        var doc_name = 'test';
+        var doc_name_input = document.querySelector('#opennamu_editor_doc_name');
+        if (doc_name_input !== null) {
+            doc_name = doc_name_input.value;
+        }
+        fetch("/api/w_tool/preview/" + opennamu_do_url_encode(doc_name), {
             method: 'POST',
             headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
             body: new URLSearchParams({

+ 8 - 1
views/main_css/js/route/editor_sub.ts

@@ -1,7 +1,14 @@
 function opennamu_do_editor_preview() {
     const input = document.querySelector('#opennamu_edit_textarea') as HTMLInputElement | null;
     if(input !== null) {
-        fetch("/api/w/test/doc_tool/preview", {
+        let doc_name : string = 'test';
+
+        const doc_name_input = document.querySelector('#opennamu_editor_doc_name') as HTMLInputElement | null;
+        if(doc_name_input !== null) {
+            doc_name = doc_name_input.value;
+        }
+
+        fetch("/api/w_tool/preview/" + (opennamu_do_url_encode(doc_name) as (arg1 : string) => string), {
             method : 'POST',
             headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
             body : new URLSearchParams({