Ver código fonte

Merge pull request #418 from 2DU/master

Master
Surplus_Up (2DU) 8 anos atrás
pai
commit
5a0fa301ce
6 arquivos alterados com 191 adições e 105 exclusões
  1. 8 6
      .gitignore
  2. 111 84
      app.py
  3. 9 2
      func.py
  4. 57 6
      set_mark/start.py
  5. 5 0
      version.md
  6. 1 7
      views/acme/index.html

+ 8 - 6
.gitignore

@@ -1,15 +1,17 @@
 set.json
 set.json
+
+set_mark/__pycache__
 /__pycache__
 /__pycache__
 /app_session
 /app_session
+.vscode
+
 opennamu.db
 opennamu.db
 back_opennamu.db
 back_opennamu.db
+Test.db
 image
 image
-.vscode
-back_opennamu.db
-set_mark/__pycache__
-test.db
+robots.txt
+
 views/liberty
 views/liberty
 views/yousoro
 views/yousoro
-t_opennamu.db
 views/super_lite
 views/super_lite
-robots.txt
+views/buma

+ 111 - 84
app.py

@@ -17,7 +17,7 @@ import random
 import sys
 import sys
 
 
 # 버전 표기
 # 버전 표기
-r_ver = 'v3.0.0-Stable-Fix-02'
+r_ver = 'v3.0.1'
 print('Version : ' + r_ver)
 print('Version : ' + r_ver)
 
 
 # 나머지 불러오기
 # 나머지 불러오기
@@ -62,21 +62,17 @@ compress.init_app(app)
 def md5_replace(data):
 def md5_replace(data):
     return hashlib.md5(data.encode()).hexdigest()       
     return hashlib.md5(data.encode()).hexdigest()       
 
 
-def plus_data(first, second):
-    return first + second             
-
 app.jinja_env.filters['md5_replace'] = md5_replace
 app.jinja_env.filters['md5_replace'] = md5_replace
-app.jinja_env.filters['plus_data'] = plus_data
 
 
 # 셋업 부분
 # 셋업 부분
 curs.execute("create table if not exists data(title text, data text)")
 curs.execute("create table if not exists data(title text, data text)")
 curs.execute("create table if not exists history(id text, title text, data text, date text, ip text, send text, leng text, hide text)")
 curs.execute("create table if not exists history(id text, title text, data text, date text, ip text, send text, leng text, hide text)")
 curs.execute("create table if not exists rd(title text, sub text, date text)")
 curs.execute("create table if not exists rd(title text, sub text, date text)")
-curs.execute("create table if not exists user(id text, pw text, acl text, date text)")
-curs.execute("create table if not exists ban(block text, end text, why text, band text)")
+curs.execute("create table if not exists user(id text, pw text, acl text, date text, email text, skin text)")
+curs.execute("create table if not exists ban(block text, end text, why text, band text, login text)")
 curs.execute("create table if not exists topic(id text, title text, sub text, data text, date text, ip text, block text, top text)")
 curs.execute("create table if not exists topic(id text, title text, sub text, data text, date text, ip text, block text, top text)")
 curs.execute("create table if not exists stop(title text, sub text, close text)")
 curs.execute("create table if not exists stop(title text, sub text, close text)")
-curs.execute("create table if not exists rb(block text, end text, today text, blocker text, why text)")
+curs.execute("create table if not exists rb(block text, end text, today text, blocker text, why text, band text)")
 curs.execute("create table if not exists back(title text, link text, type text)")
 curs.execute("create table if not exists back(title text, link text, type text)")
 curs.execute("create table if not exists agreedis(title text, sub text)")
 curs.execute("create table if not exists agreedis(title text, sub text)")
 curs.execute("create table if not exists custom(user text, css text)")
 curs.execute("create table if not exists custom(user text, css text)")
@@ -116,6 +112,28 @@ else:
     
     
     print('Port : ' + str(rep_port))
     print('Port : ' + str(rep_port))
 
 
+# robots.txt 점검
+try:
+    if not os.path.exists('robots.txt'):
+        curs.execute("select data from other where name = 'robot'")
+        robot_test = curs.fetchall()
+        if robot_test:
+            fw_test = open('./robots.txt', 'w')
+            fw_test.write(re.sub('\r\n', '\n', robot_test[0][0]))
+            fw_test.close()
+
+        else:
+            fw_test = open('./robots.txt', 'w')
+            fw_test.write('User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/')
+            fw_test.close()
+
+            curs.execute("insert into other (name, data) values ('robot', 'User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/')")
+        
+        print('robots.txt create')
+
+except:
+    pass
+
 # 비밀 키 점검
 # 비밀 키 점검
 curs.execute("select data from other where name = 'key'")
 curs.execute("select data from other where name = 'key'")
 rep_data = curs.fetchall()
 rep_data = curs.fetchall()
@@ -198,24 +216,10 @@ try:
 except:
 except:
     pass
     pass
 
 
-try:
-    if not os.path.exists('robot.txt'):
-        curs.execute("select data from other where name = 'robot'")
-        robot_test = curs.fetchall()
-        if robot_test:
-            fw_test = open('./robots.txt', 'w')
-            fw_test.write(re.sub('\r\n', '\n', robot_test[0][0]))
-            fw_test.close()
-
-            print('robot.txt create')
-
-except:
-    pass
-
 try:
 try:
     curs.execute("alter table user add email text default ''")
     curs.execute("alter table user add email text default ''")
 
 
-    print('user table add email acl')
+    print('user table add column email')
 
 
 except:
 except:
     pass
     pass
@@ -230,6 +234,14 @@ try:
 
 
         print('filter data fix')
         print('filter data fix')
 
 
+except:
+    pass
+
+try:
+    curs.execute("alter table user add skin text default ''")
+
+    print('user table add column skin')
+
 except:
 except:
     pass
     pass
         
         
@@ -939,16 +951,18 @@ def indexing():
     print('')
     print('')
 
 
     curs.execute("select name from sqlite_master where type = 'index'")
     curs.execute("select name from sqlite_master where type = 'index'")
-    for delete_index in curs.fetchall():
-        print('Delete : ' + delete_index[0])
+    data = curs.fetchall()
+    if data:
+        for delete_index in data:
+            print('Delete : ' + delete_index[0])
 
 
-        sql = 'drop index if exists ' + delete_index[0]
-        
-        try:
-            curs.execute(sql)
+            sql = 'drop index if exists ' + delete_index[0]
+            
+            try:
+                curs.execute(sql)
 
 
-        except:
-            pass
+            except:
+                pass
     else:
     else:
         curs.execute("select name from sqlite_master where type in ('table', 'view') and name not like 'sqlite_%' union all select name from sqlite_temp_master where type in ('table', 'view') order by 1;")
         curs.execute("select name from sqlite_master where type in ('table', 'view') and name not like 'sqlite_%' union all select name from sqlite_temp_master where type in ('table', 'view') order by 1;")
         for table in curs.fetchall():            
         for table in curs.fetchall():            
@@ -1868,7 +1882,7 @@ def manager(num = 1):
     if num == 1:
     if num == 1:
         return html_minify(render_template(skin_check(conn), 
         return html_minify(render_template(skin_check(conn), 
             imp = ['관리자 메뉴', wiki_set(conn, 1), custom(conn), other2([0, 0])],
             imp = ['관리자 메뉴', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data = '<h2>목록</h2><ul><li><a href="/manager/2">문서 ACL</a></li><li><a href="/manager/3">사용자 검사</a></li><li><a href="/manager/4">사용자 차단</a></li><li><a href="/manager/5">권한 주기</a></li><li><a href="/big_delete">여러 문서 삭제</a></li><li><a href="/edit_filter">편집 필터</a></li></ul><br><h2>소유자</h2><ul><li><a href="/indexing">인덱싱 (생성 or 삭제)</a></li><li><a href="/manager/8">관리 그룹 생성</a></li><li><a href="/edit_set">설정 편집</a></li><li><a href="/re_start">서버 재 시작</a></li><li><a href="/update">업데이트 (Git 사용)</a></li><!-- <li><a href="/inter_wiki">인터위키</a></li> --></ul>',
+            data = '<h2>목록</h2><ul><li><a href="/manager/2">문서 ACL</a></li><li><a href="/manager/3">사용자 검사</a></li><li><a href="/manager/4">사용자 차단</a></li><li><a href="/manager/5">권한 주기</a></li><li><a href="/big_delete">여러 문서 삭제</a></li><li><a href="/edit_filter">편집 필터</a></li></ul><br><h2>소유자</h2><ul><li><a href="/indexing">인덱싱 (생성 or 삭제)</a></li><li><a href="/manager/8">관리 그룹 생성</a></li><li><a href="/edit_set">설정 편집</a></li><li><a href="/re_start">서버 재 시작</a></li><li><a href="/update">업데이트 (Git 사용)</a></li><li><a href="/inter_wiki">인터위키</a></li></ul>',
             menu = [['other', '기타']]
             menu = [['other', '기타']]
         ))
         ))
     elif num in range(2, 14):
     elif num in range(2, 14):
@@ -2413,37 +2427,76 @@ def change_password():
         return redirect('/login')
         return redirect('/login')
     
     
     if request.method == 'POST':    
     if request.method == 'POST':    
-        if request.form['pw2'] != request.form['pw3']:
-            return re_error(conn, '/error/20')
+        if request.form.get('pw', None):
+            if request.form['pw2'] != request.form['pw3']:
+                return re_error(conn, '/error/20')
 
 
-        curs.execute("select pw from user where id = ?", [session['DREAMER']])
-        user = curs.fetchall()
-        if not user:
-            return re_error(conn, '/error/10')
+            curs.execute("select pw from user where id = ?", [session['DREAMER']])
+            user = curs.fetchall()
+            if not user:
+                return re_error(conn, '/error/10')
 
 
-        if not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8')):
-            return re_error(conn, '/error/5')
+            if not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8')):
+                return re_error(conn, '/error/5')
 
 
-        hashed = bcrypt.hashpw(bytes(request.form['pw2'], 'utf-8'), bcrypt.gensalt())
+            hashed = bcrypt.hashpw(bytes(request.form['pw2'], 'utf-8'), bcrypt.gensalt())
+            
+            curs.execute("update user set pw = ? where id = ?", [hashed.decode(), session['DREAMER']])
         
         
-        curs.execute("update user set pw = ? where id = ?", [hashed.decode(), session['DREAMER']])
+        curs.execute("update user set email = ? where id = ?", [request.form.get('email', ''), ip_check()])
+        curs.execute("update user set skin = ? where id = ?", [request.form.get('skin', ''), ip_check()])
         conn.commit()
         conn.commit()
         
         
-        return redirect('/user')
+        return redirect('/change')
 
 
     else:        
     else:        
+        ip = ip_check()
+
+        curs.execute('select email from user where id = ?', [ip])
+        data = curs.fetchall()
+        if data:
+            email = data[0][0]
+
+        else:
+            email = ''
+
+        div2 = ''
+
+        curs.execute('select skin from user where id = ?', [ip])
+        data = curs.fetchall()
+
+        for skin_data in os.listdir(os.path.abspath('views')):
+            if not data:
+                curs.execute('select data from other where name = "skin"')
+                sql_data = curs.fetchall()
+                if sql_data and sql_data[0][0] == skin_data:
+                    div2 = '<option value="' + skin_data + '">' + skin_data + '</option>' + div2
+
+                else:
+                    div2 += '<option value="' + skin_data + '">' + skin_data + '</option>'
+            
+            elif data[0][0] == skin_data:
+                div2 = '<option value="' + skin_data + '">' + skin_data + '</option>' + div2
+                
+            else:
+                div2 += '<option value="' + skin_data + '">' + skin_data + '</option>'
+
         return html_minify(render_template(skin_check(conn),    
         return html_minify(render_template(skin_check(conn),    
-            imp = ['비밀번호 변경', wiki_set(conn, 1), custom(conn), other2([0, 0])],
+            imp = ['내 정보 수정', wiki_set(conn, 1), custom(conn), other2([0, 0])],
             data = '<form method="post"> \
             data = '<form method="post"> \
-                        <input placeholder="현재 비밀번호" name="pw" type="password"><hr> \
-                        <input placeholder="변경할 비밀번호" name="pw2" type="password"><hr> \
+                        <span>닉네임 : ' + ip + '</span><hr>\
+                        <input placeholder="현재 비밀번호" name="pw" type="password"><br><br> \
+                        <input placeholder="변경할 비밀번호" name="pw2" type="password"><br><br> \
                         <input placeholder="재 확인" name="pw3" type="password"><hr> \
                         <input placeholder="재 확인" name="pw3" type="password"><hr> \
+                        <input placeholder="이메일" name="email" type="text" value="' + email + '"><hr> \
+                        <span>스킨</span><br><br> \
+                        <select name="skin">' + div2 + '</select><hr> \
                         <button type="submit">변경</button><hr> \
                         <button type="submit">변경</button><hr> \
                         <span>주의 : 만약 HTTPS 연결이 아닌 경우 데이터가 유출될 가능성이 있습니다. 이에 대해 책임지지 않습니다.</span> \
                         <span>주의 : 만약 HTTPS 연결이 아닌 경우 데이터가 유출될 가능성이 있습니다. 이에 대해 책임지지 않습니다.</span> \
                     </form>',
                     </form>',
             menu = [['user', '사용자']]
             menu = [['user', '사용자']]
         ))
         ))
-                
+
 @app.route('/check/<name>')
 @app.route('/check/<name>')
 def user_check(name = None):
 def user_check(name = None):
     if admin_check(conn, 4, 'check (' + name + ')') != 1:
     if admin_check(conn, 4, 'check (' + name + ')') != 1:
@@ -2886,7 +2939,7 @@ def diff_data(name = None):
                 result = '내용이 같습니다.'
                 result = '내용이 같습니다.'
             else:            
             else:            
                 diff_data = difflib.SequenceMatcher(None, first_data, second_data)
                 diff_data = difflib.SequenceMatcher(None, first_data, second_data)
-                result = diff(diff_data)
+                result = re.sub('\r', '', diff(diff_data))
             
             
             return html_minify(render_template(skin_check(conn), 
             return html_minify(render_template(skin_check(conn), 
                 imp = [name, wiki_set(conn, 1), custom(conn), other2([' (비교)', 0])],
                 imp = [name, wiki_set(conn, 1), custom(conn), other2([' (비교)', 0])],
@@ -2918,7 +2971,6 @@ def read_view(name = None):
     sub = ''
     sub = ''
     acl = ''
     acl = ''
     div = ''
     div = ''
-    topic = 0
 
 
     num = request.args.get('num', None)
     num = request.args.get('num', None)
     if num:
     if num:
@@ -2928,7 +2980,7 @@ def read_view(name = None):
     for data in curs.fetchall():
     for data in curs.fetchall():
         curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
         curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
         if not curs.fetchall():
         if not curs.fetchall():
-            topic = 1
+            sub += ' (토론 O)'
 
 
             break
             break
                 
                 
@@ -2982,8 +3034,12 @@ def read_view(name = None):
 
 
             div += '</ul>'
             div += '</ul>'
             
             
+            if div == '<br><h2 id="cate_normal">분류</h2><ul></ul>':
+                div = ''
+            
             if u_div != '':
             if u_div != '':
-                div = '<br><h2 id="cate_under">하위 분류</h2><ul>' + u_div + '</ul>' + div
+                div += '<br><h2 id="cate_under">하위 분류</h2><ul>' + u_div + '</ul>'
+
 
 
     if num:
     if num:
         curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
         curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
@@ -3036,7 +3092,7 @@ def read_view(name = None):
         else:
         else:
             curs.execute("select block from ban where block = ?", [g[0]])
             curs.execute("select block from ban where block = ?", [g[0]])
             if curs.fetchall():
             if curs.fetchall():
-                sub = ' (차단)'
+                sub += ' (차단)'
 
 
             else:
             else:
                 acl = ''
                 acl = ''
@@ -3058,9 +3114,9 @@ def read_view(name = None):
     end_data = namumark(conn, name, else_data, 0)
     end_data = namumark(conn, name, else_data, 0)
 
 
     if data_none == 1:
     if data_none == 1:
-        menu = [['edit/' + url_pas(name), '생성'], ['topic/' + url_pas(name), topic], ['history/' + url_pas(name), '역사'], ['move/' + url_pas(name), '이동'], ['xref/' + url_pas(name), '역링크']]
+        menu = [['edit/' + url_pas(name), '생성'], ['topic/' + url_pas(name), '토론'], ['history/' + url_pas(name), '역사'], ['move/' + url_pas(name), '이동'], ['xref/' + url_pas(name), '역링크']]
     else:
     else:
-        menu = [['edit/' + url_pas(name), '수정'], ['topic/' + url_pas(name), topic], ['history/' + url_pas(name), '역사'], ['delete/' + url_pas(name), '삭제'], ['move/' + url_pas(name), '이동'], ['raw/' + url_pas(name), '원본'], ['xref/' + url_pas(name), '역링크']]
+        menu = [['edit/' + url_pas(name), '수정'], ['topic/' + url_pas(name), '토론'], ['history/' + url_pas(name), '역사'], ['delete/' + url_pas(name), '삭제'], ['move/' + url_pas(name), '이동'], ['raw/' + url_pas(name), '원본'], ['xref/' + url_pas(name), '역링크']]
         
         
     if admin_memu == 1:
     if admin_memu == 1:
         menu += [['acl/' + url_pas(name), 'ACL']]
         menu += [['acl/' + url_pas(name), 'ACL']]
@@ -3478,7 +3534,7 @@ def user_info():
     if custom(conn)[2] != 0:
     if custom(conn)[2] != 0:
         ip_user = '<a href="/w/사용자:' + ip + '">' + ip + '</a>'
         ip_user = '<a href="/w/사용자:' + ip + '">' + ip + '</a>'
         
         
-        plus = '<li><a href="/logout">로그아웃</a></li><li><a href="/change">비밀번호 변경</a></li><li><a href="/email">이메일 수정</a></li>'
+        plus = '<li><a href="/logout">로그아웃</a></li><li><a href="/change">내 정보 변경</a></li>'
 
 
     else:
     else:
         ip_user = ip
         ip_user = ip
@@ -3491,35 +3547,6 @@ def user_info():
         menu = 0
         menu = 0
     ))
     ))
 
 
-@app.route('/email', methods=['GET', 'POST'])
-def email():
-    if custom(conn)[2] == 0:
-        return re_error(conn, '/error/1')
-
-    if request.method == 'POST':
-        curs.execute("update user set email = ? where id = ?", [request.form.get('email', ''), ip_check()])
-        conn.commit()
-
-        return redirect('/user')
-
-    else:
-        curs.execute('select email from user where id = ?', [ip_check()])
-        data = curs.fetchall()
-        if data:
-            email = data[0][0]
-
-        else:
-            email = ''
-
-        return html_minify(render_template(skin_check(conn),    
-            imp = ['이메일 수정', wiki_set(conn, 1), custom(conn), other2([0, 0])],
-            data = '<form method="post"> \
-                        <input placeholder="이메일" name="email" type="text" value="' + email + '"><hr> \
-                        <button type="submit">변경</button><hr> \
-                    </form>',
-            menu = [['user', '사용자']]
-        ))
-
 @app.route('/watch_list')
 @app.route('/watch_list')
 def watch_list():
 def watch_list():
     div = '한도 : 10개<hr>'
     div = '한도 : 10개<hr>'

+ 9 - 2
func.py

@@ -89,11 +89,18 @@ def skin_check(conn):
     skin = './views/acme/'
     skin = './views/acme/'
     
     
     try:
     try:
-        curs.execute('select data from other where name = "skin"')
+        curs.execute('select skin from user where id = ?', [ip_check()])
         skin_exist = curs.fetchall()
         skin_exist = curs.fetchall()
-        if skin_exist:
+        if skin_exist and skin_exist[0][0] != '':
             if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1:
             if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1:
                 skin = './views/' + skin_exist[0][0] + '/'
                 skin = './views/' + skin_exist[0][0] + '/'
+        
+        else:
+            curs.execute('select data from other where name = "skin"')
+            skin_exist = curs.fetchall()
+            if skin_exist:
+                if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1:
+                    skin = './views/' + skin_exist[0][0] + '/'
 
 
     except:
     except:
         pass
         pass

+ 57 - 6
set_mark/start.py

@@ -667,6 +667,32 @@ def start(conn, data, title):
         else:
         else:
             break
             break
 
 
+    # 하위 문서
+    while 1:
+        under_link = re.search('\[\[\.\.\/(?:\|((?:(?!]]).)+))?]]', data)
+        if under_link:
+            under_link = under_link.groups()
+
+            title_data = re.search('^(.+)\/(?:(?:(?!\/).)+)$', title)
+            if title_data:
+                title_data = title_data.groups()[0]
+
+                if under_link[0]:
+                    data = re.sub('\[\[\.\.\/(?:\|((?:(?!]]).)+))?]]', '[[' + title_data + '|' + under_link[0] + ']]', data, 1)
+
+                else:
+                    data = re.sub('\[\[\.\.\/(?:\|((?:(?!]]).)+))?]]', '[[' + title_data + ']]', data, 1)
+
+            else:
+                if under_link[0]:
+                    data = re.sub('\[\[\.\.\/(?:\|((?:(?!]]).)+))?]]', '[[' + title + '|' + under_link[0] + ']]', data, 1)
+
+                else:
+                    data = re.sub('\[\[\.\.\/(?:\|((?:(?!]]).)+))?]]', '[[' + title + ']]', data, 1)
+
+        else:
+            break
+
     # 링크 관련 문법 구현
     # 링크 관련 문법 구현
     category = '\n<hr><div id="cate">분류: '
     category = '\n<hr><div id="cate">분류: '
     while 1:
     while 1:
@@ -762,6 +788,32 @@ def start(conn, data, title):
             elif re.search('^wiki:', main_link):
             elif re.search('^wiki:', main_link):
                 data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="inside" href="/' + tool.url_pas(re.sub('^wiki:', '', main_link)) + '">' + see_link + '</a>', data, 1)
                 data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="inside" href="/' + tool.url_pas(re.sub('^wiki:', '', main_link)) + '">' + see_link + '</a>', data, 1)
 
 
+            elif re.search('^inter:((?:(?!:).)+):', main_link):
+                inter_data = re.search('^inter:((?:(?!:).)+):((?:(?!\]\]|\|).)+)', main_link)
+                inter_data = inter_data.groups()
+
+                curs.execute('select link from inter where title = ?', [inter_data[0]])
+                inter = curs.fetchall()
+                if inter:
+                    if see_link != main_link:
+                        data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="inside" href="' + inter[0][0] + inter_data[1] + '">' + inter_data[0] + ':' + see_link + '</a>', data, 1)
+                    
+                    else:
+                        data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="inside" href="' + inter[0][0] + inter_data[1] + '">' + inter_data[0] + ':' + inter_data[1] + '</a>', data, 1)
+
+                else:
+                    data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '인터위키 정보 없음', data, 1)
+
+            elif re.search('^\/', main_link):
+                under_title = re.search('^(\/(?:.+))$', main_link)
+                under_title = under_title.groups()[0]
+
+                if see_link != main_link:
+                    data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '[[' + title + under_title + '|' + see_link + ']]', data, 1)
+
+                else:
+                    data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '[[' + title + under_title + ']]', data, 1)
+
             elif re.search('^http(s)?:\/\/', main_link):
             elif re.search('^http(s)?:\/\/', main_link):
                 data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="out_link" rel="nofollow" href="' + main_link + '">' + see_link + '</a>', data, 1)
                 data = re.sub('\[\[((?:(?!\[\[|\]\]).)+)\]\]', '<a id="out_link" rel="nofollow" href="' + main_link + '">' + see_link + '</a>', data, 1)
 
 
@@ -829,11 +881,14 @@ def start(conn, data, title):
         else:
         else:
             break
             break
 
 
+    data = re.sub('\n+$', '', data)
+
     footnote_all += '</ul>'
     footnote_all += '</ul>'
     if footnote_all == '\n<hr><ul id="footnote_data"></ul>':
     if footnote_all == '\n<hr><ul id="footnote_data"></ul>':
         footnote_all = ''
         footnote_all = ''
 
 
-    data = re.sub('\n$', footnote_all, data, 1)
+    
+    data = re.sub('\n$', footnote_all, data + '\n', 1)
 
 
     # 분류 마지막 처리
     # 분류 마지막 처리
     category += '</div>'
     category += '</div>'
@@ -842,11 +897,7 @@ def start(conn, data, title):
     if category == '\n<hr><div id="cate">분류: </div>':
     if category == '\n<hr><div id="cate">분류: </div>':
         category = ''
         category = ''
 
 
-    if data != '\n\n':
-        data += category
-
-    else:
-        data = re.sub('\n<hr>', '', category)
+    data += category
     
     
     # 마지막 처리
     # 마지막 처리
     data = re.sub('(?P<in><\/h[0-9]>)(\n)+', '\g<in>', data)
     data = re.sub('(?P<in><\/h[0-9]>)(\n)+', '\g<in>', data)

+ 5 - 0
version.md

@@ -143,6 +143,11 @@
 ## 3.0 (진행)
 ## 3.0 (진행)
  * 파서 다시 작성
  * 파서 다시 작성
  * 사소한 기능 변경
  * 사소한 기능 변경
+ * 내 정보 수정 완성
+ * 사용자 스킨 기능
+ * 차단 관련 조정
+ * 스킨 JinJa로 변경
+
 
 
 ## 자세한 내용
 ## 자세한 내용
  * [참조](https://github.com/2DU/openNAMU/commits/master)
  * [참조](https://github.com/2DU/openNAMU/commits/master)

+ 1 - 7
views/acme/index.html

@@ -108,13 +108,7 @@
                                 <li style="margin: 0;">
                                 <li style="margin: 0;">
                                     {% if menu != 0 %}
                                     {% if menu != 0 %}
                                         {% for sub_d in menu %}
                                         {% for sub_d in menu %}
-                                            {% if sub_d[1] == 1 %}
-                                                <a class="menu-item" href="/{{sub_d[0]}}" id="open">토론</a>
-                                            {% elif sub_d[1] == 0 %}
-                                                <a class="menu-item" href="/{{sub_d[0]}}">토론</a>
-                                            {% else %}
-                                                <a class="menu-item" href="/{{sub_d[0]}}">{{sub_d[1]}}</a>
-                                            {% endif %}
+                                            <a class="menu-item" href="/{{sub_d[0]}}">{{sub_d[1]}}</a>
                                             {% if menu[loop.index] %}
                                             {% if menu[loop.index] %}
                                             {% endif %}
                                             {% endif %}