main.py 107 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207
  1. from flask import Flask, request, session, render_template, send_file
  2. app = Flask(__name__)
  3. from urllib import parse
  4. import json
  5. import pymysql
  6. import time
  7. import re
  8. import bcrypt
  9. import os
  10. import difflib
  11. import hashlib
  12. from func import *
  13. from mark import *
  14. json_data = open('set.json').read()
  15. set_data = json.loads(json_data)
  16. print('port : ' + set_data['port'])
  17. import logging
  18. log = logging.getLogger('werkzeug')
  19. log.setLevel(logging.ERROR)
  20. def start():
  21. try:
  22. db_ex("select * from data limit 1")
  23. except:
  24. db_ex("create table data(title text, data longtext, acl text)")
  25. try:
  26. db_ex("select * from history limit 1")
  27. except:
  28. db_ex("create table history(id text, title text, data longtext, date text, ip text, send text, leng text)")
  29. try:
  30. db_ex("select * from rd limit 1")
  31. except:
  32. db_ex("create table rd(title text, sub text, date text)")
  33. try:
  34. db_ex("select * from user limit 1")
  35. except:
  36. db_ex("create table user(id text, pw text, acl text)")
  37. try:
  38. db_ex("select * from ban limit 1")
  39. except:
  40. db_ex("create table ban(block text, end text, why text, band text)")
  41. try:
  42. db_ex("select * from topic limit 1")
  43. except:
  44. db_ex("create table topic(id text, title text, sub text, data longtext, date text, ip text, block text)")
  45. try:
  46. db_ex("select * from stop limit 1")
  47. except:
  48. db_ex("create table stop(title text, sub text, close text)")
  49. try:
  50. db_ex("select * from rb limit 1")
  51. except:
  52. db_ex("create table rb(block text, end text, today text, blocker text, why text)")
  53. try:
  54. db_ex("select * from login limit 1")
  55. except:
  56. db_ex("create table login(user text, ip text, today text)")
  57. try:
  58. db_ex("select * from back limit 1")
  59. except:
  60. db_ex("create table back(title text, link text, type text)")
  61. try:
  62. db_ex("select * from cat limit 1")
  63. except:
  64. db_ex("create table cat(title text, cat text)")
  65. try:
  66. db_ex("select * from hidhi limit 1")
  67. except:
  68. db_ex("create table hidhi(title text, re text)")
  69. try:
  70. db_ex("select * from distop limit 1")
  71. except:
  72. db_ex("create table distop(id text, title text, sub text)")
  73. try:
  74. db_ex("select * from agreedis limit 1")
  75. except:
  76. db_ex("create table agreedis(title text, sub text)")
  77. conn = pymysql.connect(host = set_data['host'], user = set_data['user'], password = set_data['pw'], charset = 'utf8mb4')
  78. curs = conn.cursor(pymysql.cursors.DictCursor)
  79. def db_com():
  80. conn.commit()
  81. def url_pas(data):
  82. return parse.quote(data).replace('/','%2F')
  83. def db_get():
  84. return curs.fetchall()
  85. web_render = render_template
  86. db_ex = curs.execute
  87. db_pas = pymysql.escape_string
  88. try:
  89. db_ex("use " + set_data['db'])
  90. except:
  91. db_ex("create database " + set_data['db'])
  92. db_ex("use " + set_data['db'])
  93. db_ex("alter database " + set_data['db'] + " character set = utf8mb4 collate = utf8mb4_unicode_ci")
  94. start()
  95. app.secret_key = hashlib.sha512(bytes(set_data['key'], 'ascii')).hexdigest()
  96. @app.route('/upload', methods=['GET', 'POST'])
  97. def upload():
  98. app.config['MAX_CONTENT_LENGTH'] = int(set_data['upload']) * 1024 * 1024
  99. ip = ip_check()
  100. ban = ban_check(ip)
  101. if(request.method == 'POST'):
  102. if(ban == 1):
  103. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  104. else:
  105. file = request.files['file']
  106. if(file):
  107. if(re.search('^([^./\\*<>|:?"]+)\.([Jj][Pp][Gg]|[Gg][Ii][Ff]|[Jj][Pp][Ee][Gg]|[Pp][Nn][Gg])$', file.filename)):
  108. filename = file.filename
  109. if(os.path.exists(os.path.join('image', filename))):
  110. return '<meta http-equiv="refresh" content="0;url=/error/16" />'
  111. else:
  112. file.save(os.path.join('image', filename))
  113. db_ex("insert into data (title, data, acl) value ('" + db_pas('파일:' + filename) + "', '" + db_pas('[[파일:' + filename + ']][br][br]{{{[[파일:' + filename + ']]}}}') + "', '')")
  114. db_com()
  115. history_plus('파일:' + filename, '[[파일:' + filename + ']][br][br]{{{[[파일:' + filename + ']]}}}', get_time(), ip, '파일:' + filename + ' 업로드', '0')
  116. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas('파일:' + filename) + '" />'
  117. else:
  118. return '<meta http-equiv="refresh" content="0;url=/error/15" />'
  119. else:
  120. return '<meta http-equiv="refresh" content="0;url=/error/14" />'
  121. else:
  122. if(ban == 1):
  123. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  124. else:
  125. return web_render('index.html', login = login_check(), logo = set_data['name'], title = '업로드', tn = 21, number = set_data['upload'])
  126. @app.route('/image/<path:name>')
  127. def image_get(name = None):
  128. if(os.path.exists(os.path.join('image', name))):
  129. return send_file(os.path.join('image', name), mimetype='image')
  130. else:
  131. return web_render('index.html', login = login_check(), logo = set_data['name'], data = '이미지 없음.', title = '이미지 보기'), 404
  132. @app.route('/adminlist')
  133. def admin_list():
  134. i = 0
  135. div = '<div>'
  136. db_ex("select * from user where acl = 'admin' or acl = 'owner'")
  137. user_data = db_get()
  138. if(user_data):
  139. while(True):
  140. try:
  141. a = user_data[i]
  142. except:
  143. div = div + '</div>'
  144. break
  145. if(user_data[i]['acl'] == 'owner'):
  146. acl = '소유자'
  147. else:
  148. acl = '관리자'
  149. db_ex("select * from data where title = '사용자:" + user_data[i]['id'] + "'")
  150. user = db_get()
  151. if(user):
  152. name = '<a href="/w/' + url_pas('사용자:' + user_data[i]['id']) + '">' + user_data[i]['id'] + '</a> (' + acl + ')'
  153. else:
  154. name = '<a class="not_thing" href="/w/' + url_pas('사용자:' + user_data[i]['id']) + '">' + user_data[i]['id'] + '</a> (' + acl + ')'
  155. div = div + '<li>' + str(i + 1) + '. ' + name + '</li>'
  156. i += 1
  157. return web_render('index.html', login = login_check(), logo = set_data['name'], data = div, title = '관리자 목록')
  158. else:
  159. return web_render('index.html', login = login_check(), logo = set_data['name'], title = '관리자 목록')
  160. @app.route('/recentchanges')
  161. def recent_changes():
  162. i = 0
  163. div = '<div>'
  164. db_ex("select * from history order by date desc limit 50")
  165. rows = db_get()
  166. if(rows):
  167. while(True):
  168. try:
  169. a = rows[i]
  170. except:
  171. div = div + '</div>'
  172. break
  173. if(rows[i]['send']):
  174. send = rows[i]['send']
  175. send = re.sub('<a href="\/w\/(?P<in>[^"]*)">(?P<out>[^&]*)<\/a>', '<a href="/w/\g<in>">\g<out></a>', send)
  176. else:
  177. send = '<br>'
  178. title = rows[i]['title']
  179. title = re.sub('<', '&lt;', title)
  180. title = re.sub('>', '&gt;', title)
  181. m = re.search("\+", rows[i]['leng'])
  182. n = re.search("\-", rows[i]['leng'])
  183. if(m):
  184. leng = '<span style="color:green;">' + rows[i]['leng'] + '</span>'
  185. elif(n):
  186. leng = '<span style="color:red;">' + rows[i]['leng'] + '</span>'
  187. else:
  188. leng = '<span style="color:gray;">' + rows[i]['leng'] + '</span>'
  189. if(admin_check() == 1):
  190. db_ex("select * from ban where block = '" + db_pas(rows[i]['ip']) + "'")
  191. row = db_get()
  192. if(row):
  193. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(해제)</a>'
  194. else:
  195. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(차단)</a>'
  196. else:
  197. ban = ''
  198. if(re.search('\.', rows[i]['ip'])):
  199. ip = rows[i]['ip'] + ' <a href="/record/' + url_pas(rows[i]['ip']) + '/n/1">(기록)</a>'
  200. else:
  201. db_ex("select * from data where title = '사용자:" + db_pas(rows[i]['ip']) + "'")
  202. row = db_get()
  203. if(row):
  204. ip = '<a href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a> <a href="/record/' + url_pas(rows[i]['ip']) + '/n/1">(기록)</a>'
  205. else:
  206. ip = '<a class="not_thing" href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a> <a href="/record/' + url_pas(rows[i]['ip']) + '/n/1">(기록)</a>'
  207. if((int(rows[i]['id']) - 1) == 0):
  208. revert = ''
  209. else:
  210. revert = '<a href="/revert/' + url_pas(rows[i]['title']) + '/r/' + str(int(rows[i]['id']) - 1) + '">(되돌리기)</a>'
  211. div = div + '<table style="width: 100%;"><tbody><tr><td style="text-align: center;width:33.33%;"><a href="/w/' + url_pas(rows[i]['title']) + '">' + title + '</a> <a href="/history/' + url_pas(rows[i]['title']) + '/n/1">(역사)</a> ' + revert + ' (' + leng + ')</td><td style="text-align: center;width:33.33%;">' + ip + ban + '</td><td style="text-align: center;width:33.33%;">' + rows[i]['date'] + '</td></tr><tr><td colspan="3" style="text-align: center;width:100%;">' + send + '</td></tr></tbody></table>'
  212. i += 1
  213. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = div, tn = 3, title = '최근 변경내역')
  214. else:
  215. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = '', tn = 3, title = '최근 변경내역')
  216. @app.route('/history/<path:name>/r/<int:num>/hidden')
  217. def history_hidden(name = None, num = None):
  218. if(owner_check() == 1):
  219. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  220. exist = db_get()
  221. if(exist):
  222. db_ex("delete from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  223. else:
  224. db_ex("insert into hidhi (title, re) value ('" + db_pas(name) + "', '" + db_pas(str(num)) + "')")
  225. db_com()
  226. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '/n/1" />'
  227. else:
  228. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '/n/1" />'
  229. @app.route('/record/<path:name>/n/<int:num>')
  230. def user_record(name = None, num = None):
  231. v = num * 50
  232. i = v - 50
  233. div = '<div>'
  234. db_ex("select * from history where ip = '" + db_pas(name) + "' order by date desc")
  235. rows = db_get()
  236. if(rows):
  237. while(True):
  238. try:
  239. a = rows[i]
  240. except:
  241. div = div + '</div>'
  242. if(num != 1):
  243. div = div + '<br><a href="/record/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)'
  244. break
  245. if(rows[i]['send']):
  246. send = rows[i]['send']
  247. send = re.sub('<a href="\/w\/(?P<in>[^"]*)">(?P<out>[^&]*)<\/a>', '<a href="/w/\g<in>">\g<out></a>', send)
  248. else:
  249. send = '<br>'
  250. title = rows[i]['title']
  251. title = re.sub('<', '&lt;', title)
  252. title = re.sub('>', '&gt;', title)
  253. m = re.search("\+", rows[i]['leng'])
  254. n = re.search("\-", rows[i]['leng'])
  255. if(m):
  256. leng = '<span style="color:green;">' + rows[i]['leng'] + '</span>'
  257. elif(n):
  258. leng = '<span style="color:red;">' + rows[i]['leng'] + '</span>'
  259. else:
  260. leng = '<span style="color:gray;">' + rows[i]['leng'] + '</span>'
  261. if(admin_check() == 1):
  262. db_ex("select * from ban where block = '" + db_pas(rows[i]['ip']) + "'")
  263. row = db_get()
  264. if(row):
  265. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(해제)</a>'
  266. else:
  267. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(차단)</a>'
  268. else:
  269. ban = ''
  270. if(re.search('\.', rows[i]['ip'])):
  271. ip = rows[i]['ip']
  272. else:
  273. db_ex("select * from data where title = '사용자:" + db_pas(rows[i]['ip']) + "'")
  274. row = db_get()
  275. if(row):
  276. ip = '<a href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a>'
  277. else:
  278. ip = '<a class="not_thing" href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a>'
  279. if((int(rows[i]['id']) - 1) == 0):
  280. revert = ''
  281. else:
  282. revert = '<a href="/revert/' + url_pas(rows[i]['title']) + '/r/' + str(int(rows[i]['id']) - 1) + '">(되돌리기)</a>'
  283. div = div + '<table style="width: 100%;"><tbody><tr><td style="text-align: center;width:33.33%;"><a href="/w/' + url_pas(rows[i]['title']) + '">' + title + '</a> r' + rows[i]['id'] + ' <a href="/history/' + url_pas(rows[i]['title']) + '/n/1">(역사)</a> ' + revert + ' (' + leng + ')</td><td style="text-align: center;width:33.33%;">' + ip + ban + '</td><td style="text-align: center;width:33.33%;">' + rows[i]['date'] + '</td></tr><tr><td colspan="3" style="text-align: center;width:100%;">' + send + '</td></tr></tbody></table>'
  284. if(i == v):
  285. div = div + '</div>'
  286. if(num == 1):
  287. div = div + '<br><a href="/record/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  288. else:
  289. div = div + '<br><a href="/record/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전) <a href="/record/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  290. break
  291. i += 1
  292. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = div, tn = 3, title = '유저 기록')
  293. else:
  294. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = '', tn = 3, title = '유저 기록')
  295. @app.route('/userlog/n/<int:number>')
  296. def user_log(number = None):
  297. i = number * 50
  298. j = i - 50
  299. list = ''
  300. db_ex("select * from user")
  301. user_list = db_get()
  302. if(user_list):
  303. while(True):
  304. try:
  305. a = user_list[j]
  306. except:
  307. if(number != 1):
  308. list = list + '<br><a href="/userlog/n/' + str(number - 1) + '">(이전)'
  309. break
  310. if(admin_check() == 1):
  311. db_ex("select * from ban where block = '" + db_pas(user_list[j]['id']) + "'")
  312. ban_exist = db_get()
  313. if(ban_exist):
  314. ban_button = ' <a href="/ban/' + url_pas(user_list[j]['id']) + '">(해제)</a>'
  315. else:
  316. ban_button = ' <a href="/ban/' + url_pas(user_list[j]['id']) + '">(차단)</a>'
  317. else:
  318. ban_button = ''
  319. db_ex("select * from data where title = '사용자:" + db_pas(user_list[j]['id']) + "'")
  320. file = db_get()
  321. if(file):
  322. ip = '<a href="/w/' + url_pas('사용자:' + user_list[j]['id']) + '">' + user_list[j]['id'] + '</a> <a href="/record/' + url_pas(user_list[j]['id']) + '/n/1">(기록)</a>'
  323. else:
  324. ip = '<a class="not_thing" href="/w/' + url_pas('사용자:' + user_list[j]['id']) + '">' + user_list[j]['id'] + '</a> <a href="/record/' + url_pas(user_list[j]['id']) + '/n/1">(기록)</a>'
  325. list = list + '<li>' + str(j + 1) + '. ' + ip + ban_button + '</li>'
  326. if(j == i):
  327. if(number == 1):
  328. list = list + '<br><a href="/userlog/n/' + str(number + 1) + '">(다음)'
  329. else:
  330. list = list + '<br><a href="/userlog/n/' + str(number - 1) + '">(이전) <a href="/userlog/n/' + str(number + 1) + '">(다음)'
  331. break
  332. else:
  333. j += 1
  334. return web_render('index.html', login = login_check(), logo = set_data['name'], data = list, title = '유저 가입 기록')
  335. else:
  336. return web_render('index.html', login = login_check(), logo = set_data['name'], data = '', title = '유저 가입 기록')
  337. @app.route('/backlink/<path:name>/n/<int:num>')
  338. def backlink(name = None, num = None):
  339. v = num * 50
  340. i = v - 50
  341. div = ''
  342. restart = 0
  343. db_ex("select * from back where title = '" + db_pas(name) + "' order by link asc")
  344. rows = db_get()
  345. if(rows):
  346. while(True):
  347. try:
  348. a = rows[i]
  349. except:
  350. if(num != 1):
  351. div = div + '<br><a href="/backlink/n/' + str(num - 1) + '">(이전)'
  352. break
  353. if(rows[i]['type'] == 'include'):
  354. db_ex("select * from back where title = '" + db_pas(name) + "' and link = '" + db_pas(rows[i]['link']) + "' and type = ''")
  355. test = db_get()
  356. if(test):
  357. restart = 1
  358. db_ex("delete from back where title = '" + db_pas(name) + "' and link = '" + db_pas(rows[i]['link']) + "' and type = ''")
  359. db_com()
  360. if(not re.search('^사용자:', rows[i]['link'])):
  361. db_ex("select * from data where title = '" + db_pas(rows[i]['link']) + "'")
  362. row = db_get()
  363. if(row):
  364. data = row[0]['data']
  365. data = re.sub("(?P<in>\[include\((?P<out>(?:(?!\)\]|,).)*)((?:,\s?(?:[^)]*))+)?\)\])", "\g<in>\n\n[[\g<out>]]\n\n", data)
  366. data = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', '[[\g<in>]]', data)
  367. data = namumark('', data)
  368. if(re.search("<a(?:(?:(?!href=).)*)?href=\"\/w\/" + url_pas(name) + "(?:\#[^\"]*)?\"(?:(?:(?!>).)*)?>([^<]*)<\/a>", data)):
  369. div = div + '<li><a href="/w/' + url_pas(rows[i]['link']) + '">' + rows[i]['link'] + '</a>'
  370. if(rows[i]['type']):
  371. div = div + ' (' + rows[i]['type'] + ')</li>'
  372. else:
  373. div = div + '</li>'
  374. if(i == v):
  375. if(num == 1):
  376. div = div + '<br><a href="/backlink/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  377. else:
  378. div = div + '<br><a href="/backlink/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전) <a href="/backlink/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  379. break
  380. else:
  381. i += 1
  382. else:
  383. db_ex("delete from back where title = '" + db_pas(name) + "' and link = '" + db_pas(rows[i]['link']) + "'")
  384. db_com()
  385. i += 1
  386. v += 1
  387. else:
  388. db_ex("delete from back where title = '" + db_pas(name) + "' and link = '" + db_pas(rows[i]['link']) + "'")
  389. db_com()
  390. i += 1
  391. v += 1
  392. else:
  393. db_ex("delete from back where title = '" + db_pas(name) + "' and link = '" + db_pas(rows[i]['link']) + "'")
  394. db_com()
  395. i += 1
  396. v += 1
  397. if(restart == 1):
  398. return '<meta http-equiv="refresh" content="0;url=/backlink/' + url_pas(name) + '/n/' + str(num) + '" />'
  399. else:
  400. return web_render('index.html', login = login_check(), logo = set_data['name'], data = div, title = name, page = url_pas(name), sub = '역링크')
  401. else:
  402. return web_render('index.html', login = login_check(), logo = set_data['name'], data = '', title = name, page = url_pas(name), sub = '역링크')
  403. @app.route('/recentdiscuss')
  404. def recent_discuss():
  405. i = 0
  406. div = '<div>'
  407. db_ex("select * from rd order by date desc limit 50")
  408. rows = db_get()
  409. if(rows):
  410. while(True):
  411. try:
  412. a = rows[i]
  413. except:
  414. div = div + '</div>'
  415. break
  416. title = rows[i]['title']
  417. title = re.sub('<', '&lt;', title)
  418. title = re.sub('>', '&gt;', title)
  419. sub = rows[i]['sub']
  420. sub = re.sub('<', '&lt;', sub)
  421. sub = re.sub('>', '&gt;', sub)
  422. div = div + '<table style="width: 100%;"><tbody><tr><td style="text-align: center;width:50%;"><a href="/topic/' + url_pas(rows[i]['title']) + '/sub/' + url_pas(rows[i]['sub']) + '">' + title + '</a> (' + sub + ')</td><td style="text-align: center;width:50%;">' + rows[i]['date'] + '</td></tr></tbody></table>'
  423. i += 1
  424. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = div, tn = 12, title = '최근 토론내역')
  425. else:
  426. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = '', tn = 12, title = '최근 토론내역')
  427. @app.route('/history/<path:name>/n/<int:num>', methods=['POST', 'GET'])
  428. def history_view(name = None, num = None):
  429. if(request.method == 'POST'):
  430. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '/r/' + request.form["b"] + '/diff/' + request.form["a"] + '" />'
  431. else:
  432. select = ''
  433. v = num * 50
  434. i = v - 50
  435. div = '<div>'
  436. db_ex("select * from history where title = '" + db_pas(name) + "' order by id+0 desc")
  437. rows = db_get()
  438. if(rows):
  439. while(True):
  440. style = ''
  441. try:
  442. a = rows[i]
  443. except:
  444. div = div + '</div>'
  445. if(num != 1):
  446. div = div + '<br><a href="/history/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)'
  447. break
  448. select = '<option value="' + str(i + 1) + '">' + str(i + 1) + '</option>' + select
  449. if(rows[i]['send']):
  450. send = rows[i]['send']
  451. send = re.sub('<a href="\/w\/(?P<in>[^"]*)">(?P<out>[^&]*)<\/a>', '<a href="/w/\g<in>">\g<out></a>', send)
  452. else:
  453. send = '<br>'
  454. m = re.search("\+", rows[i]['leng'])
  455. n = re.search("\-", rows[i]['leng'])
  456. if(m):
  457. leng = '<span style="color:green;">' + rows[i]['leng'] + '</span>'
  458. elif(n):
  459. leng = '<span style="color:red;">' + rows[i]['leng'] + '</span>'
  460. else:
  461. leng = '<span style="color:gray;">' + rows[i]['leng'] + '</span>'
  462. if(re.search("\.", rows[i]["ip"])):
  463. ip = rows[i]["ip"] + ' <a href="/record/' + url_pas(rows[i]["ip"]) + '/n/1">(기록)</a>'
  464. else:
  465. db_ex("select * from data where title = '사용자:" + db_pas(rows[i]['ip']) + "'")
  466. row = db_get()
  467. if(row):
  468. ip = '<a href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a> <a href="/record/' + url_pas(rows[i]["ip"]) + '/n/1">(기록)</a>'
  469. else:
  470. ip = '<a class="not_thing" href="/w/' + url_pas('사용자:' + rows[i]['ip']) + '">' + rows[i]['ip'] + '</a> <a href="/record/' + url_pas(rows[i]["ip"]) + '/n/1">(기록)</a>'
  471. if(admin_check() == 1):
  472. db_ex("select * from user where id = '" + db_pas(rows[i]['ip']) + "'")
  473. row = db_get()
  474. if(row):
  475. if(row[0]['acl'] == 'owner' or row[0]['acl'] == 'admin'):
  476. ban = ''
  477. else:
  478. db_ex("select * from ban where block = '" + db_pas(rows[i]['ip']) + "'")
  479. row = db_get()
  480. if(row):
  481. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(해제)</a>'
  482. else:
  483. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(차단)</a>'
  484. else:
  485. db_ex("select * from ban where block = '" + db_pas(rows[i]['ip']) + "'")
  486. row = db_get()
  487. if(row):
  488. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(해제)</a>'
  489. else:
  490. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(차단)</a>'
  491. if(owner_check() == 1):
  492. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(rows[i]['id']) + "'")
  493. row = db_get()
  494. if(row):
  495. ip = ip + ' (숨김)'
  496. hidden = ' <a href="/history/' + url_pas(name) + '/r/' + rows[i]['id'] + '/hidden">(공개)'
  497. else:
  498. hidden = ' <a href="/history/' + url_pas(name) + '/r/' + rows[i]['id'] + '/hidden">(숨김)'
  499. else:
  500. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(rows[i]['id']) + "'")
  501. row = db_get()
  502. if(row):
  503. ip = '숨김'
  504. hidden = ''
  505. send = '숨김'
  506. ban = ''
  507. style = 'display:none;'
  508. v += 1
  509. else:
  510. hidden = ''
  511. else:
  512. ban = ''
  513. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(rows[i]['id']) + "'")
  514. row = db_get()
  515. if(row):
  516. ip = '숨김'
  517. hidden = ''
  518. send = '숨김'
  519. ban = ''
  520. style = 'display:none;'
  521. v += 1
  522. else:
  523. hidden = ''
  524. div = div + '<table style="width: 100%;' + style + '"><tbody><tr><td style="text-align: center;width:33.33%;">r' + rows[i]['id'] + '</a> <a href="/w/' + url_pas(rows[i]['title']) + '/r/' + rows[i]['id'] + '">(w)</a> <a href="/w/' + url_pas(rows[i]['title']) + '/raw/' + rows[i]['id'] + '">(Raw)</a> <a href="/revert/' + url_pas(rows[i]['title']) + '/r/' + rows[i]['id'] + '">(되돌리기)</a> (' + leng + ')</td><td style="text-align: center;width:33.33%;">' + ip + ban + hidden + '</td><td style="text-align: center;width:33.33%;">' + rows[i]['date'] + '</td></tr><tr><td colspan="3" style="text-align: center;width:100%;">' + send + '</td></tr></tbody></table>'
  525. if(i == v):
  526. div = div + '</div>'
  527. if(num == 1):
  528. div = div + '<br><a href="/history/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  529. else:
  530. div = div + '<br><a href="/history/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전) <a href="/history/' + url_pas(name) + '/n/' + str(num + 1) + '">(다음)'
  531. break
  532. else:
  533. i += 1
  534. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = div, tn = 5, title = name, page = url_pas(name), select = select, sub = '역사')
  535. else:
  536. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = '', tn = 5, title = name, page = url_pas(name), select = select, sub = '역사')
  537. @app.route('/search', methods=['POST'])
  538. def search():
  539. db_ex("select * from data where title = '" + db_pas(request.form["search"]) + "'")
  540. rows = db_get()
  541. if(rows):
  542. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(request.form["search"]) + '" />'
  543. else:
  544. db_ex("select * from data where title like '%" + db_pas(request.form["search"]) + "%'")
  545. rows = db_get()
  546. if(rows):
  547. i = 0
  548. div = '<li>문서가 없습니다. <a href="/w/' + url_pas(request.form["search"]) + '">바로가기</a></li><br>'
  549. while(True):
  550. try:
  551. div = div + '<li><a href="/w/' + url_pas(rows[i]['title']) + '">' + rows[i]['title'] + '</a></li>'
  552. except:
  553. break
  554. i += 1
  555. else:
  556. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(request.form["search"]) + '" />'
  557. return web_render('index.html', login = login_check(), logo = set_data['name'], data = div, title = '검색')
  558. @app.route('/w/<path:name>')
  559. @app.route('/w/<path:name>/from/<path:redirect>')
  560. def read_view(name = None, redirect = None):
  561. i = 0
  562. db_ex("select * from rd where title = '" + db_pas(name) + "' order by date asc")
  563. rows = db_get()
  564. while(True):
  565. try:
  566. a = rows[i]
  567. except:
  568. topic = ""
  569. break
  570. db_ex("select * from stop where title = '" + db_pas(rows[i]['title']) + "' and sub = '" + db_pas(rows[i]['sub']) + "' and close = 'O'")
  571. row = db_get()
  572. if(not row):
  573. topic = "open"
  574. break
  575. else:
  576. i += 1
  577. acl = ''
  578. m = re.search("^(.*)\/(.*)$", name)
  579. if(m):
  580. g = m.groups()
  581. uppage = g[0]
  582. style = ""
  583. else:
  584. uppage = ""
  585. style = "display:none;"
  586. if(admin_check() == 1):
  587. admin_memu = 'ACL'
  588. else:
  589. admin_memu = ''
  590. if(re.search("^분류:", name)):
  591. db_ex("select * from cat where title = '" + db_pas(name) + "' order by cat asc")
  592. rows = db_get()
  593. if(rows):
  594. div = ''
  595. i = 0
  596. while(True):
  597. try:
  598. a = rows[i]
  599. except:
  600. break
  601. db_ex("select * from data where title = '" + db_pas(rows[i]['cat']) + "'")
  602. row = db_get()
  603. if(row):
  604. aa = row[0]['data']
  605. aa = namumark('', aa)
  606. bb = re.search('<div style="width:100%;border: 1px solid #777;padding: 5px;margin-top: 1em;">분류:((?:(?!<\/div>).)*)<\/div>', aa)
  607. if(bb):
  608. cc = bb.groups()
  609. mm = re.search("^분류:(.*)", name)
  610. if(mm):
  611. ee = mm.groups()
  612. if(re.search("<a (class=\"not_thing\")? href=\"\/w\/" + url_pas(name) + "\">" + ee[0] + "<\/a>", cc[0])):
  613. div = div + '<li><a href="/w/' + url_pas(rows[i]['cat']) + '">' + rows[i]['cat'] + '</a></li>'
  614. i += 1
  615. else:
  616. db_ex("delete from cat where title = '" + db_pas(name) + "' and cat = '" + db_pas(rows[i]['cat']) + "'")
  617. db_com()
  618. i += 1
  619. else:
  620. db_ex("delete from cat where title = '" + db_pas(name) + "' and cat = '" + db_pas(rows[i]['cat']) + "'")
  621. db_com()
  622. i += 1
  623. else:
  624. db_ex("delete from cat where title = '" + db_pas(name) + "' and cat = '" + db_pas(rows[i]['cat']) + "'")
  625. db_com()
  626. i += 1
  627. else:
  628. db_ex("delete from cat where title = '" + db_pas(name) + "' and cat = '" + db_pas(rows[i]['cat']) + "'")
  629. db_com()
  630. i += 1
  631. div = '<h2>분류</h2>' + div
  632. else:
  633. div = ''
  634. else:
  635. div = ''
  636. db_ex("select * from data where title = '" + db_pas(name) + "'")
  637. rows = db_get()
  638. if(rows):
  639. if(rows[0]['acl'] == 'admin'):
  640. acl = '(관리자)'
  641. elif(rows[0]['acl'] == 'user'):
  642. acl = '(유저)'
  643. else:
  644. if(not acl):
  645. acl = ''
  646. m = re.search("^사용자:(.*)", name)
  647. if(m):
  648. g = m.groups()
  649. db_ex("select * from user where id = '" + db_pas(g[0]) + "'")
  650. test = db_get()
  651. if(test):
  652. if(test[0]['acl'] == 'owner'):
  653. acl = '(소유자)'
  654. elif(test[0]['acl'] == 'admin'):
  655. acl = '(관리자)'
  656. db_ex("select * from ban where block = '" + db_pas(g[0]) + "'")
  657. user = db_get()
  658. if(user):
  659. elsedata = '{{{#!wiki style="border:2px solid red;padding:10px;"\r\n{{{+2 {{{#red 이 사용자는 차단 당했습니다.}}}}}}\r\n\r\n차단 해제 일 : ' + user[0]['end'] + '[br]사유 : ' + user[0]['why'] + '}}}[br]' + rows[0]['data']
  660. else:
  661. elsedata = rows[0]['data']
  662. else:
  663. elsedata = rows[0]['data']
  664. if(redirect):
  665. elsedata = re.sub("^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)", " * [[\g<in>]] 문서로 넘겨주기", elsedata)
  666. enddata = namumark(name, elsedata)
  667. m = re.search('<div id="toc">((?:(?!\/div>).)*)<\/div>', enddata)
  668. if(m):
  669. result = m.groups()
  670. left = result[0]
  671. else:
  672. left = ''
  673. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata + div, license = set_data['license'], tn = 1, acl = acl, left = left, uppage = uppage, style = style, topic = topic, redirect = redirect, admin = admin_memu)
  674. else:
  675. m = re.search("^사용자:(.*)", name)
  676. if(m):
  677. g = m.groups()
  678. db_ex("select * from ban where block = '" + db_pas(g[0]) + "'")
  679. user = db_get()
  680. if(user):
  681. elsedata = '{{{#!wiki style="border:2px solid red;padding:10px;"\r\n{{{+2 {{{#red 이 사용자는 차단 당했습니다.}}}}}}\r\n\r\n차단 해제 일 : ' + user[0]['end'] + '[br]사유 : ' + user[0]['why'] + '}}}[br]' + '문서 없음'
  682. else:
  683. elsedata = '문서 없음'
  684. else:
  685. elsedata = '문서 없음'
  686. if(redirect):
  687. elsedata = re.sub("^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)", " * [[\g<in>]] 문서로 넘겨주기", elsedata)
  688. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = namumark(name, elsedata) + div, license = set_data['license'], tn = 1, uppage = uppage, style = style, acl = acl, topic = topic, redirect = redirect, admin = admin_memu), 404
  689. @app.route('/w/<path:name>/r/<int:num>')
  690. def old_view(name = None, num = None):
  691. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  692. row = db_get()
  693. if(row):
  694. if(owner_check() == 1):
  695. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  696. rows = db_get()
  697. if(rows):
  698. enddata = namumark(name, rows[0]['data'])
  699. m = re.search('<div id="toc">((?:(?!\/div>).)*)<\/div>', enddata)
  700. if(m):
  701. result = m.groups()
  702. left = result[0]
  703. else:
  704. left = ''
  705. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata, tn = 6, left = left, sub = '옛 문서')
  706. else:
  707. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  708. else:
  709. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  710. else:
  711. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  712. rows = db_get()
  713. if(rows):
  714. enddata = namumark(name, rows[0]['data'])
  715. m = re.search('<div id="toc">((?:(?!\/div>).)*)<\/div>', enddata)
  716. if(m):
  717. result = m.groups()
  718. left = result[0]
  719. else:
  720. left = ''
  721. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata, tn = 6, left = left, sub = '옛 문서')
  722. else:
  723. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  724. @app.route('/w/<path:name>/raw/<int:num>')
  725. def old_raw(name = None, num = None):
  726. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  727. row = db_get()
  728. if(row):
  729. if(owner_check() == 1):
  730. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  731. rows = db_get()
  732. if(rows):
  733. enddata = re.sub('<', '&lt;', rows[0]['data'])
  734. enddata = re.sub('>', '&gt;', enddata)
  735. enddata = re.sub('"', '&quot;', enddata)
  736. enddata = '<pre>' + enddata + '</pre>'
  737. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata, sub = '옛 Raw')
  738. else:
  739. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  740. else:
  741. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  742. else:
  743. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  744. rows = db_get()
  745. if(rows):
  746. enddata = re.sub('<', '&lt;', rows[0]['data'])
  747. enddata = re.sub('>', '&gt;', enddata)
  748. enddata = re.sub('"', '&quot;', enddata)
  749. enddata = '<pre>' + enddata + '</pre>'
  750. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata, sub = '옛 Raw')
  751. else:
  752. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  753. @app.route('/raw/<path:name>')
  754. def raw_view(name = None):
  755. db_ex("select * from data where title = '" + db_pas(name) + "'")
  756. rows = db_get()
  757. if(rows):
  758. enddata = re.sub('<', '&lt;', rows[0]['data'])
  759. enddata = re.sub('>', '&gt;', enddata)
  760. enddata = re.sub('"', '&quot;', enddata)
  761. enddata = '<pre>' + enddata + '</pre>'
  762. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = enddata, tn = 7, sub = 'Raw')
  763. else:
  764. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  765. @app.route('/revert/<path:name>/r/<int:num>', methods=['POST', 'GET'])
  766. def revert(name = None, num = None):
  767. ip = ip_check()
  768. can = acl_check(ip, name)
  769. today = get_time()
  770. if(request.method == 'POST'):
  771. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  772. row = db_get()
  773. if(row):
  774. if(owner_check() == 1):
  775. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  776. rows = db_get()
  777. if(rows):
  778. if(can == 1):
  779. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  780. else:
  781. db_ex("select * from data where title = '" + db_pas(name) + "'")
  782. row = db_get()
  783. if(row):
  784. leng = leng_check(len(row[0]['data']), len(rows[0]['data']))
  785. db_ex("update data set data = '" + db_pas(rows[0]['data']) + "' where title = '" + db_pas(name) + "'")
  786. db_com()
  787. else:
  788. leng = '+' + str(len(rows[0]['data']))
  789. db_ex("insert into data (title, data, acl) value ('" + db_pas(name) + "', '" + db_pas(rows[0]['data']) + "', '')")
  790. db_com()
  791. history_plus(name, rows[0]['data'], today, ip, '문서를 ' + str(num) + '판으로 되돌렸습니다.', leng)
  792. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  793. else:
  794. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  795. else:
  796. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  797. else:
  798. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  799. rows = db_get()
  800. if(rows):
  801. if(can == 1):
  802. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  803. else:
  804. db_ex("select * from data where title = '" + db_pas(name) + "'")
  805. row = db_get()
  806. if(row):
  807. leng = leng_check(len(row[0]['data']), len(rows[0]['data']))
  808. db_ex("update data set data = '" + db_pas(rows[0]['data']) + "' where title = '" + db_pas(name) + "'")
  809. db_com()
  810. else:
  811. leng = '+' + str(len(rows[0]['data']))
  812. db_ex("insert into data (title, data, acl) value ('" + db_pas(name) + "', '" + db_pas(rows[0]['data']) + "', '')")
  813. db_com()
  814. history_plus(name, rows[0]['data'], today, ip, '문서를 ' + str(num) + '판으로 되돌렸습니다.', leng)
  815. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  816. else:
  817. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  818. else:
  819. db_ex("select * from hidhi where title = '" + db_pas(name) + "' and re = '" + db_pas(str(num)) + "'")
  820. row = db_get()
  821. if(row):
  822. if(owner_check() == 1):
  823. if(can == 1):
  824. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  825. else:
  826. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  827. rows = db_get()
  828. if(rows):
  829. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), r = url_pas(str(num)), tn = 13, plus = '정말 되돌리시겠습니까?', sub = '되돌리기')
  830. else:
  831. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  832. else:
  833. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  834. else:
  835. if(can == 1):
  836. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  837. else:
  838. db_ex("select * from history where title = '" + db_pas(name) + "' and id = '" + str(num) + "'")
  839. rows = db_get()
  840. if(rows):
  841. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), r = url_pas(str(num)), tn = 13, plus = '정말 되돌리시겠습니까?', sub = '되돌리기')
  842. else:
  843. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  844. @app.route('/edit/<path:name>', methods=['POST', 'GET'])
  845. def edit(name = None):
  846. ip = ip_check()
  847. can = acl_check(ip, name)
  848. if(request.method == 'POST'):
  849. m = re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.form["send"])
  850. if(m):
  851. return '<meta http-equiv="refresh" content="0;url=/error/17" />'
  852. else:
  853. today = get_time()
  854. content = savemark(request.form["content"])
  855. db_ex("select * from data where title = '" + db_pas(name) + "'")
  856. rows = db_get()
  857. if(rows):
  858. if(rows[0]['data'] == content):
  859. return '<meta http-equiv="refresh" content="0;url=/error/18" />'
  860. else:
  861. if(can == 1):
  862. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  863. else:
  864. leng = leng_check(len(rows[0]['data']), len(content))
  865. history_plus(name, content, today, ip, request.form["send"], leng)
  866. db_ex("update data set data = '" + db_pas(content) + "' where title = '" + db_pas(name) + "'")
  867. db_com()
  868. else:
  869. if(can == 1):
  870. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  871. else:
  872. leng = '+' + str(len(content))
  873. history_plus(name, content, today, ip, request.form["send"], leng)
  874. db_ex("insert into data (title, data, acl) value ('" + db_pas(name) + "', '" + db_pas(content) + "', '')")
  875. db_com()
  876. include_check(name, content)
  877. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  878. else:
  879. if(can == 1):
  880. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  881. else:
  882. db_ex("select * from data where title = '" + db_pas(set_data["help"]) + "'")
  883. rows = db_get()
  884. if(rows):
  885. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', rows[0]["data"])
  886. left = namumark(name, newdata)
  887. else:
  888. left = ''
  889. db_ex("select * from data where title = '" + db_pas(name) + "'")
  890. rows = db_get()
  891. if(rows):
  892. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = rows[0]['data'], tn = 2, left = left, sub = '편집')
  893. else:
  894. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = '', tn = 2, left = left, sub = '편집')
  895. @app.route('/edit/<path:name>/section/<int:num>', methods=['POST', 'GET'])
  896. def section_edit(name = None, num = None):
  897. ip = ip_check()
  898. can = acl_check(ip, name)
  899. if(request.method == 'POST'):
  900. m = re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.form["send"])
  901. if(m):
  902. return '<meta http-equiv="refresh" content="0;url=/error/17" />'
  903. else:
  904. today = get_time()
  905. content = savemark(request.form["content"])
  906. db_ex("select * from data where title = '" + db_pas(name) + "'")
  907. rows = db_get()
  908. if(rows):
  909. if(request.form["otent"] == content):
  910. return '<meta http-equiv="refresh" content="0;url=/error/18" />'
  911. else:
  912. if(can == 1):
  913. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  914. else:
  915. leng = leng_check(len(request.form['otent']), len(content))
  916. content = rows[0]['data'].replace(request.form['otent'], content)
  917. history_plus(name, content, today, ip, request.form["send"], leng)
  918. db_ex("update data set data = '" + db_pas(content) + "' where title = '" + db_pas(name) + "'")
  919. db_com()
  920. include_check(name, content)
  921. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  922. else:
  923. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  924. else:
  925. if(can == 1):
  926. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  927. else:
  928. db_ex("select * from data where title = '" + db_pas(set_data["help"]) + "'")
  929. rows = db_get()
  930. if(rows):
  931. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', rows[0]["data"])
  932. left = namumark(name, newdata)
  933. else:
  934. left = ''
  935. db_ex("select * from data where title = '" + db_pas(name) + "'")
  936. rows = db_get()
  937. if(rows):
  938. i = 0
  939. j = 0
  940. gdata = rows[0]['data'] + '\r\n'
  941. while(True):
  942. m = re.search("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", gdata)
  943. if(m):
  944. if(i == num - 1):
  945. g = m.groups()
  946. gdata = re.sub("\r\n$", "", g[0])
  947. break
  948. else:
  949. gdata = re.sub("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", "", gdata, 1)
  950. i += 1
  951. else:
  952. j = 1
  953. break
  954. if(j == 0):
  955. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = gdata, tn = 2, left = left, section = 1, number = num, sub = '편집')
  956. else:
  957. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  958. else:
  959. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  960. @app.route('/preview/<path:name>', methods=['POST'])
  961. def preview(name = None):
  962. ip = ip_check()
  963. can = acl_check(ip, name)
  964. if(can == 1):
  965. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  966. else:
  967. newdata = request.form["content"]
  968. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', newdata)
  969. enddata = namumark(name, newdata)
  970. db_ex("select * from data where title = '" + db_pas(data["help"]) + "'")
  971. rows = db_get()
  972. if(rows):
  973. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', rows[0]["data"])
  974. left = namumark(name, newdata)
  975. else:
  976. left = ''
  977. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = request.form["content"], tn = 2, preview = 1, enddata = enddata, left = left, sub = '미리보기')
  978. @app.route('/preview/<path:name>/section/<int:num>', methods=['POST'])
  979. def section_preview(name = None, num = None):
  980. ip = ip_check()
  981. can = acl_check(ip, name)
  982. if(can == 1):
  983. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  984. else:
  985. newdata = request.form["content"]
  986. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', newdata)
  987. enddata = namumark(name, newdata)
  988. db_ex("select * from data where title = '" + db_pas(data["help"]) + "'")
  989. rows = db_get()
  990. if(rows):
  991. newdata = re.sub('^#(?:[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', rows[0]["data"])
  992. left = namumark(name, newdata)
  993. else:
  994. left = ''
  995. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), data = request.form["content"], tn = 2, preview = 1, enddata = enddata, left = left, section = 1, number = num, odata = request.form["otent"], sub = '미리보기')
  996. @app.route('/delete/<path:name>', methods=['POST', 'GET'])
  997. def delete(name = None):
  998. ip = ip_check()
  999. can = acl_check(ip, name)
  1000. if(request.method == 'POST'):
  1001. db_ex("select * from data where title = '" + db_pas(name) + "'")
  1002. rows = db_get()
  1003. if(rows):
  1004. if(can == 1):
  1005. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1006. else:
  1007. today = get_time()
  1008. leng = '-' + str(len(rows[0]['data']))
  1009. history_plus(name, '', today, ip, '문서를 삭제 했습니다.', leng)
  1010. db_ex("delete from data where title = '" + db_pas(name) + "'")
  1011. db_com()
  1012. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  1013. else:
  1014. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  1015. else:
  1016. db_ex("select * from data where title = '" + db_pas(name) + "'")
  1017. rows = db_get()
  1018. if(rows):
  1019. if(can == 1):
  1020. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1021. else:
  1022. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), tn = 8, plus = '정말 삭제 하시겠습니까?', sub = '삭제')
  1023. else:
  1024. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  1025. @app.route('/move/<path:name>', methods=['POST', 'GET'])
  1026. def move(name = None):
  1027. ip = ip_check()
  1028. can = acl_check(ip, name)
  1029. today = get_time()
  1030. if(request.method == 'POST'):
  1031. db_ex("select * from data where title = '" + db_pas(name) + "'")
  1032. rows = db_get()
  1033. if(can == 1):
  1034. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1035. else:
  1036. leng = '0'
  1037. db_ex("select * from history where title = '" + db_pas(request.form["title"]) + "'")
  1038. row = db_get()
  1039. if(row):
  1040. return '<meta http-equiv="refresh" content="0;url=/error/19" />'
  1041. else:
  1042. history_plus(name, rows[0]['data'], today, ip, '<a href="/w/' + url_pas(name) + '">' + name + '</a> 문서를 <a href="/w/' + url_pas(request.form["title"]) + '">' + request.form["title"] + '</a> 문서로 이동 했습니다.', leng)
  1043. if(rows):
  1044. db_ex("update data set title = '" + db_pas(request.form["title"]) + "' where title = '" + db_pas(name) + "'")
  1045. db_ex("update history set title = '" + db_pas(request.form["title"]) + "' where title = '" + db_pas(name) + "'")
  1046. db_com()
  1047. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(request.form["title"]) + '" />'
  1048. else:
  1049. if(can == 1):
  1050. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1051. else:
  1052. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], page = url_pas(name), tn = 9, plus = '정말 이동 하시겠습니까?', sub = '이동')
  1053. @app.route('/other')
  1054. def other():
  1055. return web_render('index.html', login = login_check(), title = '기타 메뉴', logo = set_data['name'], data = '<h2 style="margin-top: 0px;">기록</h2><li><a href="/blocklog/n/1">유저 차단 기록</a></li><li><a href="/userlog/n/1">유저 가입 기록</a></li><li><a href="/manager/6">유저 기록</a></li><h2>기타</h2><li><a href="/titleindex">모든 문서</a></li><li><a href="/upload">업로드</a></li><li><a href="/adminlist">관리자 목록</a></li><li><a href="/manager/1">관리자 메뉴</a></li><br>이 오픈나무의 버전은 <a href="https://github.com/2DU/openNAMU/blob/master/version.md">1.9.1</a> 입니다.')
  1056. @app.route('/manager/<int:num>', methods=['POST', 'GET'])
  1057. def manager(num = None):
  1058. if(num == 1):
  1059. return web_render('index.html', login = login_check(), title = '관리자 메뉴', logo = set_data['name'], data = '<h2 style="margin-top: 0px;">관리자 및 소유자</h2><li><a href="/manager/2">문서 ACL</a></li><li><a href="/manager/3">유저 체크</a></li><li><a href="/manager/4">유저 차단</a></li><h2>소유자</h2><li><a href="/manager/5">관리자 권한 주기</a></li><h2>기타</h2><li>이 메뉴에 없는 기능은 해당 문서의 역사나 토론에서 바로 사용 가능함</li>')
  1060. elif(num == 2):
  1061. if(request.method == 'POST'):
  1062. return '<meta http-equiv="refresh" content="0;url=/acl/' + url_pas(request.form["name"]) + '" />'
  1063. else:
  1064. return web_render('index.html', login = login_check(), title = 'ACL 이동', logo = set_data['name'], data = '<form id="usrform" method="POST" action="/manager/2"><input name="name" type="text"><br><br><button class="btn btn-primary" type="submit">이동</button></form>')
  1065. elif(num == 3):
  1066. if(request.method == 'POST'):
  1067. return '<meta http-equiv="refresh" content="0;url=/check/' + url_pas(request.form["name"]) + '" />'
  1068. else:
  1069. return web_render('index.html', login = login_check(), title = '체크 이동', logo = set_data['name'], data = '<form id="usrform" method="POST" action="/manager/3"><input name="name" type="text"><br><br><button class="btn btn-primary" type="submit">이동</button></form>')
  1070. elif(num == 4):
  1071. if(request.method == 'POST'):
  1072. return '<meta http-equiv="refresh" content="0;url=/ban/' + url_pas(request.form["name"]) + '" />'
  1073. else:
  1074. return web_render('index.html', login = login_check(), title = '차단 이동', logo = set_data['name'], data = '<form id="usrform" method="POST" action="/manager/4"><input name="name" type="text"><br><br><button class="btn btn-primary" type="submit">이동</button><br><br><span>아이피 앞 두자리 (XXX.XXX) 입력하면 대역 차단</span></form>')
  1075. elif(num == 5):
  1076. if(request.method == 'POST'):
  1077. return '<meta http-equiv="refresh" content="0;url=/admin/' + url_pas(request.form["name"]) + '" />'
  1078. else:
  1079. return web_render('index.html', login = login_check(), title = '권한 이동', logo = set_data['name'], data = '<form id="usrform" method="POST" action="/manager/5"><input name="name" type="text"><br><br><button class="btn btn-primary" type="submit">이동</button></form>')
  1080. elif(num == 6):
  1081. if(request.method == 'POST'):
  1082. return '<meta http-equiv="refresh" content="0;url=/record/' + url_pas(request.form["name"]) + '/n/1" />'
  1083. else:
  1084. return web_render('index.html', login = login_check(), title = '기록 이동', logo = set_data['name'], data = '<form id="usrform" method="POST" action="/manager/6"><input name="name" type="text"><br><br><button class="btn btn-primary" type="submit">이동</button></form>')
  1085. else:
  1086. return '<meta http-equiv="refresh" content="0;url=/" />'
  1087. @app.route('/titleindex')
  1088. def title_index():
  1089. i = 0
  1090. data = '<div>'
  1091. db_ex("select title from data order by title asc")
  1092. title_list = db_get()
  1093. if(title_list):
  1094. while(True):
  1095. try:
  1096. a = title_list[i]
  1097. except:
  1098. break
  1099. data = data + '<li>' + str(i + 1) + '. <a href="/w/' + url_pas(title_list[i]['title']) + '">' + title_list[i]['title'] + '</a></li>'
  1100. i += 1
  1101. data = data + '</div>'
  1102. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = data + '<br><span>이 위키에는 총 ' + str(i) + '개의 문서가 있습니다.</span>', tn = 4, title = '모든 문서')
  1103. else:
  1104. return web_render('index.html', login = login_check(), logo = set_data['name'], rows = '', tn = 4, title = '모든 문서')
  1105. @app.route('/topic/<path:name>', methods=['POST', 'GET'])
  1106. def topic_list(name = None):
  1107. if(request.method == 'POST'):
  1108. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(request.form["topic"]) + '" />'
  1109. else:
  1110. div = '<div>'
  1111. i = 0
  1112. j = 1
  1113. db_ex("select * from rd where title = '" + db_pas(name) + "' order by date asc")
  1114. rows = db_get()
  1115. while(True):
  1116. try:
  1117. a = rows[i]
  1118. except:
  1119. div = div + '</div>'
  1120. break
  1121. db_ex("select * from topic where title = '" + db_pas(rows[i]['title']) + "' and sub = '" + db_pas(rows[i]['sub']) + "' and id = '1' order by sub asc")
  1122. aa = db_get()
  1123. indata = namumark(name, aa[0]['data'])
  1124. if(aa[0]['block'] == 'O'):
  1125. indata = '블라인드 되었습니다.'
  1126. block = 'style="background: gainsboro;"'
  1127. else:
  1128. block = ''
  1129. ip = ip_pas(aa[0]['ip'])
  1130. db_ex("select * from stop where title = '" + db_pas(rows[i]['title']) + "' and sub = '" + db_pas(rows[i]['sub']) + "' and close = 'O'")
  1131. row = db_get()
  1132. if(not row):
  1133. div = div + '<h2><a href="/topic/' + url_pas(rows[i]['title']) + '/sub/' + url_pas(rows[i]['sub']) + '">' + str(j) + '. ' + rows[i]['sub'] + '</a></h2><table id="toron"><tbody><tr><td id="toroncolorgreen"><a href="javascript:void(0);" id="1">#1</a> ' + ip + ' <span style="float:right;">' + aa[0]['date'] + '</span></td></tr><tr><td ' + block + '>' + indata + '</td></tr></tbody></table><br>'
  1134. j += 1
  1135. i += 1
  1136. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = set_data['name'], plus = div, tn = 10, list = 1, sub = '토론 목록')
  1137. @app.route('/topic/<path:name>/close')
  1138. def close_topic_list(name = None):
  1139. div = '<div>'
  1140. i = 0
  1141. db_ex("select * from stop where title = '" + db_pas(name) + "' and close = 'O' order by sub asc")
  1142. rows = db_get()
  1143. while(True):
  1144. try:
  1145. a = rows[i]
  1146. except:
  1147. div = div + '</div>'
  1148. break
  1149. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(rows[i]['sub']) + "' and id = '1'")
  1150. row = db_get()
  1151. if(row):
  1152. indata = namumark(name, row[0]['data'])
  1153. if(row[0]['block'] == 'O'):
  1154. indata = '블라인드 되었습니다.'
  1155. block = 'style="background: gainsboro;"'
  1156. else:
  1157. block = ''
  1158. ip = ip_pas(row[0]['ip'])
  1159. div = div + '<h2><a href="/topic/' + url_pas(name) + '/sub/' + url_pas(rows[i]['sub']) + '">' + str((i + 1)) + '. ' + rows[i]['sub'] + '</a></h2><table id="toron"><tbody><tr><td id="toroncolorgreen"><a href="javascript:void(0);" id="1">#1</a> ' + ip + ' <span style="float:right;">' + row[0]['date'] + '</span></td></tr><tr><td ' + block + '>' + indata + '</td></tr></tbody></table><br>'
  1160. i += 1
  1161. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = set_data['name'], plus = div, tn = 10, sub = '닫힌 토론')
  1162. @app.route('/topic/<path:name>/agree')
  1163. def agree_topic_list(name = None):
  1164. div = '<div>'
  1165. i = 0
  1166. db_ex("select * from agreedis where title = '" + db_pas(name) + "' order by sub asc")
  1167. agree_list = db_get()
  1168. while(True):
  1169. try:
  1170. a = agree_list[i]
  1171. except:
  1172. div = div + '</div>'
  1173. break
  1174. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(agree_list[i]['sub']) + "' and id = '1'")
  1175. data = db_get()
  1176. if(data):
  1177. indata = namumark(name, data[0]['data'])
  1178. if(data[0]['block'] == 'O'):
  1179. indata = '블라인드 되었습니다.'
  1180. block = 'style="background: gainsboro;"'
  1181. else:
  1182. block = ''
  1183. ip = ip_pas(data[0]['ip'])
  1184. div = div + '<h2><a href="/topic/' + url_pas(name) + '/sub/' + url_pas(data[i]['sub']) + '">' + str((i + 1)) + '. ' + data[i]['sub'] + '</a></h2><table id="toron"><tbody><tr><td id="toroncolorgreen"><a href="javascript:void(0);" id="1">#1</a> ' + 아이디 + ' <span style="float:right;">' + data[0]['date'] + '</span></td></tr><tr><td ' + block + '>' + indata + '</td></tr></tbody></table><br>'
  1185. i += 1
  1186. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = set_data['name'], plus = div, tn = 10, sub = '합의된 토론')
  1187. @app.route('/topic/<path:name>/sub/<path:sub>', methods=['POST', 'GET'])
  1188. def topic(name = None, sub = None):
  1189. ip = ip_check()
  1190. ban = topic_check(ip, name, sub)
  1191. admin = admin_check()
  1192. if(request.method == 'POST'):
  1193. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' order by id+0 desc limit 1")
  1194. rows = db_get()
  1195. if(rows):
  1196. number = int(rows[0]['id']) + 1
  1197. else:
  1198. number = 1
  1199. if(ban == 1 and not admin == 1):
  1200. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1201. else:
  1202. db_ex("select * from user where id = '" + db_pas(ip) + "'")
  1203. rows = db_get()
  1204. if(rows):
  1205. if(rows[0]['acl'] == 'owner' or rows[0]['acl'] == 'admin'):
  1206. ip = ip + ' - Admin'
  1207. today = get_time()
  1208. rd_plus(name, sub, today)
  1209. aa = request.form["content"]
  1210. aa = re.sub("\[\[(분류:(?:(?:(?!\]\]).)*))\]\]", "[br]", aa)
  1211. aa = savemark(aa)
  1212. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + str(number) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', '" + db_pas(aa) + "', '" + today + "', '" + ip + "', '')")
  1213. db_com()
  1214. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1215. else:
  1216. style = ''
  1217. db_ex("select * from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = 'O'")
  1218. close = db_get()
  1219. db_ex("select * from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = ''")
  1220. stop = db_get()
  1221. if(admin == 1):
  1222. div = '<div>'
  1223. if(close):
  1224. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/close">(토론 열기)</a> '
  1225. else:
  1226. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/close">(토론 닫기)</a> '
  1227. if(stop):
  1228. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/stop">(토론 재개)</a> '
  1229. else:
  1230. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/stop">(토론 정지)</a> '
  1231. db_ex("select * from agreedis where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "'")
  1232. agree = db_get()
  1233. if(agree):
  1234. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/agree">(합의 취소)</a>'
  1235. else:
  1236. div = div + '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/agree">(합의 완료)</a>'
  1237. div = div + '<br><br>'
  1238. else:
  1239. div = '<div>'
  1240. if(stop or close):
  1241. if(not admin == 1):
  1242. style = 'display:none;'
  1243. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' order by id+0 asc")
  1244. rows = db_get()
  1245. db_ex("select * from distop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' order by id+0 asc")
  1246. top = db_get()
  1247. i = 0
  1248. if(top):
  1249. while(True):
  1250. try:
  1251. a = top[i]
  1252. except:
  1253. break
  1254. num = int(top[i]['id']) - 1
  1255. if(i == 0):
  1256. start = rows[num]['ip']
  1257. top_data = namumark('', rows[num]['data'])
  1258. top_data = re.sub("(?P<in>#(?:[0-9]*))", '<a href="\g<in>">\g<in></a>', top_data)
  1259. ip = ip_pas(rows[num]['ip'])
  1260. div = div + '<table id="toron"><tbody><tr><td id="toroncolorred"><a href="#' + top[i]['id'] + '" id="' + top[i]['id'] + '-nt">#' + top[i]['id'] + '</a> ' + ip + ' <span style="float:right;">' + rows[num]['date'] + '</span></td></tr><tr><td>' + top_data + '</td></tr></tbody></table><br>'
  1261. i = i + 1
  1262. i = 0
  1263. while(True):
  1264. try:
  1265. a = rows[i]
  1266. except:
  1267. div = div + '</div>'
  1268. break
  1269. if(i == 0):
  1270. start = rows[i]['ip']
  1271. indata = namumark('', rows[i]['data'])
  1272. indata = re.sub("(?P<in>#(?:[0-9]*))", '<a href="\g<in>">\g<in></a>', indata)
  1273. if(rows[i]['block'] == 'O'):
  1274. indata = '블라인드 되었습니다.'
  1275. block = 'style="background: gainsboro;"'
  1276. else:
  1277. block = ''
  1278. m = re.search("^([^-]*)\s\-\s(Close|Reopen|Stop|Restart|Agreement|Settlement)$", rows[i]['ip'])
  1279. if(m):
  1280. ban = ""
  1281. else:
  1282. if(admin == 1):
  1283. if(rows[i]['block'] == 'O'):
  1284. isblock = ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(i + 1) + '">(해제)</a>'
  1285. else:
  1286. isblock = ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(i + 1) + '">(블라인드)</a>'
  1287. db_ex("select * from distop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and id = '" + db_pas(str(i + 1)) + "'")
  1288. row = db_get()
  1289. if(row):
  1290. isblock = isblock + ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(i + 1) + '">(해제)</a>'
  1291. else:
  1292. isblock = isblock + ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(i + 1) + '">(공지)</a>'
  1293. n = re.search("\- (?:Admin)$", rows[i]['ip'])
  1294. if(n):
  1295. ban = isblock
  1296. else:
  1297. db_ex("select * from ban where block = '" + db_pas(rows[i]['ip']) + "'")
  1298. row = db_get()
  1299. if(row):
  1300. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(해제)</a>' + isblock
  1301. else:
  1302. ban = ' <a href="/ban/' + url_pas(rows[i]['ip']) + '">(차단)</a>' + isblock
  1303. else:
  1304. ban = ""
  1305. ip = ip_pas(rows[i]['ip'])
  1306. if(rows[i]['ip'] == start):
  1307. j = i + 1
  1308. div = div + '<table id="toron"><tbody><tr><td id="toroncolorgreen"><a href="javascript:void(0);" id="' + str(j) + '">#' + str(j) + '</a> ' + ip + ban + ' <span style="float:right;">' + rows[i]['date'] + '</span></td></tr><tr><td ' + block + '>' + indata + '</td></tr></tbody></table><br>'
  1309. else:
  1310. j = i + 1
  1311. div = div + '<table id="toron"><tbody><tr><td id="toroncolor"><a href="javascript:void(0);" id="' + str(j) + '">#' + str(j) + '</a> ' + ip + ban + ' <span style="float:right;">' + rows[i]['date'] + '</span></td></tr><tr><td ' + block + '>' + indata + '</td></tr></tbody></table><br>'
  1312. i += 1
  1313. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), suburl = url_pas(sub), toron = sub, logo = set_data['name'], rows = div, tn = 11, ban = ban, style = style, sub = '토론')
  1314. @app.route('/topic/<path:name>/sub/<path:sub>/b/<int:num>')
  1315. def topic_block(name = None, sub = None, num = None):
  1316. if(admin_check() == 1):
  1317. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and id = '" + str(num) + "'")
  1318. block = db_get()
  1319. if(block):
  1320. if(block[0]['block'] == 'O'):
  1321. db_ex("update topic set block = '' where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and id = '" + str(num) + "'")
  1322. else:
  1323. db_ex("update topic set block = 'O' where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and id = '" + str(num) + "'")
  1324. db_com()
  1325. rd_plus(name, sub, get_time())
  1326. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1327. else:
  1328. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1329. else:
  1330. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1331. @app.route('/topic/<path:name>/sub/<path:sub>/notice/<int:num>')
  1332. def topic_top(name = None, sub = None, num = None):
  1333. if(admin_check() == 1):
  1334. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and id = '" + str(num) + "'")
  1335. topic_data = db_get()
  1336. if(topic_data):
  1337. db_ex("select * from distop where id = '" + str(num) + "' and title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "'")
  1338. top_data = db_get()
  1339. if(top_data):
  1340. db_ex("delete from distop where id = '" + str(num) + "' and title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "'")
  1341. else:
  1342. db_ex("insert into distop (id, title, sub) value ('" + db_pas(str(num)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "')")
  1343. db_com()
  1344. rd_plus(name, sub, get_time())
  1345. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1346. else:
  1347. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1348. else:
  1349. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1350. @app.route('/topic/<path:name>/sub/<path:sub>/stop')
  1351. def topic_stop(name = None, sub = None):
  1352. if(admin_check() == 1):
  1353. ip = ip_check()
  1354. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' limit 1")
  1355. topic_check = db_get()
  1356. if(topic_check):
  1357. time = get_time()
  1358. db_ex("select * from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = ''")
  1359. stop = db_get()
  1360. if(stop):
  1361. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Restart', '" + db_pas(time) + "', '" + db_pas(ip) + " - Restart', '')")
  1362. db_ex("delete from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = ''")
  1363. else:
  1364. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Stop', '" + db_pas(time) + "', '" + db_pas(ip) + " - Stop', '')")
  1365. db_ex("insert into stop (title, sub, close) value ('" + db_pas(name) + "', '" + db_pas(sub) + "', '')")
  1366. db_com()
  1367. rd_plus(name, sub, time)
  1368. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1369. else:
  1370. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1371. else:
  1372. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1373. @app.route('/topic/<path:name>/sub/<path:sub>/close')
  1374. def topic_close(name = None, sub = None):
  1375. if(admin_check() == 1):
  1376. ip = ip_check()
  1377. db_ex("select * from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' order by id+0 desc limit 1")
  1378. topic_check = db_get()
  1379. if(topic_check):
  1380. time = get_time()
  1381. db_ex("select * from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = 'O'")
  1382. close = db_get()
  1383. if(close):
  1384. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Reopen', '" + db_pas(time) + "', '" + db_pas(ip) + " - Reopen', '')")
  1385. db_ex("delete from stop where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' and close = 'O'")
  1386. else:
  1387. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Close', '" + db_pas(time) + "', '" + db_pas(ip) + " - Close', '')")
  1388. db_ex("insert into stop (title, sub, close) value ('" + db_pas(name) + "', '" + db_pas(sub) + "', 'O')")
  1389. db_com()
  1390. rd_plus(name, sub, time)
  1391. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1392. else:
  1393. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1394. else:
  1395. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1396. @app.route('/topic/<path:name>/sub/<path:sub>/agree')
  1397. def topic_agree(name = None, sub = None):
  1398. if(admin_check() == 1):
  1399. ip = ip_check()
  1400. db_ex("select id from topic where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "' order by id+0 desc limit 1")
  1401. topic_check = db_get()
  1402. if(topic_check):
  1403. time = get_time()
  1404. db_ex("select * from agreedis where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "'")
  1405. agree = db_get()
  1406. if(agree):
  1407. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Settlement', '" + db_pas(time) + "', '" + db_pas(ip) + " - Settlement', '')")
  1408. db_ex("delete from agreedis where title = '" + db_pas(name) + "' and sub = '" + db_pas(sub) + "'")
  1409. else:
  1410. db_ex("insert into topic (id, title, sub, data, date, ip, block) value ('" + db_pas(str(int(topic_check[0]['id']) + 1)) + "', '" + db_pas(name) + "', '" + db_pas(sub) + "', 'Agreement', '" + db_pas(time) + "', '" + db_pas(ip) + " - Agreement', '')")
  1411. db_ex("insert into agreedis (title, sub) value ('" + db_pas(name) + "', '" + db_pas(sub) + "')")
  1412. db_com()
  1413. rd_plus(name, sub, time)
  1414. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1415. else:
  1416. return '<meta http-equiv="refresh" content="0;url=/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '" />'
  1417. else:
  1418. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1419. @app.route('/login', methods=['POST', 'GET'])
  1420. def login():
  1421. ip = ip_check()
  1422. ban = ban_check(ip)
  1423. if(request.method == 'POST'):
  1424. if(ban == 1):
  1425. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1426. else:
  1427. db_ex("select * from user where id = '" + db_pas(request.form["id"]) + "'")
  1428. user = db_get()
  1429. if(user):
  1430. if(session.get('Now') == True):
  1431. return '<meta http-equiv="refresh" content="0;url=/error/11" />'
  1432. elif(bcrypt.checkpw(bytes(request.form["pw"], 'utf-8'), bytes(user[0]['pw'], 'utf-8'))):
  1433. session['Now'] = True
  1434. session['DREAMER'] = request.form["id"]
  1435. db_ex("insert into login (user, ip, today) value ('" + db_pas(request.form["id"]) + "', '" + db_pas(ip) + "', '" + db_pas(get_time()) + "')")
  1436. db_com()
  1437. return '<meta http-equiv="refresh" content="0;url=/user" />'
  1438. else:
  1439. return '<meta http-equiv="refresh" content="0;url=/error/13" />'
  1440. else:
  1441. return '<meta http-equiv="refresh" content="0;url=/error/12" />'
  1442. else:
  1443. if(ban == 1):
  1444. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1445. else:
  1446. if(session.get('Now') == True):
  1447. return '<meta http-equiv="refresh" content="0;url=/error/11" />'
  1448. else:
  1449. return web_render('index.html', login = login_check(), title = '로그인', enter = '로그인', logo = set_data['name'], tn = 15)
  1450. @app.route('/change', methods=['POST', 'GET'])
  1451. def change_password():
  1452. ip = ip_check()
  1453. ban = ban_check(ip)
  1454. if(request.method == 'POST'):
  1455. if(request.form["pw2"] == request.form["pw3"]):
  1456. if(ban == 1):
  1457. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1458. else:
  1459. db_ex("select * from user where id = '" + db_pas(request.form["id"]) + "'")
  1460. user = db_get()
  1461. if(user):
  1462. if(session.get('Now') == True):
  1463. session['Now'] = False
  1464. session.pop('DREAMER', None)
  1465. return '<meta http-equiv="refresh" content="0;url=/change" />'
  1466. elif(bcrypt.checkpw(bytes(request.form["pw"], 'utf-8'), bytes(user[0]['pw'], 'utf-8'))):
  1467. hashed = bcrypt.hashpw(bytes(request.form["pw2"], 'utf-8'), bcrypt.gensalt())
  1468. db_ex("update user set pw = '" + db_pas(hashed.decode()) + "' where id = '" + db_pas(request.form["id"]) + "'")
  1469. db_com()
  1470. return '<meta http-equiv="refresh" content="0;url=/login" />'
  1471. else:
  1472. return '<meta http-equiv="refresh" content="0;url=/error/10" />'
  1473. else:
  1474. return '<meta http-equiv="refresh" content="0;url=/error/9" />'
  1475. else:
  1476. return '<meta http-equiv="refresh" content="0;url=/error/20" />'
  1477. else:
  1478. if(ban == 1):
  1479. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1480. else:
  1481. if(session.get('Now') == True):
  1482. session['Now'] = False
  1483. session.pop('DREAMER', None)
  1484. return '<meta http-equiv="refresh" content="0;url=/change" />'
  1485. else:
  1486. return web_render('index.html', login = login_check(), title = '비밀번호 변경', enter = '변경', logo = set_data['name'], tn = 15)
  1487. @app.route('/check/<name>')
  1488. def user_check(name = None, sub = None):
  1489. db_ex("select * from user where id = '" + db_pas(name) + "'")
  1490. user = db_get()
  1491. if(user and user[0]['acl'] == 'owner' or user and user[0]['acl'] == 'admin'):
  1492. return '<meta http-equiv="refresh" content="0;url=/error/4" />'
  1493. else:
  1494. if(admin_check() == 1):
  1495. m = re.search('(?:[0-9](?:[0-9][0-9])?\.[0-9](?:[0-9][0-9])?\.[0-9](?:[0-9][0-9])?\.[0-9](?:[0-9][0-9])?)', name)
  1496. if(m):
  1497. db_ex("select * from login where ip = '" + db_pas(name) + "' order by today desc")
  1498. row = db_get()
  1499. if(row):
  1500. i = 0
  1501. c = ''
  1502. while(True):
  1503. try:
  1504. c = c + '<table style="width: 100%;"><tbody><tr><td style="text-align: center;width:33.33%;">' + row[i]['user'] + '</td><td style="text-align: center;width:33.33%;">' + row[i]['ip'] + '</td><td style="text-align: center;width:33.33%;">' + row[i]['today'] + '</td></tr></tbody></table>'
  1505. except:
  1506. break
  1507. i += 1
  1508. return web_render('index.html', login = login_check(), title = '다중 검사', logo = set_data['name'], tn = 22, rows = c)
  1509. else:
  1510. return web_render('index.html', login = login_check(), title = '다중 검사', logo = set_data['name'], tn = 22, rows = '')
  1511. else:
  1512. db_ex("select * from login where user = '" + db_pas(name) + "' order by today desc")
  1513. row = db_get()
  1514. if(row):
  1515. i = 0
  1516. c = ''
  1517. while(True):
  1518. try:
  1519. c = c + '<table style="width: 100%;"><tbody><tr><td style="text-align: center;width:33.33%;">' + row[i]['user'] + '</td><td style="text-align: center;width:33.33%;">' + row[i]['ip'] + '</td><td style="text-align: center;width:33.33%;">' + row[i]['today'] + '</td></tr></tbody></table>'
  1520. except:
  1521. break
  1522. i += 1
  1523. return web_render('index.html', login = login_check(), title = '다중 검사', logo = set_data['name'], tn = 22, rows = c)
  1524. else:
  1525. return web_render('index.html', login = login_check(), title = '다중 검사', logo = set_data['name'], tn = 22, rows = '')
  1526. else:
  1527. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1528. @app.route('/register', methods=['POST', 'GET'])
  1529. def register():
  1530. ip = ip_check()
  1531. ban = ban_check(ip)
  1532. if(request.method == 'POST'):
  1533. if(request.form["pw"] == request.form["pw2"]):
  1534. if(ban == 1):
  1535. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1536. else:
  1537. m = re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.form["id"])
  1538. if(m):
  1539. return '<meta http-equiv="refresh" content="0;url=/error/8" />'
  1540. else:
  1541. if(len(request.form["id"]) > 20):
  1542. return '<meta http-equiv="refresh" content="0;url=/error/7" />'
  1543. else:
  1544. db_ex("select * from user where id = '" + db_pas(request.form["id"]) + "'")
  1545. rows = db_get()
  1546. if(rows):
  1547. return '<meta http-equiv="refresh" content="0;url=/error/6" />'
  1548. else:
  1549. hashed = bcrypt.hashpw(bytes(request.form["pw"], 'utf-8'), bcrypt.gensalt())
  1550. if(request.form["id"] == data['owner']):
  1551. db_ex("insert into user (id, pw, acl) value ('" + db_pas(request.form["id"]) + "', '" + db_pas(hashed.decode()) + "', 'owner')")
  1552. else:
  1553. db_ex("insert into user (id, pw, acl) value ('" + db_pas(request.form["id"]) + "', '" + db_pas(hashed.decode()) + "', 'user')")
  1554. db_com()
  1555. return '<meta http-equiv="refresh" content="0;url=/login" />'
  1556. else:
  1557. return '<meta http-equiv="refresh" content="0;url=/error/20" />'
  1558. else:
  1559. if(ban == 1):
  1560. return '<meta http-equiv="refresh" content="0;url=/ban" />'
  1561. else:
  1562. return web_render('index.html', login = login_check(), title = '회원가입', enter = '회원가입', logo = set_data['name'], tn = 15)
  1563. @app.route('/logout')
  1564. def logout():
  1565. session['Now'] = False
  1566. session.pop('DREAMER', None)
  1567. return '<meta http-equiv="refresh" content="0;url=/user" />'
  1568. @app.route('/ban/<name>', methods=['POST', 'GET'])
  1569. def user_ban(name = None):
  1570. db_ex("select * from user where id = '" + db_pas(name) + "'")
  1571. user = db_get()
  1572. if(user and user[0]['acl'] == 'owner' or user and user[0]['acl'] == 'admin'):
  1573. return '<meta http-equiv="refresh" content="0;url=/error/4" />'
  1574. else:
  1575. if(request.method == 'POST'):
  1576. if(admin_check() == 1):
  1577. ip = ip_check()
  1578. if(not re.search("[0-9]{4}-[0-9]{2}-[0-9]{2}", request.form["end"])):
  1579. end = ''
  1580. else:
  1581. end = request.form["end"]
  1582. db_ex("select * from ban where block = '" + db_pas(name) + "'")
  1583. row = db_get()
  1584. if(row):
  1585. rb_plus(name, '해제', 시간(), ip, '')
  1586. db_ex("delete from ban where block = '" + db_pas(name) + "'")
  1587. else:
  1588. b = re.search("^([0-9](?:[0-9]?[0-9]?)\.[0-9](?:[0-9]?[0-9]?))$", name)
  1589. if(b):
  1590. rb_plus(name, end, 시간(), ip, request.form["why"])
  1591. db_ex("insert into ban (block, end, why, band) value ('" + db_pas(name) + "', '" + db_pas(end) + "', '" + db_pas(request.form["why"]) + "', 'O')")
  1592. else:
  1593. rb_plus(name, end, 시간(), ip, request.form["why"])
  1594. db_ex("insert into ban (block, end, why, band) value ('" + db_pas(name) + "', '" + db_pas(end) + "', '" + db_pas(request.form["why"]) + "', '')")
  1595. db_com()
  1596. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(data['frontpage']) + '" />'
  1597. else:
  1598. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1599. else:
  1600. if(admin_check() == 1):
  1601. db_ex("select * from ban where block = '" + db_pas(name) + "'")
  1602. row = db_get()
  1603. if(row):
  1604. now = '차단 해제'
  1605. else:
  1606. b = re.search("^([0-9](?:[0-9]?[0-9]?)\.[0-9](?:[0-9]?[0-9]?))$", name)
  1607. if(b):
  1608. now = '대역 차단'
  1609. else:
  1610. now = '차단'
  1611. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = set_data['name'], tn = 16, now = now, today = get_time(), sub = '차단')
  1612. else:
  1613. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1614. @app.route('/acl/<path:name>', methods=['POST', 'GET'])
  1615. def acl(name = None):
  1616. if(request.method == 'POST'):
  1617. if(admin_check() == 1):
  1618. db_ex("select * from data where title = '" + db_pas(name) + "'")
  1619. row = db_get()
  1620. if(row):
  1621. if(request.form["select"] == 'admin'):
  1622. db_ex("update data set acl = 'admin' where title = '" + db_pas(name) + "'")
  1623. elif(request.form["select"] == 'user'):
  1624. db_ex("update data set acl = 'user' where title = '" + db_pas(name) + "'")
  1625. else:
  1626. db_ex("update data set acl = '' where title = '" + db_pas(name) + "'")
  1627. db_com()
  1628. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  1629. else:
  1630. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1631. else:
  1632. if(admin_check() == 1):
  1633. db_ex("select * from data where title = '" + db_pas(name) + "'")
  1634. row = db_get()
  1635. if(row):
  1636. if(row[0]['acl'] == 'admin'):
  1637. now = '관리자만'
  1638. elif(row[0]['acl'] == 'user'):
  1639. now = '유저 이상'
  1640. else:
  1641. now = '일반'
  1642. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = set_data['name'], tn = 19, now = '현재 ACL 상태는 ' + now, sub = 'ACL')
  1643. else:
  1644. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(name) + '" />'
  1645. else:
  1646. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1647. @app.route('/admin/<name>', methods=['POST', 'GET'])
  1648. def user_admin(name = None):
  1649. if(request.method == 'POST'):
  1650. if(owner_check() == 1):
  1651. db_ex("select * from user where id = '" + db_pas(name) + "'")
  1652. user = db_get()
  1653. if(user):
  1654. if(user[0]['acl'] == 'admin' or user[0]['acl'] == 'owner'):
  1655. db_ex("update user set acl = 'user' where id = '" + db_pas(name) + "'")
  1656. else:
  1657. db_ex("update user set acl = '" + db_pas(request.form["select"]) + "' where id = '" + db_pas(name) + "'")
  1658. db_com()
  1659. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(data['frontpage']) + '" />'
  1660. else:
  1661. return '<meta http-equiv="refresh" content="0;url=/error/5" />'
  1662. else:
  1663. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1664. else:
  1665. if(owner_check() == 1):
  1666. db_ex("select * from user where id = '" + db_pas(name) + "'")
  1667. user = db_get()
  1668. if(user):
  1669. if(user[0]['acl'] == 'admin' or user[0]['acl'] == 'owner'):
  1670. now = '권한 해제'
  1671. else:
  1672. now = '권한 부여'
  1673. return web_render('index.html', login = login_check(), title = name, page = url_pas(name), logo = data['name'], tn = 18, now = now, sub = '권한 부여')
  1674. else:
  1675. return '<meta http-equiv="refresh" content="0;url=/error/5" />'
  1676. else:
  1677. return '<meta http-equiv="refresh" content="0;url=/error/3" />'
  1678. @app.route('/ban')
  1679. def are_you_ban():
  1680. ip = ip_check()
  1681. if(ban_check(ip) == 1):
  1682. db_ex("select * from ban where block = '" + db_pas(ip) + "'")
  1683. rows = db_get()
  1684. if(rows):
  1685. if(rows[0]['end']):
  1686. end = rows[0]['end'] + ' 까지 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  1687. now = get_time()
  1688. now = re.sub(':', '', now)
  1689. now = re.sub('\-', '', now)
  1690. now = re.sub(' ', '', now)
  1691. now = int(now)
  1692. day = rows[0]['end']
  1693. day = re.sub('\-', '', day)
  1694. if(now >= int(day + '000000')):
  1695. db_ex("delete from ban where block = '" + db_pas(ip) + "'")
  1696. db_com()
  1697. end = '차단이 풀렸습니다. 다시 시도 해 보세요.'
  1698. else:
  1699. end = '영구 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  1700. else:
  1701. b = re.search("^([0-9](?:[0-9]?[0-9]?)\.[0-9](?:[0-9]?[0-9]?))", ip)
  1702. if(b):
  1703. results = b.groups()
  1704. db_ex("select * from ban where block = '" + db_pas(results[0]) + "' and band = 'O'")
  1705. row = db_get()
  1706. if(row):
  1707. if(row[0]['end']):
  1708. end = row[0]['end'] + ' 까지 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  1709. now = get_time()
  1710. now = re.sub(':', '', now)
  1711. now = re.sub('\-', '', now)
  1712. now = re.sub(' ', '', now)
  1713. now = int(now)
  1714. day = row[0]['end']
  1715. day = re.sub('\-', '', day)
  1716. if(now >= int(day + '000000')):
  1717. db_ex("delete from ban where block = '" + db_pas(results[0]) + "' and band = 'O'")
  1718. db_com()
  1719. end = '차단이 풀렸습니다. 다시 시도 해 보세요.'
  1720. else:
  1721. end = '영구 차단 상태 입니다. / 사유 : ' + row[0]['why']
  1722. else:
  1723. end = '권한이 맞지 않는 상태 입니다.'
  1724. return web_render('index.html', login = login_check(), title = '권한 오류', logo = set_data['name'], data = end), 401
  1725. @app.route('/w/<path:name>/r/<int:a>/diff/<int:b>')
  1726. def diff_data(name = None, a = None, b = None):
  1727. db_ex("select * from history where id = '" + db_pas(str(a)) + "' and title = '" + db_pas(name) + "'")
  1728. a_raw_data = db_get()
  1729. if(a_raw_data):
  1730. db_ex("select * from history where id = '" + db_pas(str(b)) + "' and title = '" + db_pas(name) + "'")
  1731. b_raw_data = db_get()
  1732. if(b_raw_data):
  1733. a_data = re.sub('<', '&lt;', a_raw_data[0]['data'])
  1734. a_data = re.sub('>', '&gt;', a_data)
  1735. a_data = re.sub('"', '&quot;', a_data)
  1736. b_data = re.sub('<', '&lt;', b_raw_data[0]['data'])
  1737. b_data = re.sub('>', '&gt;', b_data)
  1738. b_data = re.sub('"', '&quot;', b_data)
  1739. diff_data = difflib.SequenceMatcher(None, a_data, b_data)
  1740. result = diff(diff_data)
  1741. result = '<pre>' + result + '</pre>'
  1742. return web_render('index.html', login = login_check(), title = name, logo = set_data['name'], data = result, sub = '비교')
  1743. else:
  1744. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  1745. else:
  1746. return '<meta http-equiv="refresh" content="0;url=/history/' + url_pas(name) + '" />'
  1747. @app.route('/user')
  1748. def user_info():
  1749. ip = ip_check()
  1750. raw_ip = ip
  1751. db_ex("select * from user where id = '" + db_pas(ip) + "'")
  1752. rows = db_get()
  1753. if(ban_check(ip) == 0):
  1754. if(rows):
  1755. if(rows[0]['acl'] == 'admin' or rows[0]['acl'] == 'owner'):
  1756. if(rows[0]['acl'] == 'admin'):
  1757. acl = '관리자'
  1758. else:
  1759. acl = '소유자'
  1760. else:
  1761. acl = '유저'
  1762. else:
  1763. acl = '일반'
  1764. else:
  1765. acl = '차단'
  1766. ip = ip_pas(ip)
  1767. return web_render('index.html', login = login_check(), title = '유저 메뉴', logo = set_data['name'], data = ip + '<br><br><span>권한 상태 : ' + acl + '<h2>로그인 관련</h2><li><a href="/login">로그인</a></li><li><a href="/logout">로그아웃</a></li><li><a href="/register">회원가입</a></li><h2>기타</h2><li><a href="/change">비밀번호 변경</a></li><li><a href="/count">기여 횟수</a></li><li><a href="/record/' + raw_ip + '/n/1">기여 목록</a></li>')
  1768. @app.route('/count')
  1769. def count_edit():
  1770. db_ex("select count(title) from history where ip = '" + ip_check() + "'")
  1771. i = db_get()
  1772. if(i):
  1773. return web_render('index.html', login = login_check(), title = '기여 횟수', logo = set_data['name'], data = "기여 횟수 : " + str(i[0]["count(title)"]))
  1774. else:
  1775. return web_render('index.html', login = login_check(), title = '기여 횟수', logo = set_data['name'], data = "기여 횟수 : 0")
  1776. @app.route('/random')
  1777. def random():
  1778. db_ex("select * from data order by rand() limit 1")
  1779. rows = db_get()
  1780. if(rows):
  1781. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(rows[0]['title']) + '" />'
  1782. else:
  1783. return '<meta http-equiv="refresh" content="0;url=/" />'
  1784. @app.route('/error/<int:num>')
  1785. def 오류(num = None):
  1786. if(num == 1):
  1787. return web_render('index.html', login = login_check(), title = '권한 오류', logo = set_data['name'], data = '비 로그인 상태 입니다.'), 401
  1788. elif(num == 2):
  1789. return web_render('index.html', login = login_check(), title = '권한 오류', logo = set_data['name'], data = '이 계정이 없습니다.'), 401
  1790. elif(num == 3):
  1791. return web_render('index.html', login = login_check(), title = '권한 오류', logo = set_data['name'], data = '권한이 모자랍니다.'), 401
  1792. elif(num == 4):
  1793. return web_render('index.html', login = login_check(), title = '권한 오류', logo = set_data['name'], data = '관리자는 차단, 검사 할 수 없습니다.'), 401
  1794. elif(num == 5):
  1795. return web_render('index.html', login = login_check(), title = '유저 오류', logo = set_data['name'], data = '그런 계정이 없습니다.'), 401
  1796. elif(num == 6):
  1797. return web_render('index.html', login = login_check(), title = '가입 오류', logo = set_data['name'], data = '동일한 아이디의 유저가 있습니다.'), 401
  1798. elif(num == 7):
  1799. return web_render('index.html', login = login_check(), title = '가입 오류', logo = set_data['name'], data = '아이디는 20글자보다 짧아야 합니다.'), 401
  1800. elif(num == 8):
  1801. return web_render('index.html', login = login_check(), title = '가입 오류', logo = set_data['name'], data = '아이디에는 한글과 알파벳과 공백만 허용 됩니다.'), 401
  1802. elif(num == 9):
  1803. return web_render('index.html', login = login_check(), title = '변경 오류', logo = set_data['name'], data = '그런 계정이 없습니다.'), 401
  1804. elif(num == 10):
  1805. return web_render('index.html', login = login_check(), title = '변경 오류', logo = set_data['name'], data = '비밀번호가 다릅니다.'), 401
  1806. elif(num == 11):
  1807. return web_render('index.html', login = login_check(), title = '로그인 오류', logo = set_data['name'], data = '이미 로그인 되어 있습니다.'), 401
  1808. elif(num == 12):
  1809. return web_render('index.html', login = login_check(), title = '로그인 오류', logo = set_data['name'], data = '그런 계정이 없습니다.'), 401
  1810. elif(num == 13):
  1811. return web_render('index.html', login = login_check(), title = '로그인 오류', logo = set_data['name'], data = '비밀번호가 다릅니다.'), 401
  1812. elif(num == 14):
  1813. return web_render('index.html', login = login_check(), title = '업로드 오류', logo = set_data['name'], data = 'jpg, gif, jpeg, png만 가능 합니다.'), 401
  1814. elif(num == 15):
  1815. return web_render('index.html', login = login_check(), title = '업로드 오류', logo = set_data['name'], data = '파일 명에 . / \ * < > | : ? 가 들어 갈 수 없습니다.'), 401
  1816. elif(num == 16):
  1817. return web_render('index.html', login = login_check(), title = '업로드 오류', logo = set_data['name'], data = '동일한 이름의 파일이 있습니다.'), 401
  1818. elif(num == 17):
  1819. return web_render('index.html', login = login_check(), title = '편집 오류', logo = set_data['name'], data = '편집 내용 기록에는 한글과 영어와 숫자, 공백만 허용 됩니다.'), 401
  1820. elif(num == 18):
  1821. return web_render('index.html', login = login_check(), title = '편집 오류', logo = set_data['name'], data = '내용이 원래 문서와 동일 합니다.'), 401
  1822. elif(num == 19):
  1823. return web_render('index.html', login = login_check(), title = '이동 오류', logo = set_data['name'], data = '이동 하려는 곳에 문서가 이미 있습니다.'), 401
  1824. elif(num == 20):
  1825. return web_render('index.html', login = login_check(), title = '비밀번호 오류', logo = set_data['name'], data = '재 확인이랑 비밀번호가 다릅니다.'), 401
  1826. else:
  1827. return '<meta http-equiv="refresh" content="0;url=/" />'
  1828. @app.errorhandler(404)
  1829. def uncaughtError(error):
  1830. return '<meta http-equiv="refresh" content="0;url=/w/' + url_pas(set_data['frontpage']) + '" />'
  1831. @app.errorhandler(413)
  1832. def uncaughtError(error):
  1833. app.config['MAX_CONTENT_LENGTH'] = (1024**3)
  1834. return error, 401
  1835. if(__name__ == '__main__'):
  1836. app.run(host = '0.0.0.0', port = int(set_data['port']))