app.py 146 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602
  1. ๏ปฟfrom flask import Flask, request, send_from_directory
  2. from flask_reggie import Reggie
  3. from tornado.wsgi import WSGIContainer
  4. from tornado.httpserver import HTTPServer
  5. from tornado.ioloop import IOLoop
  6. import bcrypt
  7. import difflib
  8. import shutil
  9. import threading
  10. import logging
  11. import random
  12. import sys
  13. logging.basicConfig(level = logging.ERROR)
  14. app = Flask(__name__)
  15. Reggie(app)
  16. r_ver = 'v2.6.5 Beta'
  17. print('Version : ' + r_ver)
  18. from func import *
  19. from set_mark.mid_pas import mid_pas
  20. from set_mark.macro import savemark
  21. # set.json ์„ค์ • ํ™•์ธ
  22. try:
  23. json_data = open('set.json').read()
  24. set_data = json.loads(json_data)
  25. except:
  26. while 1:
  27. print('DB Name : ', end = '')
  28. new_json = str(input())
  29. if new_json != '':
  30. with open("set.json", "w") as f:
  31. f.write('{ "db" : "' + new_json + '" }')
  32. json_data = open('set.json').read()
  33. set_data = json.loads(json_data)
  34. break
  35. else:
  36. print('Insert Values')
  37. pass
  38. # ๋””๋น„ ์—ฐ๊ฒฐ
  39. conn = sqlite3.connect(set_data['db'] + '.db', check_same_thread = False)
  40. curs = conn.cursor()
  41. # ์Šคํ‚จ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ถ€๋ถ„
  42. skin_check(conn)
  43. # ์…‹์—… ๋ถ€๋ถ„
  44. curs.execute("create table if not exists data(title text, data text)")
  45. curs.execute("create table if not exists history(id text, title text, data text, date text, ip text, send text, leng text, hide text)")
  46. curs.execute("create table if not exists rd(title text, sub text, date text)")
  47. curs.execute("create table if not exists user(id text, pw text, acl text, date text)")
  48. curs.execute("create table if not exists ban(block text, end text, why text, band text)")
  49. curs.execute("create table if not exists topic(id text, title text, sub text, data text, date text, ip text, block text, top text)")
  50. curs.execute("create table if not exists stop(title text, sub text, close text)")
  51. curs.execute("create table if not exists rb(block text, end text, today text, blocker text, why text)")
  52. curs.execute("create table if not exists back(title text, link text, type text)")
  53. curs.execute("create table if not exists agreedis(title text, sub text)")
  54. curs.execute("create table if not exists custom(user text, css text)")
  55. curs.execute("create table if not exists other(name text, data text)")
  56. curs.execute("create table if not exists alist(name text, acl text)")
  57. curs.execute("create table if not exists re_admin(who text, what text, time text)")
  58. curs.execute("create table if not exists alarm(name text, data text, date text)")
  59. curs.execute("create table if not exists ua_d(name text, ip text, ua text, today text, sub text)")
  60. curs.execute("create table if not exists filter(name text, regex text, sub text)")
  61. curs.execute("create table if not exists scan(user text, title text)")
  62. curs.execute("create table if not exists acl(title text, dec text, dis text, why text)")
  63. curs.execute("create table if not exists inter(title text, link text)")
  64. curs.execute("select name from alist where acl = 'owner'")
  65. if not curs.fetchall():
  66. curs.execute("delete from alist where name = 'owner'")
  67. curs.execute("insert into alist (name, acl) values ('owner', 'owner')")
  68. curs.execute("select data from other where name = 'port'")
  69. rep_data = curs.fetchall()
  70. if not rep_data:
  71. while 1:
  72. print('Port : ', end = '')
  73. rep_port = int(input())
  74. if rep_port:
  75. curs.execute("insert into other (name, data) values ('port', ?)", [rep_port])
  76. break
  77. else:
  78. pass
  79. else:
  80. rep_port = rep_data[0][0]
  81. print('Port : ' + str(rep_port))
  82. curs.execute("select data from other where name = 'key'")
  83. rep_data = curs.fetchall()
  84. if not rep_data:
  85. while 1:
  86. print('Secret Key : ', end = '')
  87. rep_key = str(input())
  88. if rep_key:
  89. curs.execute("insert into other (name, data) values ('key', ?)", [rep_key])
  90. break
  91. else:
  92. pass
  93. else:
  94. rep_key = rep_data[0][0]
  95. print('Secret Key : ' + rep_key)
  96. print('')
  97. # ํ˜ธํ™˜์„ฑ ์„ค์ •
  98. curs.execute("drop table if exists move")
  99. try:
  100. curs.execute("alter table history add hide text default ''")
  101. curs.execute('select title, re from hidhi')
  102. for rep in curs.fetchall():
  103. curs.execute("update history set hide = 'O' where title = ? and id = ?", [rep[0], rep[1]])
  104. curs.execute("drop table if exists hidhi")
  105. except:
  106. pass
  107. try:
  108. curs.execute("alter table user add date text default ''")
  109. except:
  110. pass
  111. try:
  112. curs.execute("alter table rb add band text default ''")
  113. except:
  114. pass
  115. try:
  116. curs.execute("alter table ban add login text default ''")
  117. except:
  118. pass
  119. try:
  120. curs.execute("select title, acl from data where acl != ''")
  121. for rep in curs.fetchall():
  122. curs.execute("insert into acl (title, dec, dis, why) values (?, ?, '', '')", [rep[0], rep[1]])
  123. curs.execute("alter table data drop acl")
  124. except:
  125. pass
  126. try:
  127. curs.execute("select data from other where name = 'robot'")
  128. robot_test = curs.fetchall()
  129. if robot_test:
  130. fw_test = open('./robots.txt', 'w')
  131. fw_test.write(re.sub('\r\n', '\n', robot_test[0][0]))
  132. fw_test.close()
  133. except:
  134. pass
  135. try:
  136. curs.execute("alter table user add email text default ''")
  137. except:
  138. pass
  139. conn.commit()
  140. # ์ด๋ฏธ์ง€ ํด๋” ์ƒ์„ฑ
  141. if not os.path.exists('image'):
  142. os.makedirs('image')
  143. # ์Šคํ‚จ ํด๋” ์ƒ์„ฑ
  144. if not os.path.exists('views'):
  145. os.makedirs('views')
  146. # ๋ฐฑ์—… ์„ค์ •
  147. def back_up():
  148. try:
  149. shutil.copyfile(set_data['db'] + '.db', 'back_' + set_data['db'] + '.db')
  150. print('Back Up Ok')
  151. except:
  152. print('Back Up Error')
  153. threading.Timer(60 * 60 * back_time, back_up).start()
  154. try:
  155. curs.execute('select data from other where name = "back_up"')
  156. back_up_time = curs.fetchall()
  157. back_time = int(back_up_time[0][0])
  158. except:
  159. back_time = 0
  160. # ๋ฐฑ์—… ์—ฌ๋ถ€ ํ™•์ธ
  161. if back_time != 0:
  162. print(str(back_time) + ' Hours Back Up')
  163. if __name__ == '__main__':
  164. back_up()
  165. else:
  166. print('No Back Up')
  167. @app.route('/del_alarm')
  168. def del_alarm():
  169. curs.execute("delete from alarm where name = ?", [ip_check()])
  170. conn.commit()
  171. return redirect('/alarm')
  172. @app.route('/alarm')
  173. def alarm():
  174. ip = ip_check()
  175. if custom(conn)[2] == 0:
  176. return redirect('/login')
  177. da = '<ul>'
  178. curs.execute("select data, date from alarm where name = ? order by date desc", [ip])
  179. dt = curs.fetchall()
  180. if dt:
  181. da = '<a href="/del_alarm">(๋ชจ๋‘ ์‚ญ์ œ)</a><hr>' + da
  182. for do in dt:
  183. da += '<li>' + do[0] + ' / ' + do[1] + '</li>'
  184. else:
  185. da += '<li>์•Œ๋ฆผ์ด ์—†์Šต๋‹ˆ๋‹ค.</li>'
  186. da += '</ul>'
  187. return html_minify(template('index',
  188. imp = ['์•Œ๋ฆผ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  189. data = da,
  190. menu = [['user', '์‚ฌ์šฉ์ž']]
  191. ))
  192. @app.route('/inter_wiki')
  193. def inter_wiki():
  194. div = ''
  195. admin = admin_check(conn, None, None)
  196. curs.execute('select title, link from inter')
  197. db_data = curs.fetchall()
  198. if db_data:
  199. div = '<ul>'
  200. for data in db_data:
  201. div += '<li>' + data[0] + ' : ' + data[1]
  202. if admin == 1:
  203. div += ' <a href="/del_inter/' + url_pas(data[0]) + '">(์‚ญ์ œ)</a>'
  204. div += '</li>'
  205. div += '</ul>'
  206. if admin == 1:
  207. div += '<hr><a href="/plus_inter">(์ถ”๊ฐ€)</a>'
  208. else:
  209. if admin == 1:
  210. div += '<a href="/plus_inter">(์ถ”๊ฐ€)</a>'
  211. return html_minify(template('index',
  212. imp = ['์ธํ„ฐ์œ„ํ‚ค ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  213. data = div,
  214. menu = [['other', '๊ธฐํƒ€']]
  215. ))
  216. @app.route('/del_inter/<name>')
  217. def del_inter(name = None):
  218. if admin_check(conn, None, None) == 1:
  219. curs.execute("delete from inter where title = ?", [name])
  220. conn.commit()
  221. return redirect('/inter_wiki')
  222. else:
  223. return re_error(conn, '/error/3')
  224. @app.route('/plus_inter', methods=['POST', 'GET'])
  225. def plus_inter():
  226. if request.method == 'POST':
  227. curs.execute('insert into inter (title, link) values (?, ?)', [request.form['title'], request.form['link']])
  228. conn.commit()
  229. admin_check(conn, None, 'inter_wiki_plus')
  230. return redirect('/inter_wiki')
  231. else:
  232. return html_minify(template('index',
  233. imp = ['์ธํ„ฐ์œ„ํ‚ค ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  234. data = '<form method="post"> \
  235. <input placeholder="์ด๋ฆ„" type="text" name="title"><hr> \
  236. <input placeholder="๋งํฌ" type="text" name="link"><hr> \
  237. <button type="submit">์ถ”๊ฐ€</button> \
  238. </form>',
  239. menu = [['other', '๊ธฐํƒ€']]
  240. ))
  241. @app.route('/edit_set')
  242. @app.route('/edit_set/<int:num>', methods=['POST', 'GET'])
  243. def edit_set(num = 0):
  244. if num != 0 and admin_check(conn, None, None) != 1:
  245. return re_error(conn, '/ban')
  246. if num == 0:
  247. li_list = ['๊ธฐ๋ณธ ์„ค์ •', '๋ฌธ๊ตฌ ๊ด€๋ จ', '์ „์—ญ HEAD', 'robots.txt', '๊ตฌ๊ธ€ ๊ด€๋ จ']
  248. x = 0
  249. li_data = ''
  250. for li in li_list:
  251. x += 1
  252. li_data += ' * [[wiki:edit_set/' + str(x) + '|' + li + ']]\r\n'
  253. return html_minify(template('index',
  254. imp = ['์„ค์ • ํŽธ์ง‘', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  255. data = namumark(conn, '', '[๋ชฉ์ฐจ(์—†์Œ)]\r\n' + \
  256. '== ๋ฉ”๋‰ด ==\r\n' + \
  257. li_data, 0, 0, 0),
  258. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  259. ))
  260. elif num == 1:
  261. i_list = ['name', 'logo', 'frontpage', 'license', 'upload', 'skin', 'edit', 'reg', 'ip_view', 'back_up', 'all_title']
  262. n_list = ['๋ฌด๋ช…์œ„ํ‚ค', '', '์œ„ํ‚ค:๋Œ€๋ฌธ', 'CC 0', '2', '', 'normal', '', '', '0', '']
  263. if request.method == 'POST':
  264. i = 0
  265. for data in i_list:
  266. curs.execute("update other set data = ? where name = ?", [request.form.get(data, n_list[i]), data])
  267. i += 1
  268. conn.commit()
  269. admin_check(conn, None, 'edit_set')
  270. return redirect('/edit_set/1')
  271. else:
  272. d_list = []
  273. x = 0
  274. for i in i_list:
  275. curs.execute('select data from other where name = ?', [i])
  276. sql_d = curs.fetchall()
  277. if sql_d:
  278. d_list += [sql_d[0][0]]
  279. else:
  280. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  281. d_list += [n_list[x]]
  282. x += 1
  283. conn.commit()
  284. div = ''
  285. if d_list[6] == 'login':
  286. div += '<option value="login">๊ฐ€์ž…์ž</option>'
  287. div += '<option value="normal">์ผ๋ฐ˜</option>'
  288. div += '<option value="admin">๊ด€๋ฆฌ์ž</option>'
  289. elif d_list[6] == 'admin':
  290. div += '<option value="admin">๊ด€๋ฆฌ์ž</option>'
  291. div += '<option value="login">๊ฐ€์ž…์ž</option>'
  292. div += '<option value="normal">์ผ๋ฐ˜</option>'
  293. else:
  294. div += '<option value="normal">์ผ๋ฐ˜</option>'
  295. div += '<option value="admin">๊ด€๋ฆฌ์ž</option>'
  296. div += '<option value="login">๊ฐ€์ž…์ž</option>'
  297. ch_1 = ''
  298. ch_2 = ''
  299. ch_3 = ''
  300. if d_list[7]:
  301. ch_1 = 'checked="checked"'
  302. if d_list[8]:
  303. ch_2 = 'checked="checked"'
  304. if d_list[10]:
  305. ch_3 = 'checked="checked"'
  306. return html_minify(template('index',
  307. imp = ['๊ธฐ๋ณธ ์„ค์ •', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  308. data = '<form method="post"> \
  309. <span>์ด๋ฆ„</span><br><br> \
  310. <input placeholder="์ด๋ฆ„" type="text" name="name" value="' + html.escape(d_list[0]) + '"><hr> \
  311. <span>๋กœ๊ณ  (HTML)</span><br><br> \
  312. <input placeholder="๋กœ๊ณ " type="text" name="logo" value="' + html.escape(d_list[1]) + '"><hr> \
  313. <span>๋Œ€๋ฌธ</span><br><br> \
  314. <input placeholder="๋Œ€๋ฌธ" type="text" name="frontpage" value="' + html.escape(d_list[2]) + '"><hr> \
  315. <span>๋ผ์ด์„ ์Šค (HTML)</span><br><br> \
  316. <input placeholder="๋ผ์ด์„ ์Šค" type="text" name="license" value="' + html.escape(d_list[3]) + '"><hr> \
  317. <span>ํŒŒ์ผ ํฌ๊ธฐ [๋ฉ”๊ฐ€]</span><br><br> \
  318. <input placeholder="ํŒŒ์ผ ํฌ๊ธฐ" type="text" name="upload" value="' + html.escape(d_list[4]) + '"><hr> \
  319. <span>์Šคํ‚จ {์žฌ์‹œ์ž‘ ํ•„์š”}</span><br><br> \
  320. <input placeholder="์Šคํ‚จ" type="text" name="skin" value="' + html.escape(d_list[5]) + '"><hr> \
  321. <span>์ „์—ญ ACL</span><br><br> \
  322. <select name="edit">' + div + '</select><hr> \
  323. <input type="checkbox" name="reg" ' + ch_1 + '> ๊ฐ€์ž…๋ถˆ๊ฐ€<hr> \
  324. <input type="checkbox" name="ip_view" ' + ch_2 + '> ์•„์ดํ”ผ ๋น„๊ณต๊ฐœ<hr> \
  325. <input type="checkbox" name="all_title" ' + ch_3 + '> ๋ชจ๋“  ๋ฌธ์„œ ๋ณด๊ธฐ ๋น„ํ™œ์„ฑํ™”<hr> \
  326. <span>๋ฐฑ์—… ๊ฐ„๊ฒฉ [์‹œ๊ฐ„] (๋„๊ธฐ : 0) {์žฌ์‹œ์ž‘ ํ•„์š”}</span><hr> \
  327. <input placeholder="๋ฐฑ์—… ๊ฐ„๊ฒฉ" type="text" name="back_up" value="' + html.escape(d_list[9]) + '"><hr> \
  328. <button id="save" type="submit">์ €์žฅ</button> \
  329. </form>',
  330. menu = [['edit_set', '์„ค์ •']]
  331. ))
  332. elif num == 2:
  333. if request.method == 'POST':
  334. curs.execute("update other set data = ? where name = ?", [request.form['contract'], 'contract'])
  335. curs.execute("update other set data = ? where name = ?", [request.form['no_login_warring'], 'no_login_warring'])
  336. conn.commit()
  337. admin_check(conn, None, 'edit_set')
  338. return redirect('/edit_set/2')
  339. else:
  340. i_list = ['contract', 'no_login_warring']
  341. n_list = ['', '']
  342. d_list = []
  343. x = 0
  344. for i in i_list:
  345. curs.execute('select data from other where name = ?', [i])
  346. sql_d = curs.fetchall()
  347. if sql_d:
  348. d_list += [sql_d[0][0]]
  349. else:
  350. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  351. d_list += [n_list[x]]
  352. x += 1
  353. conn.commit()
  354. return html_minify(template('index',
  355. imp = ['๋ฌธ๊ตฌ ๊ด€๋ จ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  356. data = '<form method="post"> \
  357. <span>๊ฐ€์ž… ์•ฝ๊ด€</span><br><br> \
  358. <input placeholder="๊ฐ€์ž… ์•ฝ๊ด€" type="text" name="contract" value="' + html.escape(d_list[0]) + '"><hr> \
  359. <span>๋น„ ๋กœ๊ทธ์ธ ๊ฒฝ๊ณ </span><br><br> \
  360. <input placeholder="๋น„ ๋กœ๊ทธ์ธ ๊ฒฝ๊ณ " type="text" name="no_login_warring" value="' + html.escape(d_list[1]) + '"><hr> \
  361. <button id="save" type="submit">์ €์žฅ</button> \
  362. </form>',
  363. menu = [['edit_set', '์„ค์ •']]
  364. ))
  365. elif num == 3:
  366. if request.method == 'POST':
  367. curs.execute("select name from other where name = 'head'")
  368. if curs.fetchall():
  369. curs.execute("update other set data = ? where name = 'head'", [request.form['content']])
  370. else:
  371. curs.execute("insert into other (name, data) values ('head', ?)", [request.form['content']])
  372. conn.commit()
  373. admin_check(conn, None, 'edit_set')
  374. return redirect('/edit_set/3')
  375. else:
  376. curs.execute("select data from other where name = 'head'")
  377. head = curs.fetchall()
  378. if head:
  379. data = head[0][0]
  380. else:
  381. data = ''
  382. return html_minify(template('index',
  383. imp = ['์ „์—ญ HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  384. data = '<span>&lt;style&gt;CSS&lt;/style&gt;<br>&lt;script&gt;JS&lt;/script&gt;</span><hr> \
  385. <form method="post"> \
  386. <textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr> \
  387. <button id="save" type="submit">์ €์žฅ</button> \
  388. </form>',
  389. menu = [['edit_set', '์„ค์ •']]
  390. ))
  391. elif num == 4:
  392. if request.method == 'POST':
  393. curs.execute("select name from other where name = 'robot'")
  394. if curs.fetchall():
  395. curs.execute("update other set data = ? where name = 'robot'", [request.form['content']])
  396. else:
  397. curs.execute("insert into other (name, data) values ('robot', ?)", [request.form['content']])
  398. conn.commit()
  399. fw = open('./robots.txt', 'w')
  400. fw.write(re.sub('\r\n', '\n', request.form['content']))
  401. fw.close()
  402. admin_check(conn, None, 'edit_set')
  403. return redirect('/edit_set/4')
  404. else:
  405. curs.execute("select data from other where name = 'robot'")
  406. robot = curs.fetchall()
  407. if robot:
  408. data = robot[0][0]
  409. else:
  410. data = ''
  411. f = open('./robots.txt', 'r')
  412. lines = f.readlines()
  413. f.close()
  414. if not data or data == '':
  415. data = ''.join(lines)
  416. return html_minify(template('index',
  417. imp = ['robots.txt', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  418. data = '<a href="/robots.txt">(๋ณด๊ธฐ)</a><hr> \
  419. <form method="post"> \
  420. <textarea rows="25" name="content">' + html.escape(data) + '</textarea><hr> \
  421. <button id="save" type="submit">์ €์žฅ</button> \
  422. </form>',
  423. menu = [['edit_set', '์„ค์ •']]
  424. ))
  425. elif num == 5:
  426. if request.method == 'POST':
  427. curs.execute("update other set data = ? where name = 'recaptcha'", [request.form['recaptcha']])
  428. curs.execute("update other set data = ? where name = 'sec_re'", [request.form['sec_re']])
  429. conn.commit()
  430. admin_check(conn, None, 'edit_set')
  431. return redirect('/edit_set/5')
  432. else:
  433. i_list = ['recaptcha', 'sec_re']
  434. n_list = ['', '']
  435. d_list = []
  436. x = 0
  437. for i in i_list:
  438. curs.execute('select data from other where name = ?', [i])
  439. sql_d = curs.fetchall()
  440. if sql_d:
  441. d_list += [sql_d[0][0]]
  442. else:
  443. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  444. d_list += [n_list[x]]
  445. x += 1
  446. conn.commit()
  447. return html_minify(template('index',
  448. imp = ['๊ตฌ๊ธ€ ๊ด€๋ จ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  449. data = '<form method="post"> \
  450. <span>๋ฆฌ์บก์ฐจ (HTML)</span><br><br> \
  451. <input placeholder="๋ฆฌ์บก์ฐจ (HTML)" type="text" name="recaptcha" value="' + html.escape(d_list[0]) + '"><hr> \
  452. <span>๋ฆฌ์บก์ฐจ (๋น„๋ฐ€ํ‚ค)</span><br><br> \
  453. <input placeholder="๋ฆฌ์บก์ฐจ (๋น„๋ฐ€ํ‚ค)" type="text" name="sec_re" value="' + html.escape(d_list[1]) + '"><hr> \
  454. <button id="save" type="submit">์ €์žฅ</button> \
  455. </form>',
  456. menu = [['edit_set', '์„ค์ •']]
  457. ))
  458. else:
  459. return redirect('/')
  460. @app.route('/not_close_topic')
  461. def not_close_topic():
  462. div = '<ul>'
  463. curs.execute('select title, sub from rd order by date desc')
  464. n_list = curs.fetchall()
  465. for data in n_list:
  466. curs.execute('select * from stop where title = ? and sub = ? and close = "O"', [data[0], data[1]])
  467. is_close = curs.fetchall()
  468. if not is_close:
  469. div += '<li><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[1]) + '">' + data[0] + ' (' + data[1] + ')</a></li>'
  470. div += '</ul>'
  471. return html_minify(template('index',
  472. imp = ['์—ด๋ฆฐ ํ† ๋ก  ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  473. data = div,
  474. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  475. ))
  476. @app.route('/image/<name>')
  477. def image_view(name = None):
  478. if os.path.exists(os.path.join('image', name)):
  479. return send_from_directory('./image', name)
  480. else:
  481. return redirect('/')
  482. @app.route('/acl_list')
  483. def acl_list():
  484. div = '<ul>'
  485. curs.execute("select title, dec from acl where dec = 'admin' or dec = 'user' order by title desc")
  486. list_data = curs.fetchall()
  487. for data in list_data:
  488. if not re.search('^์‚ฌ์šฉ์ž:', data[0]) and not re.search('^ํŒŒ์ผ:', data[0]):
  489. if data[1] == 'admin':
  490. acl = '๊ด€๋ฆฌ์ž'
  491. else:
  492. acl = '๊ฐ€์ž…์ž'
  493. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a> (' + acl + ')</li>'
  494. div += '</ul>'
  495. return html_minify(template('index',
  496. imp = ['ACL ๋ฌธ์„œ ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  497. data = div,
  498. menu = [['other', '๊ธฐํƒ€']]
  499. ))
  500. @app.route('/admin_plus/<name>', methods=['POST', 'GET'])
  501. def admin_plus(name = None):
  502. if request.method == 'POST':
  503. if admin_check(conn, None, 'admin_plus (' + name + ')') != 1:
  504. return re_error(conn, '/error/3')
  505. curs.execute("delete from alist where name = ?", [name])
  506. if request.form.get('ban', 0) != 0:
  507. curs.execute("insert into alist (name, acl) values (?, 'ban')", [name])
  508. if request.form.get('mdel', 0) != 0:
  509. curs.execute("insert into alist (name, acl) values (?, 'mdel')", [name])
  510. if request.form.get('toron', 0) != 0:
  511. curs.execute("insert into alist (name, acl) values (?, 'toron')", [name])
  512. if request.form.get('check', 0) != 0:
  513. curs.execute("insert into alist (name, acl) values (?, 'check')", [name])
  514. if request.form.get('acl', 0) != 0:
  515. curs.execute("insert into alist (name, acl) values (?, 'acl')", [name])
  516. if request.form.get('hidel', 0) != 0:
  517. curs.execute("insert into alist (name, acl) values (?, 'hidel')", [name])
  518. if request.form.get('give', 0) != 0:
  519. curs.execute("insert into alist (name, acl) values (?, 'give')", [name])
  520. if request.form.get('owner', 0) != 0:
  521. curs.execute("insert into alist (name, acl) values (?, 'owner')", [name])
  522. conn.commit()
  523. return redirect('/admin_plus/' + url_pas(name))
  524. else:
  525. curs.execute('select acl from alist where name = ?', [name])
  526. acl_list = curs.fetchall()
  527. data = '<ul>'
  528. exist_list = ['', '', '', '', '', '', '', '']
  529. for go in acl_list:
  530. if go[0] == 'ban':
  531. exist_list[0] = 'checked="checked"'
  532. elif go[0] == 'mdel':
  533. exist_list[1] = 'checked="checked"'
  534. elif go[0] == 'toron':
  535. exist_list[2] = 'checked="checked"'
  536. elif go[0] == 'check':
  537. exist_list[3] = 'checked="checked"'
  538. elif go[0] == 'acl':
  539. exist_list[4] = 'checked="checked"'
  540. elif go[0] == 'hidel':
  541. exist_list[5] = 'checked="checked"'
  542. elif go[0] == 'give':
  543. exist_list[6] = 'checked="checked"'
  544. elif go[0] == 'owner':
  545. exist_list[7] = 'checked="checked"'
  546. if admin_check(conn, None, None) != 1:
  547. state = 'disabled'
  548. else:
  549. state = ''
  550. data += '<li><input type="checkbox" ' + state + ' name="ban" ' + exist_list[0] + '> ์ฐจ๋‹จ</li>'
  551. data += '<li><input type="checkbox" ' + state + ' name="mdel" ' + exist_list[1] + '> ๋งŽ์€ ๋ฌธ์„œ ์‚ญ์ œ</li>'
  552. data += '<li><input type="checkbox" ' + state + ' name="toron" ' + exist_list[2] + '> ํ† ๋ก  ๊ด€๋ฆฌ</li>'
  553. data += '<li><input type="checkbox" ' + state + ' name="check" ' + exist_list[3] + '> ์‚ฌ์šฉ์ž ๊ฒ€์‚ฌ</li>'
  554. data += '<li><input type="checkbox" ' + state + ' name="acl" ' + exist_list[4] + '> ๋ฌธ์„œ ACL</li>'
  555. data += '<li><input type="checkbox" ' + state + ' name="hidel" ' + exist_list[5] + '> ์—ญ์‚ฌ ์ˆจ๊น€</li>'
  556. data += '<li><input type="checkbox" ' + state + ' name="give" ' + exist_list[6] + '> ๊ถŒํ•œ ๋ถ€์—ฌ</li>'
  557. data += '<li><input type="checkbox" ' + state + ' name="owner" ' + exist_list[7] + '> ์†Œ์œ ์ž</li></ul>'
  558. return html_minify(template('index',
  559. imp = ['๊ด€๋ฆฌ ๊ทธ๋ฃน ์ถ”๊ฐ€', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  560. data = '<form method="post">' + data + '<hr><button id="save" ' + state + ' type="submit">์ €์žฅ</button></form>',
  561. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  562. ))
  563. @app.route('/admin_list')
  564. def admin_list():
  565. div = '<ul>'
  566. curs.execute("select id, acl, date from user where not acl = 'user' order by date desc")
  567. user_data = curs.fetchall()
  568. for data in user_data:
  569. name = ip_pas(conn, data[0]) + ' <a href="/admin_plus/' + url_pas(data[1]) + '">(' + data[1] + ')</a>'
  570. if data[2] != '':
  571. name += '(๊ฐ€์ž… : ' + data[2] + ')'
  572. div += '<li>' + name + '</li>'
  573. div += '</ul>'
  574. return html_minify(template('index',
  575. imp = ['๊ด€๋ฆฌ์ž ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  576. data = div,
  577. menu = [['other', '๊ธฐํƒ€']]
  578. ))
  579. @app.route('/hidden/<path:name>')
  580. def history_hidden(name = None):
  581. num = int(request.args.get('num', 0))
  582. if admin_check(conn, 6, 'history_hidden (' + name + '#' + str(num) + ')') == 1:
  583. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  584. if curs.fetchall():
  585. curs.execute("update history set hide = '' where title = ? and id = ?", [name, str(num)])
  586. else:
  587. curs.execute("update history set hide = 'O' where title = ? and id = ?", [name, str(num)])
  588. conn.commit()
  589. return redirect('/history/' + url_pas(name))
  590. @app.route('/user_log')
  591. def user_log():
  592. num = int(request.args.get('num', 1))
  593. if num * 50 > 0:
  594. sql_num = num * 50 - 50
  595. else:
  596. sql_num = 0
  597. list_data = '<ul>'
  598. admin_one = admin_check(conn, 1, None)
  599. curs.execute("select id, date from user order by date desc limit ?, '50'", [str(sql_num)])
  600. user_list = curs.fetchall()
  601. for data in user_list:
  602. if admin_one == 1:
  603. curs.execute("select block from ban where block = ?", [data[0]])
  604. ban_exist = curs.fetchall()
  605. if ban_exist:
  606. ban_button = ' <a href="/ban/' + url_pas(data[0]) + '">(ํ•ด์ œ)</a>'
  607. else:
  608. ban_button = ' <a href="/ban/' + url_pas(data[0]) + '">(์ฐจ๋‹จ)</a>'
  609. else:
  610. ban_button = ''
  611. ip = ip_pas(conn, data[0])
  612. list_data += '<li>' + ip + ban_button
  613. if data[1] != '':
  614. list_data += ' (๊ฐ€์ž… : ' + data[1] + ')'
  615. list_data += '</li>'
  616. if num == 1:
  617. curs.execute("select count(id) from user")
  618. user_count = curs.fetchall()
  619. if user_count:
  620. count = user_count[0][0]
  621. else:
  622. count = 0
  623. list_data += '</ul><hr><ul><li>์ด ์œ„ํ‚ค์—๋Š” ' + str(count) + '๋ช…์˜ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.</li></ul>'
  624. list_data += next_fix('/user_log?num=', num, user_list)
  625. return html_minify(template('index',
  626. imp = ['์‚ฌ์šฉ์ž ๊ฐ€์ž… ๊ธฐ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  627. data = list_data,
  628. menu = [['other', '๊ธฐํƒ€']]
  629. ))
  630. @app.route('/admin_log')
  631. def admin_log():
  632. num = int(request.args.get('num', 1))
  633. if num * 50 > 0:
  634. sql_num = num * 50 - 50
  635. else:
  636. sql_num = 0
  637. list_data = '<ul>'
  638. curs.execute("select who, what, time from re_admin order by time desc limit ?, '50'", [str(sql_num)])
  639. get_list = curs.fetchall()
  640. for data in get_list:
  641. ip = ip_pas(conn, data[0])
  642. list_data += '<li>' + ip + ' / ' + data[1] + ' / ' + data[2] + '</li>'
  643. list_data += '</ul><hr><ul><li>์ฃผ์˜ : ๊ถŒํ•œ ์‚ฌ์šฉ ์•ˆํ•˜๊ณ  ์—ด๋žŒ๋งŒ ํ•ด๋„ ๊ธฐ๋ก๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.</li></ul>'
  644. list_data += next_fix('/admin_log?num=', num, get_list)
  645. return html_minify(template('index',
  646. imp = ['๊ถŒํ•œ ์‚ฌ์šฉ ๊ธฐ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  647. data = list_data,
  648. menu = [['other', '๊ธฐํƒ€']]
  649. ))
  650. @app.route('/give_log')
  651. def give_log():
  652. list_data = '<ul>'
  653. back = ''
  654. curs.execute("select distinct name from alist order by name asc")
  655. get_list = curs.fetchall()
  656. for data in get_list:
  657. if back != data[0]:
  658. back = data[0]
  659. list_data += '<li><a href="/admin_plus/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  660. list_data += '</ul><hr><a href="/manager/8">(์ƒ์„ฑ)</a>'
  661. return html_minify(template('index',
  662. imp = ['๊ด€๋ฆฌ ๊ทธ๋ฃน ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  663. data = list_data,
  664. menu = [['other', '๊ธฐํƒ€']]
  665. ))
  666. @app.route('/indexing')
  667. def indexing():
  668. if admin_check(conn, None, 'indexing') != 1:
  669. return re_error(conn, '/error/3')
  670. print('')
  671. curs.execute("select name from sqlite_master where type = 'index'")
  672. index_data = curs.fetchall()
  673. if index_data:
  674. for delete_index in index_data:
  675. print('Delete : ' + delete_index[0])
  676. sql = 'drop index if exists ' + delete_index[0]
  677. try:
  678. curs.execute(sql)
  679. except:
  680. pass
  681. else:
  682. curs.execute("select name from sqlite_master where type in ('table', 'view') and name not like " + \
  683. "'sqlite_%' union all select name from sqlite_temp_master where type in ('table', 'view') order by 1;")
  684. data = curs.fetchall()
  685. for table in data:
  686. curs.execute('select sql from sqlite_master where name = ?', [table[0]])
  687. cul = curs.fetchall()
  688. r_cul = re.findall('(?:([^ (]*) text)', str(cul[0]))
  689. for n_cul in r_cul:
  690. print('Create : index_' + table[0] + '_' + n_cul)
  691. sql = 'create index index_' + table[0] + '_' + n_cul + ' on ' + table[0] + '(' + n_cul + ')'
  692. try:
  693. curs.execute(sql)
  694. except:
  695. pass
  696. conn.commit()
  697. print('')
  698. return redirect('/')
  699. @app.route('/re_start')
  700. def re_start():
  701. if admin_check(conn, None, 're_start') != 1:
  702. return re_error(conn, '/error/3')
  703. print('')
  704. print('Re Start')
  705. print('')
  706. os.execl(sys.executable, sys.executable, *sys.argv)
  707. @app.route('/xref/<path:name>')
  708. def xref(name = None):
  709. num = int(request.args.get('num', 1))
  710. if num * 50 > 0:
  711. sql_num = num * 50 - 50
  712. else:
  713. sql_num = 0
  714. div = '<ul>'
  715. curs.execute("select link, type from back where title = ? and not type = 'cat' and not type = 'no' order by link asc limit ?, '50'", \
  716. [name, str(sql_num)])
  717. data_list = curs.fetchall()
  718. for data in data_list:
  719. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a>'
  720. if data[1]:
  721. if data[1] == 'include':
  722. side = 'ํฌํ•จ'
  723. elif data[1] == 'file':
  724. side = 'ํŒŒ์ผ'
  725. else:
  726. side = '๋„˜๊ฒจ์ฃผ๊ธฐ'
  727. div += ' (' + side + ')'
  728. div += '</li>'
  729. if re.search('^ํ‹€:', data[0]):
  730. div += '<li><a id="inside" href="/xref/' + url_pas(data[0]) + '">' + data[0] + '</a> (์—ญ๋งํฌ)</li>'
  731. div += '</ul>' + next_fix('/xref/' + url_pas(name) + '?num=', num, data_list)
  732. return html_minify(template('index',
  733. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (์—ญ๋งํฌ)', 0])],
  734. data = div,
  735. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  736. ))
  737. @app.route('/please')
  738. def please():
  739. num = int(request.args.get('num', 1))
  740. if num * 50 > 0:
  741. sql_num = num * 50 - 50
  742. else:
  743. sql_num = 0
  744. div = '<ul>'
  745. var = ''
  746. curs.execute("select distinct title from back where type = 'no' order by title asc limit ?, '50'", [str(sql_num)])
  747. data_list = curs.fetchall()
  748. for data in data_list:
  749. if var != data[0]:
  750. div += '<li><a class="not_thing" href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  751. var = data[0]
  752. div += '</ul>' + next_fix('/please?num=', num, data_list)
  753. return html_minify(template('index',
  754. imp = ['ํ•„์š”ํ•œ ๋ฌธ์„œ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  755. data = div,
  756. menu = [['other', '๊ธฐํƒ€']]
  757. ))
  758. @app.route('/recent_discuss')
  759. @app.route('/recent_discuss/<regex("close"):tools>')
  760. def recent_discuss(tools = 'normal'):
  761. if tools == 'normal' or tools == 'close':
  762. div = ''
  763. if tools == 'normal':
  764. div += '<a href="/recent_discuss/close">(๋‹ซํž˜)</a>'
  765. m_sub = 0
  766. else:
  767. div += '<a href="/recent_discuss">(์—ด๋ฆผ)</a>'
  768. m_sub = ' (๋‹ซํž˜)'
  769. div += '<hr><table style="width: 100%; text-align: center;"><tbody><tr> \
  770. <td style="width: 50%;">ํ† ๋ก ๋ช…</td><td style="width: 50%;">์‹œ๊ฐ„</td></tr>'
  771. else:
  772. return redirect('/')
  773. curs.execute("select title, sub, date from rd order by date desc limit 50")
  774. for data in curs.fetchall():
  775. title = html.escape(data[0])
  776. sub = html.escape(data[1])
  777. close = 0
  778. if tools == 'normal':
  779. curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [data[0], data[1]])
  780. if curs.fetchall():
  781. close = 1
  782. else:
  783. curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [data[0], data[1]])
  784. if not curs.fetchall():
  785. close = 1
  786. if close == 0:
  787. div += '<tr><td><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[1]) + '">' + \
  788. title + '</a> (' + sub + ')</td><td>' + data[2] + '</td></tr>'
  789. else:
  790. div += '</tbody></table>'
  791. return html_minify(template('index',
  792. imp = ['์ตœ๊ทผ ํ† ๋ก ๋‚ด์—ญ', wiki_set(conn, 1), custom(conn), other2([m_sub, 0])],
  793. data = div,
  794. menu = 0
  795. ))
  796. @app.route('/block_log')
  797. @app.route('/block_log/<regex("ip|user|never_end|can_end|end|now"):tool2>')
  798. @app.route('/<regex("block_user|block_admin"):tool>/<name>')
  799. def block_log(name = None, tool = None, tool2 = None):
  800. num = int(request.args.get('num', 1))
  801. if num * 50 > 0:
  802. sql_num = num * 50 - 50
  803. else:
  804. sql_num = 0
  805. div = '<table style="width: 100%; text-align: center;"><tbody><tr><td style="width: 33.3%;">์ฐจ๋‹จ์ž</td>' + \
  806. '<td style="width: 33.3%;">๊ด€๋ฆฌ์ž</td><td style="width: 33.3%;">๊ธฐ๊ฐ„</td></tr>'
  807. data_list = ''
  808. if not name:
  809. if not tool2:
  810. div = '<a href="/manager/11">(์ฐจ๋‹จ์ž)</a> <a href="/manager/12">(๊ด€๋ฆฌ์ž)</a><hr><a href="/block_log/ip">(์•„์ดํ”ผ)</a>' + \
  811. ' <a href="/block_log/user">(๊ฐ€์ž…์ž)</a> <a href="/block_log/never_end">(์˜๊ตฌ)</a> <a href="/block_log/can_end">(๊ธฐ๊ฐ„)</a>' + \
  812. ' <a href="/block_log/end">(ํ•ด์ œ)</a> <a href="/block_log/now">(ํ˜„์žฌ)</a><hr>' + div
  813. sub = 0
  814. menu = [['other', '๊ธฐํƒ€']]
  815. curs.execute("select why, block, blocker, end, today from rb order by today desc limit ?, '50'", [str(sql_num)])
  816. else:
  817. menu = [['block_log', '์ผ๋ฐ˜']]
  818. if tool2 == 'ip':
  819. sub = ' (์•„์ดํ”ผ)'
  820. curs.execute("select why, block, blocker, end, today from rb where (block like ? or block like ?) order by today desc limit ?, '50'", \
  821. ['%.%', '%:%', str(sql_num)])
  822. elif tool2 == 'user':
  823. sub = ' (๊ฐ€์ž…์ž)'
  824. curs.execute("select why, block, blocker, end, today from rb where not (block like ? or block like ?) order by today desc limit ?, '50'", \
  825. ['%.%', '%:%', str(sql_num)])
  826. elif tool2 == 'never_end':
  827. sub = '(์˜๊ตฌ)'
  828. curs.execute("select why, block, blocker, end, today from rb where not end like ? and not end like ? order by today desc limit ?, '50'", \
  829. ['%:%', '%ํ•ด์ œ%', str(sql_num)])
  830. elif tool2 == 'end':
  831. sub = '(ํ•ด์ œ)'
  832. curs.execute("select why, block, blocker, end, today from rb where end = ? order by today desc limit ?, '50'", ['ํ•ด์ œ', str(sql_num)])
  833. elif tool2 == 'now':
  834. sub = '(ํ˜„์žฌ)'
  835. data_list = []
  836. curs.execute("select block from ban limit ?, '50'", [str(sql_num)])
  837. for in_data in curs.fetchall():
  838. curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit 1", [in_data[0]])
  839. data_list = [curs.fetchall()[0]] + data_list
  840. else:
  841. sub = '(๊ธฐ๊ฐ„)'
  842. curs.execute("select why, block, blocker, end, today from rb where end like ? order by today desc limit ?, '50'", ['%\-%', str(sql_num)])
  843. else:
  844. menu = [['block_log', '์ผ๋ฐ˜']]
  845. if tool == 'block_user':
  846. sub = ' (์ฐจ๋‹จ์ž)'
  847. curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit ?, '50'", [name, str(sql_num)])
  848. else:
  849. sub = ' (๊ด€๋ฆฌ์ž)'
  850. curs.execute("select why, block, blocker, end, today from rb where blocker = ? order by today desc limit ?, '50'", [name, str(sql_num)])
  851. if data_list == '':
  852. data_list = curs.fetchall()
  853. for data in data_list:
  854. why = html.escape(data[0])
  855. if why == '':
  856. why = '<br>'
  857. b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data[1])
  858. if b:
  859. ip = data[1] + ' (๋Œ€์—ญ)'
  860. else:
  861. ip = ip_pas(conn, data[1])
  862. if data[3] != '':
  863. end = data[3]
  864. else:
  865. end = '๋ฌด๊ธฐํ•œ'
  866. div += '<tr><td>' + ip + '</td><td>' + ip_pas(conn, data[2]) + '</td><td>์‹œ์ž‘ : ' + data[4] + '<br>๋ : ' + end + '</td></tr>'
  867. div += '<tr><td colspan="3">' + why + '</td></tr>'
  868. div += '</tbody></table>'
  869. if not name:
  870. if not tool2:
  871. div += next_fix('/block_log?num=', num, data_list)
  872. else:
  873. div += next_fix('/block_log/' + url_pas(tool2) + '?num=', num, data_list)
  874. else:
  875. div += next_fix('/' + url_pas(tool) + '/' + url_pas(name) + '?num=', num, data_list)
  876. return html_minify(template('index',
  877. imp = ['์ฐจ๋‹จ ๊ธฐ๋ก', wiki_set(conn, 1), custom(conn), other2([sub, 0])],
  878. data = div,
  879. menu = menu
  880. ))
  881. @app.route('/search', methods=['POST'])
  882. def search():
  883. return redirect('/search/' + url_pas(request.form['search']))
  884. @app.route('/goto', methods=['POST'])
  885. def goto():
  886. curs.execute("select title from data where title = ?", [request.form['search']])
  887. data = curs.fetchall()
  888. if data:
  889. return redirect('/w/' + url_pas(request.form['search']))
  890. else:
  891. return redirect('/search/' + url_pas(request.form['search']))
  892. @app.route('/search/<path:name>')
  893. def deep_search(name = None):
  894. num = int(request.args.get('num', 1))
  895. if num * 50 > 0:
  896. sql_num = num * 50 - 50
  897. else:
  898. sql_num = 0
  899. div = '<ul>'
  900. div_plus = ''
  901. no = 0
  902. start = 2
  903. test = ''
  904. curs.execute("select title from data where title = ?", [name])
  905. if curs.fetchall():
  906. div = '<ul><li>๋ฌธ์„œ๋กœ <a href="/w/' + url_pas(name) + '">๋ฐ”๋กœ๊ฐ€๊ธฐ</a></li></ul><hr><ul>'
  907. else:
  908. div = '<ul><li>๋ฌธ์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. <a class="not_thing" href="/w/' + url_pas(name) + '">๋ฐ”๋กœ๊ฐ€๊ธฐ</a></li></ul><hr><ul>'
  909. curs.execute("select distinct title, case when title like ? then '์ œ๋ชฉ' else '๋‚ด์šฉ' " + \
  910. "end from data where title like ? or data like ? order by case when title like ? " + \
  911. "then 1 else 2 end limit ?, '50'", ['%' + name + '%', '%' + name + '%', '%' + name + '%', '%' + name + '%', str(sql_num)])
  912. all_list = curs.fetchall()
  913. if all_list:
  914. test = all_list[0][1]
  915. for data in all_list:
  916. if data[1] != test:
  917. div_plus += '</ul><hr><ul>'
  918. test = data[1]
  919. div_plus += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a> (' + data[1] + ')</li>'
  920. else:
  921. div += '<li>๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์—†์Œ</li>'
  922. div += div_plus + '</ul>'
  923. div += next_fix('/search/' + url_pas(name) + '?num=', num, all_list)
  924. return html_minify(template('index',
  925. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (๊ฒ€์ƒ‰)', 0])],
  926. data = div,
  927. menu = 0
  928. ))
  929. @app.route('/raw/<path:name>')
  930. @app.route('/topic/<path:name>/sub/<sub_t>/raw/<int:num>')
  931. def raw_view(name = None, sub_t = None, num = None):
  932. v_name = name
  933. sub = ' (์›๋ณธ)'
  934. if not num:
  935. num = request.args.get('num', None)
  936. if num:
  937. num = int(num)
  938. if not sub_t and num:
  939. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  940. hid = curs.fetchall()
  941. if hid and admin_check(conn, 6, None) != 1:
  942. return re_error(conn, '/error/3')
  943. curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
  944. sub += ' (' + str(num) + 'ํŒ)'
  945. menu = [['history/' + url_pas(name), '์—ญ์‚ฌ']]
  946. elif sub_t:
  947. curs.execute("select data from topic where id = ? and title = ? and sub = ? and block = ''", [str(num), name, sub_t])
  948. v_name = 'ํ† ๋ก  ์›๋ณธ'
  949. sub = ' (' + str(num) + '๋ฒˆ)'
  950. menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub_t) + '#' + str(num), 'ํ† ๋ก ']]
  951. else:
  952. curs.execute("select data from data where title = ?", [name])
  953. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  954. data = curs.fetchall()
  955. if data:
  956. p_data = html.escape(data[0][0])
  957. p_data = '<textarea readonly rows="25">' + p_data + '</textarea>'
  958. return html_minify(template('index',
  959. imp = [v_name, wiki_set(conn, 1), custom(conn), other2([sub, 0])],
  960. data = p_data,
  961. menu = menu
  962. ))
  963. else:
  964. return redirect('/w/' + url_pas(name))
  965. @app.route('/revert/<path:name>', methods=['POST', 'GET'])
  966. def revert(name = None):
  967. ip = ip_check()
  968. can = acl_check(conn, name)
  969. today = get_time()
  970. num = int(request.args.get('num', 0))
  971. if request.method == 'POST':
  972. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  973. return re_error(conn, '/error/13')
  974. else:
  975. captcha_post('', conn, 0)
  976. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  977. if curs.fetchall() and admin_check(conn, 6, None) != 1:
  978. return re_error(conn, '/error/3')
  979. if can == 1:
  980. return re_error(conn, '/ban')
  981. curs.execute("delete from back where link = ?", [name])
  982. conn.commit()
  983. curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
  984. data = curs.fetchall()
  985. if(data):
  986. curs.execute("select data from data where title = ?", [name])
  987. d = curs.fetchall()
  988. if d:
  989. leng = leng_check(len(d[0][0]), len(data[0][0]))
  990. curs.execute("update data set data = ? where title = ?", [data[0][0], name])
  991. else:
  992. leng = '+' + str(len(data[0][0]))
  993. curs.execute("insert into data (title, data) values (?, ?)", [name, data[0][0]])
  994. history_plus(conn, name, data[0][0], today, ip, request.form['send'] + ' (' + str(num) + 'ํŒ)', leng)
  995. namumark(conn, name, data[0][0], 1, 0, 0)
  996. conn.commit()
  997. return redirect('/w/' + url_pas(name))
  998. else:
  999. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  1000. hid = curs.fetchall()
  1001. if hid and admin_check(conn, 6, None) != 1:
  1002. return re_error(conn, '/error/3')
  1003. if can == 1:
  1004. return re_error(conn, '/ban')
  1005. curs.execute("select title from history where title = ? and id = ?", [name, str(num)])
  1006. if not curs.fetchall():
  1007. return redirect('/w/' + url_pas(name))
  1008. return html_minify(template('index',
  1009. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (๋˜๋Œ๋ฆฌ๊ธฐ)', 0])],
  1010. data = '<form method="post"> \
  1011. <span>' + request.args.get('num', '0') + 'ํŒ์œผ๋กœ ๋˜๋Œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๊นŒ?</span><hr> \
  1012. ' + ip_warring(conn) + ' \
  1013. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1014. ' + captcha_get(conn) + ' \
  1015. <button type="submit">๋˜๋Œ๋ฆฌ๊ธฐ</button> \
  1016. </form>',
  1017. menu = [['history/' + url_pas(name), '์—ญ์‚ฌ'], ['recent_changes', '์ตœ๊ทผ ๋ณ€๊ฒฝ']]
  1018. ))
  1019. @app.route('/big_delete', methods=['POST', 'GET'])
  1020. def big_delete():
  1021. if admin_check(conn, 2, 'big_delete') != 1:
  1022. return re_error(conn, '/error/3')
  1023. if request.method == 'POST':
  1024. today = get_time()
  1025. ip = ip_check()
  1026. data = request.form['content'] + '\r\n'
  1027. m = re.findall('(.*)\r\n', data)
  1028. for g in m:
  1029. curs.execute("select data from data where title = ?", [g])
  1030. d = curs.fetchall()
  1031. if d:
  1032. curs.execute("delete from back where title = ?", [g])
  1033. leng = '-' + str(len(d[0][0]))
  1034. curs.execute("delete from data where title = ?", [g])
  1035. history_plus(conn, g, '', today, ip, request.form['send'] + ' (๋Œ€๋Ÿ‰ ์‚ญ์ œ)', leng)
  1036. data = re.sub('(.*)\r\n', '', data, 1)
  1037. conn.commit()
  1038. return redirect('/')
  1039. else:
  1040. return html_minify(template('index',
  1041. imp = ['๋งŽ์€ ๋ฌธ์„œ ์‚ญ์ œ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1042. data = '<span>๋ฌธ์„œ๋ช… A<br>๋ฌธ์„œ๋ช… B<br>๋ฌธ์„œ๋ช… C<hr>์ด๋Ÿฐ ์‹์œผ๋กœ ์ ์œผ์„ธ์š”.</span><hr> \
  1043. <form method="post"> \
  1044. <textarea rows="25" name="content"></textarea><hr> \
  1045. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1046. <button type="submit">์‚ญ์ œ</button> \
  1047. </form>',
  1048. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  1049. ))
  1050. @app.route('/edit_filter')
  1051. def edit_filter():
  1052. div = '<ul>'
  1053. curs.execute("select name from filter")
  1054. data = curs.fetchall()
  1055. for data_list in data:
  1056. div += '<li><a href="/edit_filter/' + url_pas(data_list[0]) + '">' + data_list[0] + '</a></li>'
  1057. div += '</ul>'
  1058. div += '<hr><a href="/manager/9">(์ถ”๊ฐ€)</a>'
  1059. return html_minify(template('index',
  1060. imp = ['ํŽธ์ง‘ ํ•„ํ„ฐ ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1061. data = div,
  1062. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  1063. ))
  1064. @app.route('/edit_filter/<name>/delete', methods=['POST', 'GET'])
  1065. def delete_edit_filter(name = None):
  1066. if admin_check(conn, 1, 'edit_filter delete') != 1:
  1067. return re_error('/error/3')
  1068. curs.execute("delete from filter where name = ?", [name])
  1069. conn.commit()
  1070. return redirect('/edit_filter')
  1071. @app.route('/edit_filter/<name>', methods=['POST', 'GET'])
  1072. def set_edit_filter(name = None):
  1073. if request.method == 'POST':
  1074. if admin_check(conn, 1, 'edit_filter edit') != 1:
  1075. return re_error('/error/3')
  1076. if request.form['day'] == '00':
  1077. end = ''
  1078. elif request.form['day'] == '09':
  1079. end = 'X'
  1080. else:
  1081. end = request.form['day'] + ' ' + request.form['hour'] + ':' + request.form['minu']
  1082. curs.execute("select name from filter where name = ?", [name])
  1083. if curs.fetchall():
  1084. curs.execute("update filter set regex = ?, sub = ? where name = ?", [request.form['content'], end, name])
  1085. else:
  1086. curs.execute("insert into filter (name, regex, sub) values (?, ?, ?)", [name, request.form['content'], end])
  1087. conn.commit()
  1088. return redirect('/edit_filter/' + url_pas(name))
  1089. else:
  1090. curs.execute("select regex, sub from filter where name = ?", [name])
  1091. exist = curs.fetchall()
  1092. if exist:
  1093. textarea = exist[0][0]
  1094. match = re.search("^([^ ]+) ([^:]+):([^:]+)$", exist[0][1])
  1095. if match:
  1096. end_data = match.groups()
  1097. else:
  1098. end_data = ['', '', '']
  1099. else:
  1100. textarea = ''
  1101. end_data = ['', '', '']
  1102. if admin_check(conn, 1, None) != 1:
  1103. stat = 'disabled'
  1104. else:
  1105. stat = ''
  1106. day = '<option value="00">์ฐจ๋‹จ X</option>'
  1107. if exist[0][1] == 'X':
  1108. day += '<option value="09" selected>์˜๊ตฌ</option>'
  1109. else:
  1110. day += '<option value="09">์˜๊ตฌ</option>'
  1111. for i in range(0, 32):
  1112. if str(i) == end_data[0]:
  1113. day += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  1114. else:
  1115. day += '<option value="' + str(i) + '">' + str(i) + '</option>'
  1116. hour = ''
  1117. for i in range(0, 24):
  1118. if str(i) == end_data[1]:
  1119. hour += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  1120. else:
  1121. hour += '<option value="' + str(i) + '">' + str(i) + '</option>'
  1122. minu = ''
  1123. for i in range(0, 61):
  1124. if str(i) == end_data[2]:
  1125. minu += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  1126. else:
  1127. minu += '<option value="' + str(i) + '">' + str(i) + '</option>'
  1128. data = '<select ' + stat + ' name="day">' + day + '</select> ์ผ '
  1129. data += '<select ' + stat + ' name="hour">' + hour + '</select> ์‹œ '
  1130. data += '<select ' + stat + ' name="minu">' + minu + '</select> ๋ถ„ ๋™์•ˆ<hr>'
  1131. return html_minify(template('index',
  1132. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ํŽธ์ง‘ ํ•„ํ„ฐ)', 0])],
  1133. data = '<form method="post"> \
  1134. ' + data + ' \
  1135. <input ' + stat + ' placeholder="์ •๊ทœ์‹" name="content" value="' + html.escape(textarea) + '" type="text"><hr> \
  1136. <button ' + stat + ' id="save" type="submit">์ €์žฅ</button> \
  1137. </form>',
  1138. menu = [['edit_filter', '๋ชฉ๋ก'], ['edit_filter/' + url_pas(name) + '/delete', '์‚ญ์ œ']]
  1139. ))
  1140. @app.route('/edit/<path:name>', methods=['POST', 'GET'])
  1141. def edit(name = None):
  1142. ip = ip_check()
  1143. can = acl_check(conn, name)
  1144. if can == 1:
  1145. return re_error(conn, '/ban')
  1146. if request.method == 'POST':
  1147. if admin_check(conn, 1, 'edit_filter pass') != 1:
  1148. curs.execute("select regex, sub from filter")
  1149. data = curs.fetchall()
  1150. for data_list in data:
  1151. match = re.compile(data_list[0])
  1152. if match.search(request.form['content']):
  1153. if data_list[1] == 'X':
  1154. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, '')", \
  1155. [ip, '', get_time(), '๋„๊ตฌ:ํŽธ์ง‘ ํ•„ํ„ฐ', 'ํŽธ์ง‘ ํ•„ํ„ฐ์— ์˜ํ•œ ์ฐจ๋‹จ'])
  1156. curs.execute("insert into ban (block, end, why, band, login) values (?, '', ?, '', '')", [ip, 'ํŽธ์ง‘ ํ•„ํ„ฐ์— ์˜ํ•œ ์ฐจ๋‹จ'])
  1157. elif data_list[1] != '':
  1158. match = re.search("^([^ ]+) ([^:]+):([^:]+)$", data_list[1])
  1159. end_data = match.groups()
  1160. match = re.search("^([^-]+)-([^-]+)-([^ ]+) ([^:]+):([^:]+):(.+)$", get_time())
  1161. time_data = match.groups()
  1162. if int(time_data[2]) + int(end_data[0]) > 29:
  1163. month = int(time_data[1]) + 1
  1164. day = int(time_data[2]) + int(end_data[0]) - 30
  1165. if month > 12:
  1166. year = int(time_data[0]) + 1
  1167. month -= 12
  1168. else:
  1169. year = int(time_data[0])
  1170. else:
  1171. month = int(time_data[1])
  1172. day = int(time_data[2]) + int(end_data[0])
  1173. year = int(time_data[0])
  1174. if int(time_data[3]) + int(end_data[1]) > 23:
  1175. day += 1
  1176. hour = int(time_data[3]) + int(end_data[1]) - 24
  1177. else:
  1178. hour = int(time_data[3]) + int(end_data[1])
  1179. if int(time_data[4]) + int(end_data[2]) > 59:
  1180. hour += 1
  1181. minu = int(time_data[4]) + int(end_data[2]) - 60
  1182. else:
  1183. minu = int(time_data[4]) + int(end_data[2])
  1184. time_list = [month, day, hour, minu]
  1185. num = 0
  1186. for time_fix in time_list:
  1187. if not re.search("[0-9]{2}", str(time_fix)):
  1188. time_list[num] = '0' + str(time_fix)
  1189. else:
  1190. time_list[num] = str(time_fix)
  1191. num += 1
  1192. end = str(year) + '-' + time_list[0] + '-' + time_list[1] + ' ' + time_list[2] + ':' + time_list[3] + ':' + time_data[5]
  1193. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, '')", \
  1194. [ip, end, get_time(), '๋„๊ตฌ:ํŽธ์ง‘ ํ•„ํ„ฐ', 'ํŽธ์ง‘ ํ•„ํ„ฐ์— ์˜ํ•œ ์ฐจ๋‹จ'])
  1195. curs.execute("insert into ban (block, end, why, band, login) values (?, ?, ?, '', '')", [ip, end, 'ํŽธ์ง‘ ํ•„ํ„ฐ์— ์˜ํ•œ ์ฐจ๋‹จ'])
  1196. conn.commit()
  1197. return re_error(conn, '/error/21')
  1198. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1199. return re_error(conn, '/error/13')
  1200. else:
  1201. captcha_post('', conn, 0)
  1202. if len(request.form['send']) > 500:
  1203. return re_error(conn, '/error/15')
  1204. if request.form['otent'] == request.form['content']:
  1205. return re_error(conn, '/error/18')
  1206. today = get_time()
  1207. content = savemark(request.form['content'])
  1208. curs.execute("select data from data where title = ?", [name])
  1209. old = curs.fetchall()
  1210. if old:
  1211. if not request.args.get('section', None) and request.form['otent'] != old[0][0]:
  1212. return re_error(conn, '/error/12')
  1213. leng = leng_check(len(request.form['otent']), len(content))
  1214. if request.args.get('section', None):
  1215. content = old[0][0].replace(request.form['otent'], content)
  1216. curs.execute("update data set data = ? where title = ?", [content, name])
  1217. else:
  1218. leng = '+' + str(len(content))
  1219. curs.execute("insert into data (title, data) values (?, ?)", [name, content])
  1220. curs.execute("select user from scan where title = ?", [name])
  1221. for user_data in curs.fetchall():
  1222. curs.execute("insert into alarm (name, data, date) values (?, ?, ?)", \
  1223. [ip, ip + '๋‹˜์ด <a href="/w/' + url_pas(name) + '">' + name + '</a> ๋ฌธ์„œ๋ฅผ ํŽธ์ง‘ ํ–ˆ์Šต๋‹ˆ๋‹ค.', today])
  1224. history_plus(conn, name, content, today, ip, send_p(request.form['send']), leng)
  1225. curs.execute("delete from back where link = ?", [name])
  1226. curs.execute("delete from back where title = ? and type = 'no'", [name])
  1227. namumark(conn, name, content, 1, 0, 0)
  1228. conn.commit()
  1229. return redirect('/w/' + url_pas(name))
  1230. else:
  1231. curs.execute("select data from data where title = ?", [name])
  1232. new = curs.fetchall()
  1233. if new:
  1234. if request.args.get('section', None):
  1235. i = 0
  1236. j = 0
  1237. data = new[0][0] + '\r\n'
  1238. while 1:
  1239. m = re.search("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})" + \
  1240. "\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", data)
  1241. if m:
  1242. if i == int(request.args.get('section', 0)) - 1:
  1243. g = m.groups()
  1244. data = re.sub("\r\n$", "", g[0])
  1245. break
  1246. else:
  1247. data = re.sub("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})" + \
  1248. "\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", "", data, 1)
  1249. i += 1
  1250. else:
  1251. j = 1
  1252. break
  1253. if j == 0:
  1254. data = re.sub("\r\n$", "", data)
  1255. else:
  1256. data = new[0][0]
  1257. else:
  1258. data = ''
  1259. data2 = data
  1260. if not request.args.get('section', None):
  1261. get_name = '<form method="post" id="get_edit" action="/edit_get/' + url_pas(name) + '"> \
  1262. <input placeholder="๋ถˆ๋Ÿฌ ์˜ฌ ๋ฌธ์„œ" name="name" style="width: 50%;" type="text"> \
  1263. <button id="come" type="submit">๋ถˆ๋Ÿฌ์˜ค๊ธฐ</button> \
  1264. </form><hr>'
  1265. action = ''
  1266. else:
  1267. get_name = ''
  1268. action = '?section=' + request.args.get('section', None)
  1269. if request.args.get('froms', None):
  1270. curs.execute("select data from data where title = ?", [request.args.get('froms', None)])
  1271. get_data = curs.fetchall()
  1272. if get_data:
  1273. data = get_data[0][0]
  1274. get_name = ''
  1275. return html_minify(template('index',
  1276. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (์ˆ˜์ •)', 0])],
  1277. data = get_name + ' \
  1278. <form method="post" action="/edit/' + url_pas(name) + action + '"> \
  1279. <textarea rows="25" name="content">' + html.escape(data) + '</textarea> \
  1280. <textarea style="display: none;" name="otent">' + html.escape(data2) + '</textarea><hr> \
  1281. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1282. ' + captcha_get(conn) + ' \
  1283. ' + ip_warring(conn) + ' \
  1284. <button id="save" type="submit">์ €์žฅ</button> \
  1285. <button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">๋ฏธ๋ฆฌ๋ณด๊ธฐ</button> \
  1286. </form>',
  1287. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  1288. ))
  1289. @app.route('/edit_get/<path:name>', methods=['POST'])
  1290. def edit_get(name = None):
  1291. return redirect('/edit/' + url_pas(name) + '?froms=' + url_pas(request.form['name']))
  1292. @app.route('/preview/<path:name>', methods=['POST'])
  1293. def preview(name = None):
  1294. ip = ip_check()
  1295. can = acl_check(conn, name)
  1296. if can == 1:
  1297. return re_error(conn, '/ban')
  1298. newdata = request.form['content']
  1299. newdata = re.sub('^#(?:redirect|๋„˜๊ฒจ์ฃผ๊ธฐ) (?P<in>[^\n]*)', ' * [[\g<in>]] ๋ฌธ์„œ๋กœ ๋„˜๊ฒจ์ฃผ๊ธฐ', newdata)
  1300. enddata = namumark(conn, name, newdata, 0, 0, 1)
  1301. if request.args.get('section', None):
  1302. action = '?section=' + request.args.get('section', None)
  1303. else:
  1304. action = ''
  1305. return html_minify(template('index',
  1306. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (๋ฏธ๋ฆฌ๋ณด๊ธฐ)', 0])],
  1307. data = '<form method="post" action="/edit/' + url_pas(name) + action + '"> \
  1308. <textarea rows="25" name="content">' + html.escape(request.form['content']) + '</textarea> \
  1309. <textarea style="display: none;" name="otent">' + html.escape(request.form['otent']) + '</textarea><hr> \
  1310. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1311. ' + captcha_get(conn) + ' \
  1312. <button id="save" type="submit">์ €์žฅ</button> \
  1313. <button id="preview" type="submit" formaction="/preview/' + url_pas(name) + action + '">๋ฏธ๋ฆฌ๋ณด๊ธฐ</button> \
  1314. </form><hr>' + enddata,
  1315. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  1316. ))
  1317. @app.route('/delete/<path:name>', methods=['POST', 'GET'])
  1318. def delete(name = None):
  1319. ip = ip_check()
  1320. can = acl_check(conn, name)
  1321. if can == 1:
  1322. return re_error(conn, '/ban')
  1323. if request.method == 'POST':
  1324. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1325. return re_error(conn, '/error/13')
  1326. else:
  1327. captcha_post('', conn, 0)
  1328. curs.execute("select data from data where title = ?", [name])
  1329. data = curs.fetchall()
  1330. if data:
  1331. today = get_time()
  1332. leng = '-' + str(len(data[0][0]))
  1333. history_plus(conn, name, '', today, ip, request.form['send'] + ' (์‚ญ์ œ)', leng)
  1334. curs.execute("select title, link from back where title = ? and not type = 'cat' and not type = 'no'", [name])
  1335. for data in curs.fetchall():
  1336. curs.execute("insert into back (title, link, type) values (?, ?, 'no')", [data[0], data[1]])
  1337. curs.execute("delete from back where link = ?", [name])
  1338. curs.execute("delete from data where title = ?", [name])
  1339. conn.commit()
  1340. return redirect('/w/' + url_pas(name))
  1341. else:
  1342. curs.execute("select title from data where title = ?", [name])
  1343. if not curs.fetchall():
  1344. return redirect('/w/' + url_pas(name))
  1345. return html_minify(template('index',
  1346. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (์‚ญ์ œ)', 0])],
  1347. data = '<form method="post"> \
  1348. ' + ip_warring(conn) + ' \
  1349. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1350. ' + captcha_get(conn) + ' \
  1351. <button type="submit">์‚ญ์ œ</button> \
  1352. </form>',
  1353. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  1354. ))
  1355. @app.route('/move_data/<path:name>')
  1356. def move_data(name = None):
  1357. data = '<ul>'
  1358. curs.execute("select send, date, ip from history where send like ? or send like ? order by date desc", \
  1359. ['%<a href="/w/' + url_pas(name) + '">' + name + '</a> ์ด๋™)%', '%(<a href="/w/' + url_pas(name) + '">' + name + '</a>%'])
  1360. for for_data in curs.fetchall():
  1361. match = re.findall('<a href="\/w\/(?:(?:(?!">).)+)">((?:(?!<\/a>).)+)<\/a>', for_data[0])
  1362. send = re.sub('\([^\)]+\)$', '', for_data[0])
  1363. data += '<li><a href="/move_data/' + url_pas(match[0]) + '">' + match[0] + '</a> - <a href="/move_data/' + url_pas(match[1]) + '">' + match[1] + '</a>'
  1364. if re.search('^( *)+$', send):
  1365. data += ' / ' + for_data[2] + ' / ' + for_data[1] + '</li>'
  1366. else:
  1367. data += ' / ' + for_data[2] + ' / ' + for_data[1] + ' / ' + send + '</li>'
  1368. data += '</ul>'
  1369. return html_minify(template('index',
  1370. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (์ด๋™ ๊ธฐ๋ก)', 0])],
  1371. data = data,
  1372. menu = [['history/' + url_pas(name), '์—ญ์‚ฌ']]
  1373. ))
  1374. @app.route('/move/<path:name>', methods=['POST', 'GET'])
  1375. def move(name = None):
  1376. ip = ip_check()
  1377. can = acl_check(conn, name)
  1378. today = get_time()
  1379. if can == 1:
  1380. return re_error(conn, '/ban')
  1381. if request.method == 'POST':
  1382. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1383. return re_error(conn, '/error/13')
  1384. else:
  1385. captcha_post('', conn, 0)
  1386. curs.execute("select title from history where title = ?", [request.form['title']])
  1387. if curs.fetchall():
  1388. return re_error(conn, '/error/19')
  1389. curs.execute("select data from data where title = ?", [name])
  1390. data = curs.fetchall()
  1391. leng = '0'
  1392. if(data):
  1393. curs.execute("update data set title = ? where title = ?", [request.form['title'], name])
  1394. curs.execute("update back set link = ? where link = ?", [request.form['title'], name])
  1395. d = data[0][0]
  1396. else:
  1397. d = ''
  1398. history_plus(conn, name, d, today, ip, request.form['send'] + ' (<a href="/w/' + url_pas(name) + '">' + name + \
  1399. '</a> - <a href="/w/' + url_pas(request.form['title']) + '">' + request.form['title'] + '</a> ์ด๋™)', leng)
  1400. curs.execute("select title, link from back where title = ? and not type = 'cat' and not type = 'no'", [name])
  1401. for data in curs.fetchall():
  1402. curs.execute("insert into back (title, link, type) values (?, ?, 'no')", [data[0], data[1]])
  1403. curs.execute("update history set title = ? where title = ?", [request.form['title'], name])
  1404. conn.commit()
  1405. return redirect('/w/' + url_pas(request.form['title']))
  1406. else:
  1407. return html_minify(template('index',
  1408. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (์ด๋™)', 0])],
  1409. data = '<form method="post"> \
  1410. ' + ip_warring(conn) + ' \
  1411. <input placeholder="๋ฌธ์„œ๋ช…" value="' + name + '" name="title" type="text"><hr> \
  1412. <input placeholder="์‚ฌ์œ " name="send" type="text"><hr> \
  1413. ' + captcha_get(conn) + ' \
  1414. <button type="submit">์ด๋™</button> \
  1415. </form>',
  1416. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  1417. ))
  1418. @app.route('/other')
  1419. def other():
  1420. return html_minify(template('index',
  1421. imp = ['๊ธฐํƒ€ ๋ฉ”๋‰ด', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1422. data = namumark(conn, '', '[๋ชฉ์ฐจ(์—†์Œ)]\r\n' + \
  1423. '== ๊ธฐ๋ก ==\r\n' + \
  1424. ' * [[wiki:block_log|์ฐจ๋‹จ ๊ธฐ๋ก]]\r\n' + \
  1425. ' * [[wiki:user_log|๊ฐ€์ž… ๊ธฐ๋ก]]\r\n' + \
  1426. ' * [[wiki:admin_log|๊ถŒํ•œ ์‚ฌ์šฉ ๊ธฐ๋ก]]\r\n' + \
  1427. ' * [[wiki:manager/6|ํŽธ์ง‘ ๊ธฐ๋ก]]\r\n' + \
  1428. ' * [[wiki:manager/7|ํ† ๋ก  ๊ธฐ๋ก]]\r\n' + \
  1429. '== ๋ชฉ๋ก ==\r\n' + \
  1430. ' * [[wiki:admin_list|๊ด€๋ฆฌ์ž ๋ชฉ๋ก]]\r\n' + \
  1431. ' * [[wiki:give_log|๊ด€๋ฆฌ ๊ทธ๋ฃน ๋ชฉ๋ก]]\r\n' +
  1432. ' * [[wiki:not_close_topic|์—ด๋ฆฐ ํ† ๋ก  ๋ชฉ๋ก]]\r\n' + \
  1433. '== ๊ธฐํƒ€ ==\r\n' + \
  1434. ' * [[wiki:title_index|๋ชจ๋“  ๋ฌธ์„œ]]\r\n' + \
  1435. ' * [[wiki:acl_list|ACL ๋ฌธ์„œ]]\r\n' + \
  1436. ' * [[wiki:please|ํ•„์š”ํ•œ ๋ฌธ์„œ]]\r\n' + \
  1437. ' * [[wiki:upload|ํŒŒ์ผ ์˜ฌ๋ฆฌ๊ธฐ]]\r\n' + \
  1438. ' * [[wiki:manager/10|๋ฌธ์„œ ๊ฒ€์ƒ‰]]\r\n' + \
  1439. '== ๊ด€๋ฆฌ์ž ==\r\n' + \
  1440. ' * [[wiki:manager/1|๊ด€๋ฆฌ์ž ๋ฉ”๋‰ด]]\r\n' + \
  1441. '== ๋ฒ„์ „ ==\r\n' + \
  1442. ' * ์ด ์˜คํ”ˆ๋‚˜๋ฌด๋Š” [[https://github.com/2DU/openNAMU/blob/master/version.md|' + r_ver + ']] ์ž…๋‹ˆ๋‹ค.', 0, 0, 0),
  1443. menu = 0
  1444. ))
  1445. @app.route('/manager', methods=['POST', 'GET'])
  1446. @app.route('/manager/<int:num>', methods=['POST', 'GET'])
  1447. def manager(num = 1):
  1448. title_list = [['๋ฌธ์„œ ACL', '๋ฌธ์„œ๋ช…', 'acl'], ['์‚ฌ์šฉ์ž ๊ฒ€์‚ฌ', 0, 'check'], ['์‚ฌ์šฉ์ž ์ฐจ๋‹จ', 0, 'ban'], ['๊ถŒํ•œ ์ฃผ๊ธฐ', 0, 'admin'], ['ํŽธ์ง‘ ๊ธฐ๋ก', 0, 'record'], ['ํ† ๋ก  ๊ธฐ๋ก', 0, 'topic_record'], ['๊ทธ๋ฃน ์ƒ์„ฑ', '๊ทธ๋ฃน๋ช…', 'admin_plus'], ['ํŽธ์ง‘ ํ•„ํ„ฐ ์ƒ์„ฑ', 'ํ•„ํ„ฐ๋ช…', 'edit_filter'], ['๋ฌธ์„œ ๊ฒ€์ƒ‰', '๋ฌธ์„œ๋ช…', 'search'], ['์ฐจ๋‹จ์ž ๊ฒ€์ƒ‰', 0, 'block_user'], ['๊ด€๋ฆฌ์ž ๊ฒ€์ƒ‰', 0, 'block_admin'], ['์ฃผ์‹œ ๋ฌธ์„œ ์ถ”๊ฐ€', '๋ฌธ์„œ๋ช…', 'watch_list']]
  1449. if num == 1:
  1450. return html_minify(template('index',
  1451. imp = ['๊ด€๋ฆฌ์ž ๋ฉ”๋‰ด', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1452. data = namumark(conn, '', '[๋ชฉ์ฐจ(์—†์Œ)]\r\n' + \
  1453. '== ๋ชฉ๋ก ==\r\n' + \
  1454. ' * [[wiki:manager/2|๋ฌธ์„œ ACL]]\r\n' + \
  1455. ' * [[wiki:manager/3|์‚ฌ์šฉ์ž ๊ฒ€์‚ฌ]]\r\n' + \
  1456. ' * [[wiki:manager/4|์‚ฌ์šฉ์ž ์ฐจ๋‹จ]]\r\n' + \
  1457. ' * [[wiki:manager/5|๊ถŒํ•œ ์ฃผ๊ธฐ]]\r\n' + \
  1458. ' * [[wiki:big_delete|์—ฌ๋Ÿฌ ๋ฌธ์„œ ์‚ญ์ œ]]\r\n' + \
  1459. ' * [[wiki:edit_filter|ํŽธ์ง‘ ํ•„ํ„ฐ]]\r\n' + \
  1460. '== ์†Œ์œ ์ž ==\r\n' + \
  1461. ' * [[wiki:indexing|์ธ๋ฑ์‹ฑ (์ƒ์„ฑ or ์‚ญ์ œ)]]\r\n' + \
  1462. ' * [[wiki:manager/8|๊ด€๋ฆฌ ๊ทธ๋ฃน ์ƒ์„ฑ]]\r\n' + \
  1463. ' * [[wiki:edit_set|์„ค์ • ํŽธ์ง‘]]\r\n' + \
  1464. ' * [[wiki:re_start|์„œ๋ฒ„ ์žฌ ์‹œ์ž‘]]\r\n' + \
  1465. ' * [[wiki:inter_wiki|์ธํ„ฐ์œ„ํ‚ค]]\r\n' + \
  1466. '== ๊ธฐํƒ€ ==\r\n' + \
  1467. ' * ์ด ๋ฉ”๋‰ด์— ์—†๋Š” ๊ธฐ๋Šฅ์€ ํ•ด๋‹น ๋ฌธ์„œ์˜ ์—ญ์‚ฌ๋‚˜ ํ† ๋ก ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ', 0, 0, 0),
  1468. menu = [['other', '๊ธฐํƒ€']]
  1469. ))
  1470. elif num in range(2, 14):
  1471. if request.method == 'POST':
  1472. return redirect('/' + title_list[(num - 2)][2] + '/' + url_pas(request.form['name']))
  1473. else:
  1474. if title_list[(num - 2)][1] == 0:
  1475. placeholder = '์‚ฌ์šฉ์ž๋ช…'
  1476. else:
  1477. placeholder = title_list[(num - 2)][1]
  1478. return html_minify(template('index',
  1479. imp = [title_list[(num - 2)][0], wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1480. data = '<form method="post"> \
  1481. <input placeholder="' + placeholder + '" name="name" type="text"><hr> \
  1482. <button type="submit">์ด๋™</button> \
  1483. </form>',
  1484. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  1485. ))
  1486. else:
  1487. return redirect('/')
  1488. @app.route('/title_index')
  1489. def title_index():
  1490. page = int(request.args.get('page', 1))
  1491. num = int(request.args.get('num', 100))
  1492. if page * num > 0:
  1493. sql_num = page * num - num
  1494. else:
  1495. sql_num = 0
  1496. if num != 0:
  1497. all_list = sql_num + 1
  1498. else:
  1499. all_list = 1
  1500. if num > 1000:
  1501. return re_error(conn, '/error/3')
  1502. data = '<ul><a href="/title_index?num=0">(์ „์ฒด)</a> <a href="/title_index?num=250">(250)</a> <a href="/title_index?num=500">(500)</a> <a href="/title_index?num=1000">(1000)</a>'
  1503. if num == 0:
  1504. curs.execute("select data from other where name = 'all_title'")
  1505. all_title_can = curs.fetchall()
  1506. if all_title_can and all_title_can[0][0] != '':
  1507. return re_error(conn, '/error/3')
  1508. curs.execute("select title from data order by title asc")
  1509. else:
  1510. curs.execute("select title from data order by title asc limit ?, ?", [str(sql_num), str(num)])
  1511. title_list = curs.fetchall()
  1512. if title_list:
  1513. data += '<hr>'
  1514. for list_data in title_list:
  1515. data += '<li>' + str(all_list) + '. <a href="/w/' + url_pas(list_data[0]) + '">' + list_data[0] + '</a></li>'
  1516. all_list += 1
  1517. if page == 1:
  1518. count_end = []
  1519. curs.execute("select count(title) from data")
  1520. count = curs.fetchall()
  1521. if count:
  1522. count_end += [count[0][0]]
  1523. else:
  1524. count_end += [0]
  1525. sql_list = ['ํ‹€:', '๋ถ„๋ฅ˜:', '์‚ฌ์šฉ์ž:', 'ํŒŒ์ผ:']
  1526. for sql in sql_list:
  1527. curs.execute("select count(title) from data where title like ?", [sql + '%'])
  1528. count = curs.fetchall()
  1529. if count:
  1530. count_end += [count[0][0]]
  1531. else:
  1532. count_end += [0]
  1533. count_end += [count_end[0] - count_end[1] - count_end[2] - count_end[3] - count_end[4]]
  1534. data += '</ul><hr><ul><li>์ด ์œ„ํ‚ค์—๋Š” ์ด ' + str(count_end[0]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li></ul><hr><ul>'
  1535. data += '<li>ํ‹€ ๋ฌธ์„œ๋Š” ์ด ' + str(count_end[1]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li>'
  1536. data += '<li>๋ถ„๋ฅ˜ ๋ฌธ์„œ๋Š” ์ด ' + str(count_end[2]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li>'
  1537. data += '<li>์‚ฌ์šฉ์ž ๋ฌธ์„œ๋Š” ์ด ' + str(count_end[3]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li>'
  1538. data += '<li>ํŒŒ์ผ ๋ฌธ์„œ๋Š” ์ด ' + str(count_end[4]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li>'
  1539. data += '<li>๋‚˜๋จธ์ง€ ๋ฌธ์„œ๋Š” ์ด ' + str(count_end[5]) + '๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</li>'
  1540. if num != 0:
  1541. data += '</ul>' + next_fix('/title_index?num=' + str(num) + '&page=', page, title_list, num)
  1542. if ' (' + str(num) + '๊ฐœ)' == ' (0๊ฐœ)':
  1543. sub = 0
  1544. else:
  1545. sub = ' (' + str(num) + '๊ฐœ)'
  1546. return html_minify(template('index',
  1547. imp = ['๋ชจ๋“  ๋ฌธ์„œ', wiki_set(conn, 1), custom(conn), other2([sub, 0])],
  1548. data = data,
  1549. menu = [['other', '๊ธฐํƒ€']]
  1550. ))
  1551. @app.route('/topic/<path:name>/sub/<sub>/b/<int:num>')
  1552. def topic_block(name = None, sub = None, num = None):
  1553. if admin_check(conn, 3, 'blind (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
  1554. return re_error(conn, '/error/3')
  1555. curs.execute("select block from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1556. block = curs.fetchall()
  1557. if block:
  1558. if block[0][0] == 'O':
  1559. curs.execute("update topic set block = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1560. else:
  1561. curs.execute("update topic set block = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1562. rd_plus(conn, name, sub, get_time())
  1563. conn.commit()
  1564. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
  1565. @app.route('/topic/<path:name>/sub/<sub>/notice/<int:num>')
  1566. def topic_top(name = None, sub = None, num = None):
  1567. if admin_check(conn, 3, 'notice (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
  1568. return re_error(conn, '/error/3')
  1569. curs.execute("select * from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1570. topic_data = curs.fetchall()
  1571. if topic_data:
  1572. curs.execute("select top from topic where id = ? and title = ? and sub = ?", [str(num), name, sub])
  1573. top_data = curs.fetchall()
  1574. if top_data:
  1575. if top_data[0][0] == 'O':
  1576. curs.execute("update topic set top = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1577. else:
  1578. curs.execute("update topic set top = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1579. rd_plus(conn, name, sub, get_time())
  1580. conn.commit()
  1581. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
  1582. @app.route('/topic/<path:name>/sub/<sub>/tool/<regex("close|stop|agree"):tool>')
  1583. def topic_stop(name = None, sub = None, tool = None):
  1584. if tool == 'close':
  1585. set_list = ['O', '', 'ํ† ๋ก  ๋‹ซ๊ธฐ', 'ํ† ๋ก  ์—ด๋ฆผ']
  1586. elif tool == 'stop':
  1587. set_list = ['', 'O', 'ํ† ๋ก  ์ •์ง€', 'ํ† ๋ก  ์žฌ๊ฐœ']
  1588. elif tool == 'agree':
  1589. pass
  1590. else:
  1591. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  1592. if admin_check(conn, 3, 'topic ' + tool + ' (' + name + ' - ' + sub + ')') != 1:
  1593. return re_error(conn, '/error/3')
  1594. ip = ip_check()
  1595. time = get_time()
  1596. curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
  1597. topic_check = curs.fetchall()
  1598. if topic_check:
  1599. if tool == 'agree':
  1600. curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub])
  1601. if curs.fetchall():
  1602. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, 'ํ•ฉ์˜ ๊ฒฐ๋ ฌ', ?, ?, '', '1')", \
  1603. [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
  1604. curs.execute("delete from agreedis where title = ? and sub = ?", [name, sub])
  1605. else:
  1606. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, 'ํ•ฉ์˜ ์™„๋ฃŒ', ?, ?, '', '1')", \
  1607. [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
  1608. curs.execute("insert into agreedis (title, sub) values (?, ?)", [name, sub])
  1609. else:
  1610. curs.execute("select title from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[0]])
  1611. if curs.fetchall():
  1612. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", \
  1613. [str(int(topic_check[0][0]) + 1), name, sub, set_list[3], time, ip])
  1614. curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[0]])
  1615. else:
  1616. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", \
  1617. [str(int(topic_check[0][0]) + 1), name, sub, set_list[2], time, ip])
  1618. curs.execute("insert into stop (title, sub, close) values (?, ?, ?)", [name, sub, set_list[0]])
  1619. curs.execute("delete from stop where title = ? and sub = ? and close = ?", [name, sub, set_list[1]])
  1620. rd_plus(conn, name, sub, time)
  1621. conn.commit()
  1622. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  1623. @app.route('/topic/<path:name>/sub/<sub>/admin/<int:num>')
  1624. def topic_admin(name = None, sub = None, num = None):
  1625. curs.execute("select block, ip, date from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  1626. data = curs.fetchall()
  1627. if not data:
  1628. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  1629. ban = ''
  1630. if admin_check(conn, 3, None) == 1:
  1631. ban += '== ๊ด€๋ฆฌ ๋„๊ตฌ ==\r\n'
  1632. is_ban = ' * [[wiki:topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(num) + '|'
  1633. if data[0][0] == 'O':
  1634. is_ban += '๊ฐ€๋ฆผ ํ•ด์ œ'
  1635. else:
  1636. is_ban += '๊ฐ€๋ฆผ'
  1637. is_ban += ']]\r\n'
  1638. curs.execute("select id from topic where title = ? and sub = ? and id = ? and top = 'O'", [name, sub, str(num)])
  1639. is_ban += ' * [[wiki:topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(num) + '|'
  1640. if curs.fetchall():
  1641. is_ban += '๊ณต์ง€ ํ•ด์ œ'
  1642. else:
  1643. is_ban += '๊ณต์ง€'
  1644. is_ban += ']]\r\n'
  1645. curs.execute("select end from ban where block = ?", [data[0][1]])
  1646. ban += ' * [[wiki:ban/' + url_pas(data[0][1]) + '|'
  1647. if curs.fetchall():
  1648. ban += '์ฐจ๋‹จ ํ•ด์ œ'
  1649. else:
  1650. ban += '์ฐจ๋‹จ'
  1651. ban += ']]\r\n' + is_ban
  1652. ban += '== ๊ธฐํƒ€ ๋„๊ตฌ ==\r\n'
  1653. ban += ' * [[wiki:topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/raw/' + str(num) + '|์›๋ณธ]]\r\n'
  1654. ban = ' * ์ž‘์„ฑ ์‹œ๊ฐ„ : ' + data[0][2] + '\r\n' + ban
  1655. if re.search('(\.|:)', data[0][1]):
  1656. ban = ' * ์ž‘์„ฑ์ธ : ' + data[0][1] + ' [[wiki:record/' + url_pas(data[0][1]) + '|(๊ธฐ๋ก)]]\r\n' + ban
  1657. else:
  1658. ban = ' * ์ž‘์„ฑ์ธ : [[์‚ฌ์šฉ์ž:' + data[0][1] + '|' + data[0][1] + ']] [[wiki:record/' + url_pas(data[0][1]) + '|(๊ธฐ๋ก)]]\r\n' + ban
  1659. ban = '== ์ •๋ณด ==\r\n' + ban
  1660. ban = '[๋ชฉ์ฐจ(์—†์Œ)]\r\n' + ban
  1661. return html_minify(template('index',
  1662. imp = ['ํ† ๋ก  ๋„๊ตฌ', wiki_set(conn, 1), custom(conn), other2([' (' + str(num) + '๋ฒˆ)', 0])],
  1663. data = namumark(conn, '', ban, 0, 0, 0),
  1664. menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num), 'ํ† ๋ก ']]
  1665. ))
  1666. @app.route('/topic/<path:name>/sub/<sub>', methods=['POST', 'GET'])
  1667. def topic(name = None, sub = None):
  1668. ban = topic_check(conn, name, sub)
  1669. admin = admin_check(conn, 3, None)
  1670. if request.method == 'POST':
  1671. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1672. return re_error(conn, '/error/13')
  1673. else:
  1674. captcha_post('', conn, 0)
  1675. ip = ip_check()
  1676. today = get_time()
  1677. if ban == 1 and admin != 1:
  1678. return re_error(conn, '/ban')
  1679. curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
  1680. old_num = curs.fetchall()
  1681. if old_num:
  1682. num = int(old_num[0][0]) + 1
  1683. else:
  1684. num = 1
  1685. match = re.search('^์‚ฌ์šฉ์ž:([^/]+)', name)
  1686. if match:
  1687. curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [match.groups()[0], ip + '๋‹˜์ด <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '">์‚ฌ์šฉ์ž ํ† ๋ก </a>์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.', today])
  1688. data = re.sub("\[\[(๋ถ„๋ฅ˜:(?:(?:(?!\]\]).)*))\]\]", "[br]", request.form['content'])
  1689. match = re.findall("(?:#([0-9]+))", data)
  1690. for rd_data in match:
  1691. curs.execute("select ip from topic where title = ? and sub = ? and id = ?", [name, sub, rd_data])
  1692. ip_data = curs.fetchall()
  1693. if ip_data and not re.search('(\.|:)', ip_data[0][0]):
  1694. curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [ip_data[0][0], ip + '๋‹˜์ด <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num) + '">ํ† ๋ก </a>์—์„œ ์–ธ๊ธ‰ ํ–ˆ์Šต๋‹ˆ๋‹ค.', today])
  1695. data = re.sub("(?P<in>#(?:[0-9]+))", '[[\g<in>]]', data)
  1696. data = savemark(data)
  1697. rd_plus(conn, name, sub, today)
  1698. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '')", [str(num), name, sub, data, today, ip])
  1699. conn.commit()
  1700. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  1701. else:
  1702. curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, sub])
  1703. close_data = curs.fetchall()
  1704. curs.execute("select title from stop where title = ? and sub = ? and close = ''", [name, sub])
  1705. stop_data = curs.fetchall()
  1706. curs.execute("select id from topic where title = ? and sub = ? limit 1", [name, sub])
  1707. topic_exist = curs.fetchall()
  1708. display = ''
  1709. all_data = ''
  1710. data = ''
  1711. number = 1
  1712. if admin == 1 and topic_exist:
  1713. if close_data:
  1714. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/close">(์—ด๊ธฐ)</a> '
  1715. else:
  1716. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/close">(๋‹ซ๊ธฐ)</a> '
  1717. if stop_data:
  1718. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/stop">(์žฌ๊ฐœ)</a> '
  1719. else:
  1720. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/stop">(์ •์ง€)</a> '
  1721. curs.execute("select title from agreedis where title = ? and sub = ?", [name, sub])
  1722. if curs.fetchall():
  1723. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/agree">(์ทจ์†Œ)</a>'
  1724. else:
  1725. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/agree">(ํ•ฉ์˜)</a>'
  1726. all_data += '<hr>'
  1727. if (close_data or stop_data) and admin != 1:
  1728. display = 'display: none;'
  1729. curs.execute("select data, id, date, ip, block, top from topic where title = ? and sub = ? order by id + 0 asc", [name, sub])
  1730. topic_1 = curs.fetchall()
  1731. curs.execute("select data, id, date, ip from topic where title = ? and sub = ? and top = 'O' order by id + 0 asc", [name, sub])
  1732. topic_2 = curs.fetchall()
  1733. for topic_data in topic_2:
  1734. who_plus = ''
  1735. curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['notice (' + name + ' - ' + sub + '#' + topic_data[1] + ')'])
  1736. topic_data_top = curs.fetchall()
  1737. if topic_data_top:
  1738. who_plus += ' <span style="margin-right: 5px;">@' + topic_data_top[0][0] + ' </span>'
  1739. all_data += '<table id="toron"><tbody><tr><td id="toron_color_red">'
  1740. all_data += '<a href="#' + topic_data[1] + '">#' + topic_data[1] + '</a> ' + ip_pas(conn, topic_data[3]) + who_plus + ' <span style="float: right;">' + topic_data[2] + '</span>'
  1741. all_data += '</td></tr><tr><td>' + namumark(conn, '', topic_data[0], 0, 0, 0) + '</td></tr></tbody></table><br>'
  1742. for topic_data in topic_1:
  1743. if number == 1:
  1744. start = topic_data[3]
  1745. if topic_data[4] == 'O':
  1746. blind_data = 'style="background: gainsboro;"'
  1747. if admin != 1:
  1748. curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['blind (' + name + ' - ' + sub + '#' + str(number) + ')'])
  1749. who_blind = curs.fetchall()
  1750. if who_blind:
  1751. user_write = '[[์‚ฌ์šฉ์ž:' + who_blind[0][0] + ']]๋‹˜์ด ๊ฐ€๋ฆผ'
  1752. else:
  1753. user_write = '๊ด€๋ฆฌ์ž๊ฐ€ ๊ฐ€๋ฆผ'
  1754. else:
  1755. blind_data = ''
  1756. user_write = namumark(conn, '', topic_data[0], 0, 0, 0)
  1757. ip = ip_pas(conn, topic_data[3])
  1758. curs.execute('select acl from user where id = ?', [topic_data[3]])
  1759. user_acl = curs.fetchall()
  1760. if user_acl and user_acl[0][0] != 'user':
  1761. ip += ' <a href="javascript:void(0);" title="๊ด€๋ฆฌ์ž">โ˜…</a>'
  1762. if admin == 1 or blind_data == '':
  1763. ip += ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/admin/' + str(number) + '">(๋„๊ตฌ)</a>'
  1764. curs.execute("select end from ban where block = ?", [topic_data[3]])
  1765. if curs.fetchall():
  1766. ip += ' <a href="javascript:void(0);" title="์ฐจ๋‹จ์ž">โ€ </a>'
  1767. if topic_data[5] == '1':
  1768. color = '_blue'
  1769. elif topic_data[3] == start:
  1770. color = '_green'
  1771. else:
  1772. color = ''
  1773. if user_write == '':
  1774. user_write = '<br>'
  1775. all_data += '<table id="toron"><tbody><tr><td id="toron_color' + color + '">'
  1776. all_data += '<a href="javascript:void(0);" id="' + str(number) + '">#' + str(number) + '</a> ' + ip + '</span>'
  1777. all_data += '</td></tr><tr ' + blind_data + '><td>' + user_write + '</td></tr></tbody></table><br>'
  1778. number += 1
  1779. if ban != 1 or admin == 1:
  1780. data += '<a id="reload" href="javascript:void(0);" onclick="location.href.endsWith(\'#reload\') ? ' + \
  1781. 'location.reload(true) : location.href = \'#reload\'"><i aria-hidden="true" class="fa fa-refresh"></i></a>' + \
  1782. '<form style="' + display + '" method="post"><br><textarea style="height: 100px;" name="content"></textarea><hr>' + captcha_get(conn)
  1783. if display == '':
  1784. data += ip_warring(conn)
  1785. data += '<button type="submit">์ „์†ก</button></form>'
  1786. return html_minify(template('index',
  1787. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ํ† ๋ก )', 0])],
  1788. data = '<h2 id="topic_top_title">' + sub + '</h2><hr id="under_bar" style="margin-top: -5px;">' + all_data + data,
  1789. menu = [['topic/' + url_pas(name), '๋ชฉ๋ก']]
  1790. ))
  1791. @app.route('/topic/<path:name>', methods=['POST', 'GET'])
  1792. @app.route('/topic/<path:name>/<regex("close|agree"):tool>', methods=['GET'])
  1793. def close_topic_list(name = None, tool = None):
  1794. div = ''
  1795. list_d = 0
  1796. if request.method == 'POST':
  1797. t_num = ''
  1798. while 1:
  1799. curs.execute("select title from topic where title = ? and sub = ? limit 1", [name, request.form['topic'] + t_num])
  1800. if curs.fetchall():
  1801. if t_num == '':
  1802. t_num = ' 2'
  1803. else:
  1804. t_num = ' ' + str(int(t_num.replace(' ', '')) + 1)
  1805. else:
  1806. break
  1807. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(request.form['topic'] + t_num))
  1808. else:
  1809. plus = ''
  1810. menu = [['topic/' + url_pas(name), '๋ชฉ๋ก']]
  1811. if tool == 'close':
  1812. curs.execute("select sub from stop where title = ? and close = 'O' order by sub asc", [name])
  1813. sub = '๋‹ซํž˜'
  1814. elif tool == 'agree':
  1815. curs.execute("select sub from agreedis where title = ? order by sub asc", [name])
  1816. sub = 'ํ•ฉ์˜'
  1817. else:
  1818. curs.execute("select sub from rd where title = ? order by date desc", [name])
  1819. sub = 'ํ† ๋ก  ๋ชฉ๋ก'
  1820. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  1821. plus = '<a href="/topic/' + url_pas(name) + '/close">(๋‹ซํž˜)</a> <a href="/topic/' + url_pas(name) + '/agree">(ํ•ฉ์˜)</a><hr> \
  1822. <input placeholder="ํ† ๋ก ๋ช…" class="form-control" name="topic" type="text"><hr> \
  1823. <button type="submit">๋งŒ๋“ค๊ธฐ</button>'
  1824. for data in curs.fetchall():
  1825. curs.execute("select data, date, ip, block from topic where title = ? and sub = ? and id = '1'", [name, data[0]])
  1826. if(curs.fetchall()):
  1827. it_p = 0
  1828. if sub == 'ํ† ๋ก  ๋ชฉ๋ก':
  1829. curs.execute("select title from stop where title = ? and sub = ? and close = 'O' order by sub asc", [name, data[0]])
  1830. close = curs.fetchall()
  1831. if close:
  1832. it_p = 1
  1833. if it_p != 1:
  1834. div += '<h2><a href="/topic/' + url_pas(name) + '/sub/' + url_pas(data[0]) + '">' + data[0] + \
  1835. '</a></h2><hr id="under_bar" style="margin-top: -5px;">'
  1836. if div == '':
  1837. plus = re.sub('^<br>', '', plus)
  1838. return html_minify(template('index',
  1839. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + sub + ')', 0])],
  1840. data = '<form method="post">' + div + plus + '</form>',
  1841. menu = menu
  1842. ))
  1843. @app.route('/login', methods=['POST', 'GET'])
  1844. def login():
  1845. if 'Now' in session and session['Now'] == 1:
  1846. return re_error(conn, '/error/11')
  1847. ip = ip_check()
  1848. agent = request.headers.get('User-Agent')
  1849. curs.execute("select block from ban where block = ? and login = 'O'", [ip])
  1850. if not curs.fetchall():
  1851. ban = ban_check(conn)
  1852. else:
  1853. ban = 0
  1854. if ban == 1:
  1855. return re_error(conn, '/ban')
  1856. if request.method == 'POST':
  1857. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1858. return re_error(conn, '/error/13')
  1859. else:
  1860. captcha_post('', conn, 0)
  1861. curs.execute("select pw from user where id = ?", [request.form['id']])
  1862. user = curs.fetchall()
  1863. if not user:
  1864. return re_error(conn, '/error/5')
  1865. if not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8')):
  1866. return re_error(conn, '/error/10')
  1867. session['Now'] = 1
  1868. session['DREAMER'] = request.form['id']
  1869. curs.execute("select css from custom where user = ?", [request.form['id']])
  1870. css_data = curs.fetchall()
  1871. if css_data:
  1872. session['Daydream'] = css_data[0][0]
  1873. else:
  1874. session['Daydream'] = ''
  1875. curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')", [request.form['id'], ip, agent, get_time()])
  1876. conn.commit()
  1877. return redirect('/user')
  1878. else:
  1879. return html_minify(template('index',
  1880. imp = ['๋กœ๊ทธ์ธ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1881. data = '<form method="post"> \
  1882. <input placeholder="์•„์ด๋””" name="id" type="text"><hr> \
  1883. <input placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ" name="pw" type="password"><hr> \
  1884. ' + captcha_get(conn) + ' \
  1885. <button type="submit">๋กœ๊ทธ์ธ</button><hr> \
  1886. <span>์ฃผ์˜ : ๋งŒ์•ฝ HTTPS ์—ฐ๊ฒฐ์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ฑ…์ž„์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</span> \
  1887. </form>',
  1888. menu = [['user', '์‚ฌ์šฉ์ž']]
  1889. ))
  1890. @app.route('/change', methods=['POST', 'GET'])
  1891. def change_password():
  1892. ban = ban_check(conn)
  1893. if request.method == 'POST':
  1894. if request.form['pw2'] != request.form['pw3']:
  1895. return re_error(conn, '/error/20')
  1896. if ban == 1:
  1897. return re_error(conn, '/ban')
  1898. curs.execute("select pw from user where id = ?", [session['DREAMER']])
  1899. user = curs.fetchall()
  1900. if not user:
  1901. return re_error(conn, '/error/10')
  1902. if custom(conn)[2] == 0:
  1903. return redirect('/login')
  1904. if not bcrypt.checkpw(bytes(request.form['pw'], 'utf-8'), bytes(user[0][0], 'utf-8')):
  1905. return re_error(conn, '/error/5')
  1906. hashed = bcrypt.hashpw(bytes(request.form['pw2'], 'utf-8'), bcrypt.gensalt())
  1907. curs.execute("update user set pw = ? where id = ?", [hashed.decode(), session['DREAMER']])
  1908. conn.commit()
  1909. return redirect('/user')
  1910. else:
  1911. if ban == 1:
  1912. return re_error(conn, '/ban')
  1913. if custom(conn)[2] == 0:
  1914. return redirect('/login')
  1915. return html_minify(template('index',
  1916. imp = ['๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1917. data = '<form method="post"> \
  1918. <input placeholder="ํ˜„์žฌ ๋น„๋ฐ€๋ฒˆํ˜ธ" name="pw" type="password"><hr> \
  1919. <input placeholder="๋ณ€๊ฒฝํ•  ๋น„๋ฐ€๋ฒˆํ˜ธ" name="pw2" type="password"><hr> \
  1920. <input placeholder="์žฌ ํ™•์ธ" name="pw3" type="password"><hr> \
  1921. <button type="submit">๋ณ€๊ฒฝ</button><hr> \
  1922. <span>์ฃผ์˜ : ๋งŒ์•ฝ HTTPS ์—ฐ๊ฒฐ์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ฑ…์ž„์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</span> \
  1923. </form>',
  1924. menu = [['user', '์‚ฌ์šฉ์ž']]
  1925. ))
  1926. @app.route('/check/<name>')
  1927. def user_check(name = None):
  1928. if admin_check(conn, 4, 'check (' + name + ')') != 1:
  1929. return re_error(conn, '/error/3')
  1930. curs.execute("select acl from user where id = ? or id = ?", [name, request.args.get('plus', 'None-Data')])
  1931. user = curs.fetchall()
  1932. if user and user[0][0] != 'user':
  1933. if admin_check(conn, None, None) != 1:
  1934. return re_error(conn, '/error/4')
  1935. if request.args.get('plus', None):
  1936. if re.search('(?:\.|:)', name):
  1937. if re.search('(?:\.|:)', request.args.get('plus', None)):
  1938. curs.execute("select name, ip, ua, today from ua_d where ip = ? or ip = ? order by today desc", [name, request.args.get('plus', None)])
  1939. else:
  1940. curs.execute("select name, ip, ua, today from ua_d where ip = ? or name = ? order by today desc", [name, request.args.get('plus', None)])
  1941. else:
  1942. if re.search('(?:\.|:)', request.args.get('plus', None)):
  1943. curs.execute("select name, ip, ua, today from ua_d where name = ? or ip = ? order by today desc", [name, request.args.get('plus', None)])
  1944. else:
  1945. curs.execute("select name, ip, ua, today from ua_d where name = ? or name = ? order by today desc", [name, request.args.get('plus', None)])
  1946. elif re.search('(?:\.|:)', name):
  1947. curs.execute("select name, ip, ua, today from ua_d where ip = ? order by today desc", [name])
  1948. else:
  1949. curs.execute("select name, ip, ua, today from ua_d where name = ? order by today desc", [name])
  1950. record = curs.fetchall()
  1951. if record:
  1952. if not request.args.get('plus', None):
  1953. div = '<a href="/plus_check/' + url_pas(name) + '">(๋น„๊ต)</a><hr>'
  1954. else:
  1955. div = '<a href="/check/' + url_pas(name) + '">(์ฃผ์š” ๋Œ€์ƒ)</a> <a href="/check/' + url_pas(request.args.get('plus', None)) + '">(๋น„๊ต ๋Œ€์ƒ)</a><hr>'
  1956. div += '<table style="width: 100%; text-align: center;"><tbody><tr>'
  1957. div += '<td style="width: 33.3%;">์ด๋ฆ„</td><td style="width: 33.3%;">์•„์ดํ”ผ</td><td style="width: 33.3%;">์–ธ์ œ</td></tr>'
  1958. for data in record:
  1959. if data[2]:
  1960. ua = data[2]
  1961. else:
  1962. ua = '<br>'
  1963. div += '<tr><td>' + ip_pas(conn, data[0]) + '</td><td>' + ip_pas(conn, data[1]) + '</td><td>' + data[3] + '</td></tr>'
  1964. div += '<tr><td colspan="3">' + ua + '</td></tr>'
  1965. div += '</tbody></table>'
  1966. else:
  1967. return re_error(conn, '/error/5')
  1968. return html_minify(template('index',
  1969. imp = ['๋‹ค์ค‘ ๊ฒ€์‚ฌ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1970. data = div,
  1971. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  1972. ))
  1973. @app.route('/plus_check/<name>', methods=['POST', 'GET'])
  1974. def plus_check(name):
  1975. if request.method == 'POST':
  1976. return redirect('/check/' + url_pas(name) + '?plus=' + url_pas(request.form['name2']))
  1977. else:
  1978. return html_minify(template('index',
  1979. imp = ['๋Œ€์ƒ ์ถ”๊ฐ€', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  1980. data = '<form method="post"> \
  1981. <input placeholder="๋น„๊ต ๋Œ€์ƒ" name="name2" type="text"><hr> \
  1982. <button type="submit">์ด๋™</button> \
  1983. </form>',
  1984. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  1985. ))
  1986. @app.route('/register', methods=['POST', 'GET'])
  1987. def register():
  1988. ban = ban_check(conn)
  1989. if ban == 1:
  1990. return re_error(conn, '/ban')
  1991. if not admin_check(conn, None, None) == 1:
  1992. curs.execute('select data from other where name = "reg"')
  1993. set_d = curs.fetchall()
  1994. if set_d and set_d[0][0] == 'on':
  1995. return re_error(conn, '/ban')
  1996. if request.method == 'POST':
  1997. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  1998. return re_error(conn, '/error/13')
  1999. else:
  2000. captcha_post('', conn, 0)
  2001. if request.form['pw'] != request.form['pw2']:
  2002. return re_error(conn, '/error/20')
  2003. if re.search('(?:[^A-Za-zใ„ฑ-ํžฃ0-9 ])', request.form['id']):
  2004. return re_error(conn, '/error/8')
  2005. if len(request.form['id']) > 32:
  2006. return re_error(conn, '/error/7')
  2007. curs.execute("select id from user where id = ?", [request.form['id']])
  2008. if curs.fetchall():
  2009. return re_error(conn, '/error/6')
  2010. hashed = bcrypt.hashpw(bytes(request.form['pw'], 'utf-8'), bcrypt.gensalt())
  2011. curs.execute("select id from user limit 1")
  2012. user_ex = curs.fetchall()
  2013. if not user_ex:
  2014. curs.execute("insert into user (id, pw, acl, date, email) values (?, ?, 'owner', ?, ?)", \
  2015. [request.form['id'], hashed.decode(), get_time(), request.form.get('email', '')])
  2016. else:
  2017. curs.execute("insert into user (id, pw, acl, date, email) values (?, ?, 'user', ?, ?)", \
  2018. [request.form['id'], hashed.decode(), get_time(), request.form.get('email', '')])
  2019. conn.commit()
  2020. return redirect('/login')
  2021. else:
  2022. contract = ''
  2023. curs.execute('select data from other where name = "contract"')
  2024. data = curs.fetchall()
  2025. if data and data[0][0] != '':
  2026. contract = data[0][0] + '<hr>'
  2027. return html_minify(template('index',
  2028. imp = ['ํšŒ์›๊ฐ€์ž…', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2029. data = '<form method="post"> \
  2030. ' + contract + ' \
  2031. <input placeholder="์•„์ด๋””" name="id" type="text"><hr> \
  2032. <input placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ" name="pw" type="password"><hr> \
  2033. <input placeholder="๋‹ค์‹œ" name="pw2" type="password"><hr> \
  2034. <input placeholder="์ด๋ฉ”์ผ (์„ ํƒ)" name="email" type="text"><hr> \
  2035. ' + captcha_get(conn) + ' \
  2036. <button type="submit">๊ฐ€์ž…</button><hr> \
  2037. <span>์ฃผ์˜ : ๋งŒ์•ฝ HTTPS ์—ฐ๊ฒฐ์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ฑ…์ž„์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</span> \
  2038. </form>',
  2039. menu = [['user', '์‚ฌ์šฉ์ž']]
  2040. ))
  2041. @app.route('/logout')
  2042. def logout():
  2043. session['Now'] = 0
  2044. session.pop('DREAMER', None)
  2045. return redirect('/user')
  2046. @app.route('/ban/<name>', methods=['POST', 'GET'])
  2047. def user_ban(name = None):
  2048. curs.execute("select acl from user where id = ?", [name])
  2049. user = curs.fetchall()
  2050. if user and user[0][0] != 'user':
  2051. if admin_check(conn, None, None) != 1:
  2052. return re_error(conn, '/error/4')
  2053. if request.method == 'POST':
  2054. if admin_check(conn, 1, 'ban (' + name + ')') != 1:
  2055. return re_error(conn, '/error/3')
  2056. ip = ip_check()
  2057. time = get_time()
  2058. time_list = [request.form['month'], request.form['day'], request.form['hour'], request.form['minu']]
  2059. num = 0
  2060. for time_fix in time_list:
  2061. if not re.search("[0-9]{2}", time_fix):
  2062. time_list[num] = '0' + time_fix
  2063. num += 1
  2064. if request.form['year'] == '09':
  2065. end = ''
  2066. else:
  2067. end = request.form['year'] + '-' + time_list[0] + '-' + time_list[1] + ' ' + time_list[2] + ':' + time_list[3] + ':00'
  2068. curs.execute("select block from ban where block = ?", [name])
  2069. if curs.fetchall():
  2070. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, '')", [name, 'ํ•ด์ œ', time, ip, ''])
  2071. curs.execute("delete from ban where block = ?", [name])
  2072. else:
  2073. if re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name):
  2074. band_d = 'O'
  2075. else:
  2076. band_d = ''
  2077. if request.form['login_ok'] != '':
  2078. login = 'O'
  2079. else:
  2080. login = ''
  2081. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, ?)", \
  2082. [name, end, time, ip, request.form['why'], band_d])
  2083. curs.execute("insert into ban (block, end, why, band, login) values (?, ?, ?, ?, ?)", \
  2084. [name, end, request.form['why'], band_d, login])
  2085. conn.commit()
  2086. return redirect('/ban/' + url_pas(name))
  2087. else:
  2088. if admin_check(conn, 1, None) != 1:
  2089. return re_error(conn, '/error/3')
  2090. curs.execute("select end from ban where block = ?", [name])
  2091. end = curs.fetchall()
  2092. if end:
  2093. now = '์ฐจ๋‹จ ํ•ด์ œ'
  2094. if end[0][0] == '':
  2095. data = '์˜๊ตฌ ์ฐจ๋‹จ<hr>'
  2096. else:
  2097. data = end[0][0] + ' ๊นŒ์ง€ ์ฐจ๋‹จ<hr>'
  2098. else:
  2099. if re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name):
  2100. now = '๋Œ€์—ญ ์ฐจ๋‹จ'
  2101. else:
  2102. now = '์ฐจ๋‹จ'
  2103. now_time = get_time()
  2104. m = re.search('^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):[0-9]{2}', now_time)
  2105. g = m.groups()
  2106. year = '<option value="09">์˜๊ตฌ</option>'
  2107. for i in range(int(g[0]), int(g[0]) + 11):
  2108. if i == int(g[0]):
  2109. year += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  2110. else:
  2111. year += '<option value="' + str(i) + '">' + str(i) + '</option>'
  2112. month = ''
  2113. for i in range(1, 13):
  2114. if i == int(g[1]):
  2115. month += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  2116. else:
  2117. month += '<option value="' + str(i) + '">' + str(i) + '</option>'
  2118. day = ''
  2119. for i in range(1, 32):
  2120. if i == int(g[2]):
  2121. day += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  2122. else:
  2123. day += '<option value="' + str(i) + '">' + str(i) + '</option>'
  2124. hour = ''
  2125. for i in range(0, 24):
  2126. if i == int(g[3]):
  2127. hour += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  2128. else:
  2129. hour += '<option value="' + str(i) + '">' + str(i) + '</option>'
  2130. minu = ''
  2131. for i in range(0, 61):
  2132. if i == int(g[4]):
  2133. minu += '<option value="' + str(i) + '" selected>' + str(i) + '</option>'
  2134. else:
  2135. minu += '<option value="' + str(i) + '">' + str(i) + '</option>'
  2136. is_it = ''
  2137. if re.search('(\.|:)', name):
  2138. plus = '<input type="checkbox" name="login_ok"> ๋กœ๊ทธ์ธ ๊ฐ€๋Šฅ<hr>'
  2139. else:
  2140. plus = ''
  2141. data = '<select name="year">' + year + '</select> ๋…„ '
  2142. data += '<select name="month">' + month + '</select> ์›” '
  2143. data += '<select name="day">' + day + '</select> ์ผ <hr>'
  2144. data += '<select name="hour">' + hour + '</select> ์‹œ '
  2145. data += '<select name="minu">' + minu + '</select> ๋ถ„ ๊นŒ์ง€<hr>'
  2146. data += '<input placeholder="์‚ฌ์œ " class="form-control" name="why" type="text"><br>' + plus
  2147. return html_minify(template('index',
  2148. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (' + now + ')', 0])],
  2149. data = '<form method="post">' + data + '<button type="submit">' + now + '</button></form>',
  2150. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  2151. ))
  2152. @app.route('/acl/<path:name>', methods=['POST', 'GET'])
  2153. def acl(name = None):
  2154. test = re.search('^์‚ฌ์šฉ์ž:(.+)$', name)
  2155. if request.method == 'POST':
  2156. if test:
  2157. test = test.groups()
  2158. ip = ip_check()
  2159. if custom(conn)[2] == 0:
  2160. return redirect('/login')
  2161. elif test[0] != ip:
  2162. if admin_check(conn, 5, 'acl (' + name + ')') != 1:
  2163. return re_error(conn, '/error/3')
  2164. else:
  2165. if admin_check(conn, 5, 'acl (' + name + ')') != 1:
  2166. return re_error(conn, '/error/3')
  2167. if request.form['select'] == 'admin':
  2168. sql = 'admin'
  2169. elif request.form['select'] == 'all':
  2170. sql = 'all'
  2171. elif request.form['select'] == 'user':
  2172. sql = 'user'
  2173. else:
  2174. sql = ''
  2175. if sql == '':
  2176. curs.execute("delete from acl where title = ?", [name])
  2177. else:
  2178. curs.execute("select title from acl where title = ?", [name])
  2179. if curs.fetchall():
  2180. curs.execute("update acl set dec = ? where title = ?", [sql, name])
  2181. else:
  2182. curs.execute("insert into acl (title, dec, dis, why) values (?, ?, '', '')", [name, sql])
  2183. conn.commit()
  2184. return redirect('/w/' + url_pas(name))
  2185. else:
  2186. if test:
  2187. test = test.groups()
  2188. ip = ip_check()
  2189. if custom(conn)[2] == 0:
  2190. return redirect('/login')
  2191. elif test[0] != ip:
  2192. if admin_check(conn, 5, 'acl (' + name + ')') != 1:
  2193. return re_error(conn, '/error/3')
  2194. else:
  2195. if admin_check(conn, 5, 'acl (' + name + ')') != 1:
  2196. return re_error(conn, '/error/3')
  2197. acl_list = ['', '', '']
  2198. curs.execute("select dec from acl where title = ?", [name])
  2199. acl_d = curs.fetchall()
  2200. if acl_d:
  2201. if test and acl_d[0][0] == 'all':
  2202. now = '๋ชจ๋‘'
  2203. acl_list[0] = 'selected="selected"'
  2204. elif not test and acl_d[0][0] == 'admin':
  2205. now = '๊ด€๋ฆฌ์ž'
  2206. acl_list[0] = 'selected="selected"'
  2207. elif acl_d[0][0] == 'user':
  2208. now = '๊ฐ€์ž…์ž'
  2209. acl_list[1] = 'selected="selected"'
  2210. else:
  2211. now = '์ผ๋ฐ˜'
  2212. acl_list[2] = 'selected="selected"'
  2213. else:
  2214. now = '์ผ๋ฐ˜'
  2215. acl_list[2] = 'selected="selected"'
  2216. if test:
  2217. plus = '<option value="all" ' + acl_list[0] + '>๋ชจ๋‘</option>'
  2218. else:
  2219. plus = '<option value="admin" ' + acl_list[0] + '>๊ด€๋ฆฌ์ž</option>'
  2220. return html_minify(template('index',
  2221. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ACL)', 0])],
  2222. data = '<form method="post"> \
  2223. <span>ํ˜„์žฌ ACL : ' + now + '</span><hr> \
  2224. <select name="select"> \
  2225. ' + plus + ' \
  2226. <option value="user" ' + acl_list[1] + '>๊ฐ€์ž…์ž</option> \
  2227. <option value="normal" ' + acl_list[2] + '>์ผ๋ฐ˜</option> \
  2228. </select><hr> \
  2229. <button type="submit">ACL ๋ณ€๊ฒฝ</button> \
  2230. </form>',
  2231. menu = [['w/' + url_pas(name), '๋ฌธ์„œ'], ['manager', '๊ด€๋ฆฌ์ž']]
  2232. ))
  2233. @app.route('/admin/<name>', methods=['POST', 'GET'])
  2234. def user_admin(name = None):
  2235. owner = admin_check(conn, None, None)
  2236. curs.execute("select acl from user where id = ?", [name])
  2237. user = curs.fetchall()
  2238. if not user:
  2239. return re_error(conn, '/error/5')
  2240. else:
  2241. if owner != 1:
  2242. curs.execute('select name from alist where name = ? and acl = "owner"', [user[0][0]])
  2243. if curs.fetchall():
  2244. return re_error(conn, '/error/3')
  2245. if ip_check() == name:
  2246. return re_error(conn, '/error/3')
  2247. if request.method == 'POST':
  2248. if admin_check(conn, 7, 'admin (' + name + ')') != 1:
  2249. return re_error(conn, '/error/3')
  2250. curs.execute('select name from alist where name = ? and acl = "owner"', [request.form['select']])
  2251. if curs.fetchall():
  2252. return re_error(conn, '/error/3')
  2253. if request.form['select'] == 'X':
  2254. curs.execute("update user set acl = 'user' where id = ?", [name])
  2255. else:
  2256. curs.execute("update user set acl = ? where id = ?", [request.form['select'], name])
  2257. conn.commit()
  2258. return redirect('/admin/' + url_pas(name))
  2259. else:
  2260. if admin_check(conn, 7, None) != 1:
  2261. return re_error(conn, '/error/3')
  2262. div = '<option value="X">X</option>'
  2263. curs.execute('select distinct name from alist order by name asc')
  2264. get_alist = curs.fetchall()
  2265. if get_alist:
  2266. i = 0
  2267. name_rem = ''
  2268. for data in get_alist:
  2269. if user[0][0] == data[0]:
  2270. div += '<option value="' + data[0] + '" selected="selected">' + data[0] + '</option>'
  2271. else:
  2272. if owner != 1:
  2273. curs.execute('select name from alist where name = ? and acl = "owner"', [data[0]])
  2274. if not curs.fetchall():
  2275. div += '<option value="' + data[0] + '">' + data[0] + '</option>'
  2276. else:
  2277. div += '<option value="' + data[0] + '">' + data[0] + '</option>'
  2278. return html_minify(template('index',
  2279. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (๊ถŒํ•œ ๋ถ€์—ฌ)', 0])],
  2280. data = '<form method="post"> \
  2281. <select name="select">' + div + '</select><hr> \
  2282. <button type="submit">๋ณ€๊ฒฝ</button> \
  2283. </form>',
  2284. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  2285. ))
  2286. @app.route('/diff/<path:name>')
  2287. def diff_data(name = None):
  2288. first = request.args.get('first', '1')
  2289. second = request.args.get('second', '1')
  2290. curs.execute("select data from history where id = ? and title = ?", [first, name])
  2291. first_raw_data = curs.fetchall()
  2292. if first_raw_data:
  2293. curs.execute("select data from history where id = ? and title = ?", [second, name])
  2294. second_raw_data = curs.fetchall()
  2295. if second_raw_data:
  2296. first_data = html.escape(first_raw_data[0][0])
  2297. second_data = html.escape(second_raw_data[0][0])
  2298. if first == second:
  2299. result = '๋‚ด์šฉ์ด ๊ฐ™์Šต๋‹ˆ๋‹ค.'
  2300. else:
  2301. diff_data = difflib.SequenceMatcher(None, first_data, second_data)
  2302. result = diff(diff_data)
  2303. return html_minify(template('index',
  2304. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (๋น„๊ต)', 0])],
  2305. data = '<pre>' + result + '</pre>',
  2306. menu = [['history/' + url_pas(name), '์—ญ์‚ฌ']]
  2307. ))
  2308. return redirect('/history/' + url_pas(name))
  2309. @app.route('/down/<path:name>')
  2310. def down(name = None):
  2311. curs.execute("select title from data where title like ?", ['%' + name + '/%'])
  2312. under = curs.fetchall()
  2313. div = '<ul>'
  2314. for data in under:
  2315. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  2316. div += '</ul>'
  2317. return html_minify(template('index',
  2318. imp = [name, wiki_set(conn, 1), custom(conn), other2([' (ํ•˜์œ„)', 0])],
  2319. data = div,
  2320. menu = [['w/' + url_pas(name), '๋ฌธ์„œ']]
  2321. ))
  2322. @app.route('/w/<path:name>')
  2323. def read_view(name = None):
  2324. data_none = 0
  2325. sub = ''
  2326. acl = ''
  2327. div = ''
  2328. topic = 0
  2329. num = request.args.get('num', None)
  2330. if num:
  2331. num = int(num)
  2332. if not num:
  2333. if 'View_list' in session:
  2334. m = re.findall('([^\n]+)\n', session['View_List'])
  2335. if m[-1] != name:
  2336. d = re.sub(name + '\n', '', session['View_List'])
  2337. d += name + '\n'
  2338. if len(m) > 50:
  2339. d = re.sub('([^\n]+)\n', '', d, 1)
  2340. session['View_List'] = d
  2341. else:
  2342. session['View_List'] = name + '\n'
  2343. curs.execute("select sub from rd where title = ? order by date desc", [name])
  2344. rd = curs.fetchall()
  2345. for data in rd:
  2346. curs.execute("select title from stop where title = ? and sub = ? and close = 'O'", [name, data[0]])
  2347. if not curs.fetchall():
  2348. topic = 1
  2349. break
  2350. curs.execute("select title from data where title like ?", ['%' + name + '/%'])
  2351. if curs.fetchall():
  2352. down = 1
  2353. else:
  2354. down = 0
  2355. m = re.search("^(.*)\/(.*)$", name)
  2356. if m:
  2357. uppage = m.groups()[0]
  2358. else:
  2359. uppage = 0
  2360. if admin_check(conn, 5, None) == 1:
  2361. admin_memu = 1
  2362. else:
  2363. admin_memu = 0
  2364. if(re.search("^๋ถ„๋ฅ˜:", name)):
  2365. curs.execute("select link from back where title = ? and type='cat' order by link asc", [name])
  2366. back = curs.fetchall()
  2367. if back:
  2368. div = '[๋ชฉ์ฐจ(์—†์Œ)]\r\n== ๋ถ„๋ฅ˜ ==\r\n'
  2369. u_div = ''
  2370. i = 0
  2371. for data in back:
  2372. if re.search('^๋ถ„๋ฅ˜:', data[0]):
  2373. if u_div == '':
  2374. u_div = '=== ํ•˜์œ„ ๋ถ„๋ฅ˜ ===\r\n'
  2375. u_div += ' * [[:' + data[0] + ']]\r\n'
  2376. elif re.search('^ํ‹€:', data[0]):
  2377. curs.execute("select data from data where title = ?", [data[0]])
  2378. db_data = curs.fetchall()
  2379. if db_data:
  2380. cat_data = re.sub("\[\[(๋ถ„๋ฅ˜:(?:(?:(?!\]\]|#include).)+))\]\]", "", mid_pas(db_data[0][0], 0, 1, 0, 0)[0])
  2381. if re.search('\[\[' + name + '|include]]', cat_data):
  2382. div += ' * [[' + data[0] + ']]\r\n * [[wiki:xref/' + url_pas(data[0]) + '|' + data[0] + ']] (์—ญ๋งํฌ)\r\n'
  2383. else:
  2384. div += ' * [[' + data[0] + ']]\r\n'
  2385. else:
  2386. div += ' * [[' + data[0] + ']]\r\n'
  2387. div += u_div
  2388. if num:
  2389. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  2390. hid = curs.fetchall()
  2391. if hid and admin_check(conn, 6, None) != 1:
  2392. return redirect('/history/' + url_pas(name))
  2393. curs.execute("select title, data from history where title = ? and id = ?", [name, str(num)])
  2394. else:
  2395. curs.execute("select title, data from data where title = ?", [name])
  2396. data = curs.fetchall()
  2397. if data:
  2398. elsedata = data[0][1]
  2399. else:
  2400. data_none = 1
  2401. response.status = 404
  2402. elsedata = ''
  2403. if not num:
  2404. curs.execute("select dec from acl where title = ?", [name])
  2405. acl_d = curs.fetchall()
  2406. if acl_d:
  2407. if acl_d[0][0] == 'admin':
  2408. acl = ' (๊ด€๋ฆฌ์ž)'
  2409. elif acl_d[0][0] == 'user':
  2410. acl = ' (๊ฐ€์ž…์ž)'
  2411. else:
  2412. curs.execute('select data from other where name = "edit"')
  2413. set_data = curs.fetchall()
  2414. if set_data:
  2415. if set_data[0][0] == 'admin':
  2416. acl = ' (๊ด€๋ฆฌ์ž)'
  2417. elif set_data[0][0] == 'user':
  2418. acl = ' (๊ฐ€์ž…์ž)'
  2419. m = re.search("^์‚ฌ์šฉ์ž:([^/]*)", name)
  2420. if m:
  2421. g = m.groups()
  2422. curs.execute("select acl from user where id = ?", [g[0]])
  2423. test = curs.fetchall()
  2424. if test and test[0][0] != 'user':
  2425. acl = ' (๊ด€๋ฆฌ์ž)'
  2426. else:
  2427. curs.execute("select block from ban where block = ?", [g[0]])
  2428. if curs.fetchall():
  2429. sub = ' (์ฐจ๋‹จ)'
  2430. else:
  2431. acl = ''
  2432. curs.execute("select dec from acl where title = ?", [name])
  2433. data = curs.fetchall()
  2434. if data:
  2435. if data[0][0] == 'all':
  2436. acl += ' (๋ชจ๋‘)'
  2437. elif data[0][0] == 'user':
  2438. acl += ' (๊ฐ€์ž…์ž)'
  2439. if request.args.get('froms', None):
  2440. elsedata = re.sub("^#(?:redirect|๋„˜๊ฒจ์ฃผ๊ธฐ) (?P<in>[^\n]*)", " * [[\g<in>]] ๋ฌธ์„œ๋กœ ๋„˜๊ฒจ์ฃผ๊ธฐ", elsedata)
  2441. enddata = namumark(conn, name, elsedata, 0, 0, 1)
  2442. if data_none == 1:
  2443. menu = [['edit/' + url_pas(name), '์ƒ์„ฑ'], ['topic/' + url_pas(name), topic], \
  2444. ['history/' + url_pas(name), '์—ญ์‚ฌ'], ['move/' + url_pas(name), '์ด๋™'], ['xref/' + url_pas(name), '์—ญ๋งํฌ']]
  2445. else:
  2446. menu = [['edit/' + url_pas(name), '์ˆ˜์ •'], ['topic/' + url_pas(name), topic], \
  2447. ['history/' + url_pas(name), '์—ญ์‚ฌ'], ['delete/' + url_pas(name), '์‚ญ์ œ'], \
  2448. ['move/' + url_pas(name), '์ด๋™'], ['raw/' + url_pas(name), '์›๋ณธ'], ['xref/' + url_pas(name), '์—ญ๋งํฌ']]
  2449. if admin_memu == 1:
  2450. menu += [['acl/' + url_pas(name), 'ACL']]
  2451. if request.args.get('froms', None):
  2452. menu += [['w/' + url_pas(name), '๋„˜๊ธฐ๊ธฐ']]
  2453. enddata = '<ul id="redirect"><li><a href="/w/' + url_pas(request.args.get('froms', None)) + \
  2454. '?froms=' + url_pas(name) + '">' + request.args.get('froms', None) + '</a>์—์„œ ๋„˜์–ด ์™”์Šต๋‹ˆ๋‹ค.</li></ul><br>' + enddata
  2455. if uppage != 0:
  2456. menu += [['w/' + url_pas(uppage), '์ƒ์œ„']]
  2457. if down:
  2458. menu += [['down/' + url_pas(name), 'ํ•˜์œ„']]
  2459. if num:
  2460. menu = [['history/' + url_pas(name), '์—ญ์‚ฌ']]
  2461. sub = ' (' + str(num) + 'ํŒ)'
  2462. acl = ''
  2463. r_date = 0
  2464. else:
  2465. curs.execute("select date from history where title = ? order by date desc limit 1", [name])
  2466. date = curs.fetchall()
  2467. if date:
  2468. r_date = date[0][0]
  2469. else:
  2470. r_date = 0
  2471. if div != '' and enddata != '':
  2472. div = enddata + '<br>' + namumark(conn, name, div, 0, 0, 0)
  2473. else:
  2474. div = enddata + namumark(conn, name, div, 0, 0, 0)
  2475. return html_minify(template('index',
  2476. imp = [name, wiki_set(conn, 1), custom(conn), other2([sub + acl, r_date])],
  2477. data = div,
  2478. menu = menu
  2479. ))
  2480. @app.route('/topic_record/<name>')
  2481. def user_topic_list(name = None):
  2482. num = int(request.args.get('num', 1))
  2483. if num * 50 > 0:
  2484. sql_num = num * 50 - 50
  2485. else:
  2486. sql_num = 0
  2487. one_admin = admin_check(conn, 1, None)
  2488. div = '<table style="width: 100%; text-align: center;"><tbody><tr>'
  2489. div += '<td style="width: 33.3%;">ํ† ๋ก ๋ช…</td><td style="width: 33.3%;">์ž‘์„ฑ์ž</td><td style="width: 33.3%;">์‹œ๊ฐ„</td></tr>'
  2490. curs.execute("select title, id, sub, ip, date from topic where ip = ? order by date desc limit ?, '50'", [name, str(sql_num)])
  2491. data_list = curs.fetchall()
  2492. for data in data_list:
  2493. title = html.escape(data[0])
  2494. sub = html.escape(data[2])
  2495. if one_admin == 1:
  2496. curs.execute("select * from ban where block = ?", [data[3]])
  2497. if curs.fetchall():
  2498. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(ํ•ด์ œ)</a>'
  2499. else:
  2500. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(์ฐจ๋‹จ)</a>'
  2501. else:
  2502. ban = ''
  2503. ip = ip_pas(conn, data[3])
  2504. div += '<tr><td><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[2]) + '#' + data[1] + '">' + \
  2505. title + '#' + data[1] + '</a> (' + sub + ')</td>'
  2506. div += '<td>' + ip + ban + '</td><td>' + data[4] + '</td></tr>'
  2507. div += '</tbody></table>'
  2508. div += next_fix('/topic_record/' + url_pas(name) + '?num=', num, data_list)
  2509. curs.execute("select end, why from ban where block = ?", [name])
  2510. ban_it = curs.fetchall()
  2511. if ban_it:
  2512. sub = ' (์ฐจ๋‹จ)'
  2513. else:
  2514. sub = 0
  2515. return html_minify(template('index',
  2516. imp = ['ํ† ๋ก  ๊ธฐ๋ก', wiki_set(conn, 1), custom(conn), other2([sub, 0])],
  2517. data = div,
  2518. menu = [['other', '๊ธฐํƒ€'], ['user', '์‚ฌ์šฉ์ž'], ['count/' + url_pas(name), 'ํšŸ์ˆ˜'], ['record/' + url_pas(name), 'ํŽธ์ง‘']]
  2519. ))
  2520. @app.route('/recent_changes')
  2521. @app.route('/<regex("record"):tool>/<name>')
  2522. @app.route('/<regex("history"):tool>/<path:name>', methods=['POST', 'GET'])
  2523. def recent_changes(name = None, tool = 'record'):
  2524. if request.method == 'POST':
  2525. return redirect('/diff/' + url_pas(name) + '?first=' + request.form['b'] + '&second=' + request.form['a'])
  2526. else:
  2527. one_admin = admin_check(conn, 1, None)
  2528. six_admin = admin_check(conn, 6, None)
  2529. ban = ''
  2530. select = ''
  2531. what = request.args.get('what', 'all')
  2532. div = '<table style="width: 100%; text-align: center;"><tbody><tr>'
  2533. if name:
  2534. num = int(request.args.get('num', 1))
  2535. if num * 50 > 0:
  2536. sql_num = num * 50 - 50
  2537. else:
  2538. sql_num = 0
  2539. if tool == 'history':
  2540. div += '<td style="width: 33.3%;">ํŒ</td><td style="width: 33.3%;">ํŽธ์ง‘์ž</td><td style="width: 33.3%;">์‹œ๊ฐ„</td></tr>'
  2541. curs.execute("select id, title, date, ip, send, leng from history where title = ? order by id + 0 desc limit ?, '50'", \
  2542. [name, str(sql_num)])
  2543. else:
  2544. div += '<td style="width: 33.3%;">๋ฌธ์„œ๋ช…</td><td style="width: 33.3%;">ํŽธ์ง‘์ž</td><td style="width: 33.3%;">์‹œ๊ฐ„</td></tr>'
  2545. if what == 'all':
  2546. div = '<a href="/record/' + url_pas(name) + '?what=revert">(๋˜๋Œ๋ฆฌ๊ธฐ)</a><hr>' + div
  2547. div = '<a href="/record/' + url_pas(name) + '?what=move">(์ด๋™)</a> ' + div
  2548. div = '<a href="/record/' + url_pas(name) + '?what=delete">(์‚ญ์ œ)</a> ' + div
  2549. curs.execute("select id, title, date, ip, send, leng from history where ip = ? order by date desc limit ?, '50'", \
  2550. [name, str(sql_num)])
  2551. else:
  2552. if what == 'delete':
  2553. sql = '%(์‚ญ์ œ)'
  2554. elif what == 'move':
  2555. sql = '%์ด๋™)'
  2556. elif what == 'revert':
  2557. sql = '%ํŒ)'
  2558. else:
  2559. return redirect('/')
  2560. curs.execute("select id, title, date, ip, send, leng from history where ip = ? and send like ? order by date desc limit ?, '50'", \
  2561. [name, sql, str(sql_num)])
  2562. else:
  2563. div += '<td style="width: 33.3%;">๋ฌธ์„œ๋ช…</td><td style="width: 33.3%;">ํŽธ์ง‘์ž</td><td style="width: 33.3%;">์‹œ๊ฐ„</td></tr>'
  2564. if what == 'all':
  2565. div = '<a href="/recent_changes?what=revert">(๋˜๋Œ๋ฆฌ๊ธฐ)</a><hr>' + div
  2566. div = '<a href="/recent_changes?what=move">(์ด๋™)</a> ' + div
  2567. div = '<a href="/recent_changes?what=delete">(์‚ญ์ œ)</a> ' + div
  2568. curs.execute("select id, title, date, ip, send, leng from history order by date desc limit 50")
  2569. else:
  2570. if what == 'delete':
  2571. sql = '%(์‚ญ์ œ)'
  2572. elif what == 'move':
  2573. sql = '%์ด๋™)'
  2574. elif what == 'revert':
  2575. sql = '%ํŒ)'
  2576. else:
  2577. return redirect('/')
  2578. curs.execute("select id, title, date, ip, send, leng from history where send like ? order by date desc limit 50", [sql])
  2579. data_list = curs.fetchall()
  2580. for data in data_list:
  2581. select += '<option value="' + data[0] + '">' + data[0] + '</option>'
  2582. send = '<br>'
  2583. if data[4]:
  2584. if not re.search("^(?: *)$", data[4]):
  2585. send = data[4]
  2586. if re.search("\+", data[5]):
  2587. leng = '<span style="color:green;">(' + data[5] + ')</span>'
  2588. elif re.search("\-", data[5]):
  2589. leng = '<span style="color:red;">(' + data[5] + ')</span>'
  2590. else:
  2591. leng = '<span style="color:gray;">(' + data[5] + ')</span>'
  2592. if one_admin == 1:
  2593. curs.execute("select * from ban where block = ?", [data[3]])
  2594. if curs.fetchall():
  2595. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(ํ•ด์ œ)</a>'
  2596. else:
  2597. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(์ฐจ๋‹จ)</a>'
  2598. ip = ip_pas(conn, data[3])
  2599. if (int(data[0]) - 1) == 0:
  2600. revert = ''
  2601. else:
  2602. revert = '<a href="/diff/' + url_pas(data[1]) + '?first=' + str(int(data[0]) - 1) + '&second=' + data[0] + \
  2603. '">(๋น„๊ต)</a> <a href="/revert/' + url_pas(data[1]) + '?num=' + str(int(data[0]) - 1) + '">(๋˜๋Œ๋ฆฌ๊ธฐ)</a>'
  2604. style = ['', '']
  2605. date = data[2]
  2606. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [data[1], data[0]])
  2607. hide = curs.fetchall()
  2608. if six_admin == 1:
  2609. if(hide):
  2610. hidden = ' <a href="/hidden/' + url_pas(data[1]) + '?num=' + data[0] + '">(๊ณต๊ฐœ)'
  2611. style[0] = 'background: gainsboro;'
  2612. style[1] = 'background: gainsboro;'
  2613. if send == '<br>':
  2614. send = '(์ˆจ๊น€)'
  2615. else:
  2616. send += ' (์ˆจ๊น€)'
  2617. else:
  2618. hidden = ' <a href="/hidden/' + url_pas(data[1]) + '?num=' + data[0] + '">(์ˆจ๊น€)'
  2619. elif not hide:
  2620. hidden = ''
  2621. else:
  2622. ip = ''
  2623. hidden = ''
  2624. ban = ''
  2625. date = ''
  2626. send = '(์ˆจ๊น€)'
  2627. style[0] = 'display: none;'
  2628. style[1] = 'background: gainsboro;'
  2629. if tool == 'history':
  2630. title = '<a href="/w/' + url_pas(name) + '?num=' + data[0] + '">' + data[0] + 'ํŒ</a> <a href="/raw/' + \
  2631. url_pas(name) + '?num=' + data[0] + '">(์›๋ณธ)</a> '
  2632. else:
  2633. title = '<a href="/w/' + url_pas(data[1]) + '">' + html.escape(data[1]) + '</a> <a href="/history/' + \
  2634. url_pas(data[1]) + '">(' + data[0] + 'ํŒ)</a> '
  2635. div += '<tr style="' + style[0] + '"><td>' + title + revert + ' ' + leng + '</td>'
  2636. div += '<td>' + ip + ban + hidden + '</td><td>' + date + '</td></tr><tr style="' + style[1] + '"><td colspan="3">' + send + '</td></tr>'
  2637. div += '</tbody></table>'
  2638. sub = ''
  2639. if name:
  2640. if tool == 'history':
  2641. div = '<form method="post"><select name="a">' + select + '</select> <select name="b">' + select + \
  2642. '</select> <button type="submit">๋น„๊ต</button></form><hr>' + div
  2643. title = name
  2644. sub += ' (์—ญ์‚ฌ)'
  2645. menu = [['w/' + url_pas(name), '๋ฌธ์„œ'], ['move_data/' + url_pas(name), '์ด๋™ ๊ธฐ๋ก']]
  2646. div += next_fix('/history/' + url_pas(name) + '?num=', num, data_list)
  2647. else:
  2648. curs.execute("select end, why from ban where block = ?", [name])
  2649. ban_it = curs.fetchall()
  2650. if ban_it:
  2651. sub += ' (์ฐจ๋‹จ)'
  2652. title = 'ํŽธ์ง‘ ๊ธฐ๋ก'
  2653. menu = [['other', '๊ธฐํƒ€'], ['user', '์‚ฌ์šฉ์ž'], ['count/' + url_pas(name), 'ํšŸ์ˆ˜'], ['topic_record/' + url_pas(name), 'ํ† ๋ก ']]
  2654. div += next_fix('/record/' + url_pas(name) + '/' + url_pas(what) + '?num=', num, data_list)
  2655. if what != 'all':
  2656. menu += [['record/' + url_pas(name), '์ผ๋ฐ˜']]
  2657. else:
  2658. menu = 0
  2659. title = '์ตœ๊ทผ ๋ณ€๊ฒฝ๋‚ด์—ญ'
  2660. if what != 'all':
  2661. menu = [['recent_changes', '์ผ๋ฐ˜']]
  2662. if what == 'delete':
  2663. sub += ' (์‚ญ์ œ)'
  2664. elif what == 'move':
  2665. sub += ' (์ด๋™)'
  2666. elif what == 'revert':
  2667. sub += ' (๋˜๋Œ๋ฆฌ๊ธฐ)'
  2668. if sub == '':
  2669. sub = 0
  2670. return html_minify(template('index',
  2671. imp = [title, wiki_set(conn, 1), custom(conn), other2([sub, 0])],
  2672. data = div,
  2673. menu = menu
  2674. ))
  2675. @app.route('/upload', methods=['GET', 'POST'])
  2676. def upload():
  2677. if ban_check(conn) == 1:
  2678. return re_error(conn, '/ban')
  2679. if request.method == 'POST':
  2680. if captcha_post(request.form.get('g-recaptcha-response', None), conn) == 1:
  2681. return re_error(conn, '/error/13')
  2682. else:
  2683. captcha_post('', conn, 0)
  2684. data = request.files['f_data']
  2685. if not data:
  2686. return re_error(conn, '/error/9')
  2687. if int(wiki_set(conn, 3)) * 1024 * 1024 < request.content_length:
  2688. return re_error(conn, '/error/17')
  2689. value = os.path.splitext(data.filename)[1]
  2690. if not value in ['.jpeg', '.jpg', '.gif', '.png', '.webp', '.JPEG', '.JPG', '.GIF', '.PNG', '.WEBP']:
  2691. return re_error(conn, '/error/14')
  2692. if request.form['f_name']:
  2693. name = request.form['f_name'] + value
  2694. else:
  2695. name = data.filename
  2696. piece = os.path.splitext(name)
  2697. if re.search('[^ใ„ฑ-ํžฃ0-9a-zA-Z_\- ]', piece[0]):
  2698. return re_error(conn, '/error/22')
  2699. e_data = sha224(piece[0]) + piece[1]
  2700. curs.execute("select title from data where title = ?", ['ํŒŒ์ผ:' + name])
  2701. if curs.fetchall():
  2702. return re_error(conn, '/error/16')
  2703. ip = ip_check()
  2704. if request.form['f_lice']:
  2705. lice = request.form['f_lice']
  2706. else:
  2707. if custom(conn)[2] == 0:
  2708. lice = ip + ' ์˜ฌ๋ฆผ'
  2709. else:
  2710. lice = '[[์‚ฌ์šฉ์ž:' + ip + ']] ์˜ฌ๋ฆผ'
  2711. if os.path.exists(os.path.join('image', e_data)):
  2712. os.remove(os.path.join('image', e_data))
  2713. data.save(os.path.join('image', e_data))
  2714. else:
  2715. data.save(os.path.join('image', e_data))
  2716. curs.execute("select title from data where title = ?", ['ํŒŒ์ผ:' + name])
  2717. exist = curs.fetchall()
  2718. if(exist):
  2719. curs.execute("delete from data where title = ?", ['ํŒŒ์ผ:' + name])
  2720. curs.execute("insert into data (title, data) values (?, ?)", \
  2721. ['ํŒŒ์ผ:' + name, '[[ํŒŒ์ผ:' + name + ']][br][br]{{{[[ํŒŒ์ผ:' + name + ']]}}}[br][br]' + lice])
  2722. curs.execute("insert into acl (title, dec, dis, why) values (?, 'admin', '', '')", ['ํŒŒ์ผ:' + name])
  2723. history_plus(conn, 'ํŒŒ์ผ:' + name, '[[ํŒŒ์ผ:' + name + ']][br][br]{{{[[ํŒŒ์ผ:' + name + ']]}}}[br][br]' + lice, \
  2724. get_time(), ip, '(ํŒŒ์ผ ์˜ฌ๋ฆผ)', '0')
  2725. conn.commit()
  2726. return redirect('/w/ํŒŒ์ผ:' + name)
  2727. else:
  2728. return html_minify(template('index',
  2729. imp = ['ํŒŒ์ผ ์˜ฌ๋ฆฌ๊ธฐ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2730. data = '<form method="post" enctype="multipart/form-data" accept-charset="utf8"> \
  2731. <input type="file" name="f_data"><hr> \
  2732. <input placeholder="ํŒŒ์ผ ์ด๋ฆ„" name="f_name" type="text"><hr> \
  2733. <input placeholder="๋ผ์ด์„ ์Šค" name="f_lice" type="text"><hr> \
  2734. ' + captcha_get(conn) + ' \
  2735. <button id="save" type="submit">์ €์žฅ</button> \
  2736. </form>',
  2737. menu = [['other', '๊ธฐํƒ€']]
  2738. ))
  2739. @app.route('/user')
  2740. def user_info():
  2741. ip = ip_check()
  2742. curs.execute("select acl from user where id = ?", [ip])
  2743. data = curs.fetchall()
  2744. if ban_check(conn) == 0:
  2745. if data:
  2746. if data[0][0] != 'user':
  2747. acl = data[0][0]
  2748. else:
  2749. acl = '๊ฐ€์ž…์ž'
  2750. else:
  2751. acl = '์ผ๋ฐ˜'
  2752. else:
  2753. acl = '์ฐจ๋‹จ'
  2754. curs.execute("select block from ban where block = ? and login = 'O'", [ip])
  2755. if curs.fetchall():
  2756. acl += ' (๋กœ๊ทธ์ธ ๊ฐ€๋Šฅ)'
  2757. if custom(conn)[2] != 0:
  2758. ip_user = '[[์‚ฌ์šฉ์ž:' + ip + '|' + ip + ']]'
  2759. plus = ' * [[wiki:logout|๋กœ๊ทธ์•„์›ƒ]]\r\n * [[wiki:change|๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ]]\r\n * [[wiki:email|์ด๋ฉ”์ผ ์ˆ˜์ •]]'
  2760. else:
  2761. ip_user = ip
  2762. plus = ' * [[wiki:login|๋กœ๊ทธ์ธ]]'
  2763. return html_minify(template('index',
  2764. imp = ['์‚ฌ์šฉ์ž ๋ฉ”๋‰ด', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2765. data = namumark(conn, '', '[๋ชฉ์ฐจ(์—†์Œ)]\r\n' + \
  2766. '== ์ƒํƒœ ==\r\n' + \
  2767. ' * ' + ip_user + ' [[wiki:record/' + url_pas(ip) + '|(๊ธฐ๋ก)]]\r\n' + \
  2768. ' * ๊ถŒํ•œ ์ƒํƒœ : ' + acl + '\r\n' + \
  2769. '== ๋กœ๊ทธ์ธ ==\r\n' + \
  2770. plus + '\r\n' + \
  2771. ' * [[wiki:register|ํšŒ์›๊ฐ€์ž…]]\r\n' + \
  2772. '== ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ ==\r\n' + \
  2773. ' * [[wiki:acl/์‚ฌ์šฉ์ž:' + url_pas(ip) + '|์‚ฌ์šฉ์ž ๋ฌธ์„œ ACL]]\r\n' + \
  2774. ' * [[wiki:custom_head|์‚ฌ์šฉ์ž HEAD]]\r\n' + \
  2775. '== ๊ธฐํƒ€ ==\r\n' + \
  2776. ' * [[wiki:alarm|์•Œ๋ฆผ]]\r\n' + \
  2777. ' * [[wiki:view_log|์ง€๋‚˜์˜จ ๋ฌธ์„œ]]\r\n' + \
  2778. ' * [[wiki:watch_list|์ฃผ์‹œ ๋ฌธ์„œ]]\r\n' + \
  2779. ' * [[wiki:count|ํ™œ๋™ ํšŸ์ˆ˜]]\r\n', 0, 0, 0),
  2780. menu = 0
  2781. ))
  2782. @app.route('/email', methods=['GET', 'POST'])
  2783. def email():
  2784. if custom(conn)[2] == 0:
  2785. return re_error(conn, '/error/1')
  2786. if request.method == 'POST':
  2787. curs.execute("update user set email = ? where id = ?", [request.form.get('email', ''), ip_check()])
  2788. conn.commit()
  2789. return redirect('/user')
  2790. else:
  2791. curs.execute('select email from user where id = ?', [ip_check()])
  2792. data = curs.fetchall()
  2793. if data:
  2794. email = data[0][0]
  2795. else:
  2796. email = ''
  2797. return html_minify(template('index',
  2798. imp = ['์ด๋ฉ”์ผ ์ˆ˜์ •', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2799. data = '<form method="post"> \
  2800. <input placeholder="์ด๋ฉ”์ผ" name="email" type="text" value="' + email + '"><hr> \
  2801. <button type="submit">๋ณ€๊ฒฝ</button><hr> \
  2802. </form>',
  2803. menu = [['user', '์‚ฌ์šฉ์ž']]
  2804. ))
  2805. @app.route('/watch_list')
  2806. def watch_list():
  2807. div = 'ํ•œ๋„ : 10๊ฐœ<hr>'
  2808. ip = ip_check()
  2809. if custom(conn)[2] == 0:
  2810. return redirect('/login')
  2811. curs.execute("select title from scan where user = ?", [ip])
  2812. data = curs.fetchall()
  2813. for data_list in data:
  2814. div += '<li><a href="/w/' + url_pas(data_list[0]) + '">' + data_list[0] + '</a> <a href="/watch_list/' + \
  2815. url_pas(data_list[0]) + '">(์‚ญ์ œ)</a></li>'
  2816. if data:
  2817. div = '<ul>' + div + '</ul><hr>'
  2818. div += '<a href="/manager/13">(์ถ”๊ฐ€)</a>'
  2819. return html_minify(template('index',
  2820. imp = ['ํŽธ์ง‘ ํ•„ํ„ฐ ๋ชฉ๋ก', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2821. data = div,
  2822. menu = [['manager', '๊ด€๋ฆฌ์ž']]
  2823. ))
  2824. @app.route('/watch_list/<name>')
  2825. def watch_list_name(name = None):
  2826. ip = ip_check()
  2827. if custom(conn)[2] == 0:
  2828. return redirect('/login')
  2829. curs.execute("select count(title) from scan where user = ?", [ip])
  2830. count = curs.fetchall()
  2831. if count:
  2832. if count[0][0] > 9:
  2833. return redirect('/watch_list')
  2834. curs.execute("select title from scan where user = ? and title = ?", [ip, name])
  2835. if curs.fetchall():
  2836. curs.execute("delete from scan where user = ? and title = ?", [ip, name])
  2837. else:
  2838. curs.execute("insert into scan (user, title) values (?, ?)", [ip, name])
  2839. conn.commit()
  2840. return redirect('/watch_list')
  2841. @app.route('/view_log')
  2842. def view_log():
  2843. data = '<ul>'
  2844. if session['View_List']:
  2845. data += '<li>์ตœ๊ทผ 50๊ฐœ</li><hr>'
  2846. m = re.findall('([^\n]+)\n', session['View_List'])
  2847. for d in m:
  2848. data += '<li><a href="/w/' + url_pas(d) + '">' + d + '</a></li>'
  2849. else:
  2850. data += '<li>๊ธฐ๋ก ์—†์Œ</li>'
  2851. data += '</ul>'
  2852. return html_minify(template('index',
  2853. imp = ['์ง€๋‚˜์˜จ ๋ฌธ์„œ', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2854. data = data,
  2855. menu = [['user', '์‚ฌ์šฉ์ž']]
  2856. ))
  2857. @app.route('/custom_head', methods=['GET', 'POST'])
  2858. def custom_head_view():
  2859. ip = ip_check()
  2860. if request.method == 'POST':
  2861. if custom(conn)[2] != 0:
  2862. curs.execute("select user from custom where user = ?", [ip + ' (head)'])
  2863. if curs.fetchall():
  2864. curs.execute("update custom set css = ? where user = ?", [request.form['content'], ip + ' (head)'])
  2865. else:
  2866. curs.execute("insert into custom (user, css) values (?, ?)", [ip + ' (head)', request.form['content']])
  2867. conn.commit()
  2868. session['MyMaiToNight'] = request.form['content']
  2869. return redirect('/user')
  2870. else:
  2871. if custom(conn)[2] != 0:
  2872. start = ''
  2873. curs.execute("select css from custom where user = ?", [ip + ' (head)'])
  2874. head_data = curs.fetchall()
  2875. if head_data:
  2876. data = head_data[0][0]
  2877. else:
  2878. data = ''
  2879. else:
  2880. start = '<span>๋น„ ๋กœ๊ทธ์ธ์˜ ๊ฒฝ์šฐ์—๋Š” ๋กœ๊ทธ์ธํ•˜๊ฑฐ๋‚˜ ๋ธŒ๋ผ์šฐ์ € ๋‹ซ์œผ๋ฉด ๋‚ ์•„๊ฐ‘๋‹ˆ๋‹ค.</span><hr>'
  2881. try:
  2882. data = session['MyMaiToNight']
  2883. except:
  2884. data = ''
  2885. start += '<span>&lt;style&gt;CSS&lt;/style&gt;<br>&lt;script&gt;JS&lt;/script&gt;</span><hr>'
  2886. return html_minify(template('index',
  2887. imp = ['์‚ฌ์šฉ์ž HEAD', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2888. data = start + ' \
  2889. <form method="post"> \
  2890. <textarea rows="25" cols="100" name="content">' + data + '</textarea><hr> \
  2891. <button id="save" type="submit">์ €์žฅ</button> \
  2892. </form>',
  2893. menu = [['user', '์‚ฌ์šฉ์ž']]
  2894. ))
  2895. @app.route('/count')
  2896. @app.route('/count/<name>')
  2897. def count_edit(name = None):
  2898. if name == None:
  2899. that = ip_check()
  2900. else:
  2901. that = name
  2902. curs.execute("select count(title) from history where ip = ?", [that])
  2903. count = curs.fetchall()
  2904. if count:
  2905. data = count[0][0]
  2906. else:
  2907. data = 0
  2908. curs.execute("select count(title) from topic where ip = ?", [that])
  2909. count = curs.fetchall()
  2910. if count:
  2911. t_data = count[0][0]
  2912. else:
  2913. t_data = 0
  2914. return html_minify(template('index',
  2915. imp = ['ํ™œ๋™ ํšŸ์ˆ˜', wiki_set(conn, 1), custom(conn), other2([0, 0])],
  2916. data = namumark(conn, "", "[๋ชฉ์ฐจ(์—†์Œ)]\r\n== " + that + " ==\r\n||<:> ํŽธ์ง‘ ํšŸ์ˆ˜ ||<:> " + str(data) + \
  2917. "||\r\n||<:> ํ† ๋ก  ํšŸ์ˆ˜ ||<:> " + str(t_data) + "||", 0, 0, 0),
  2918. menu = [['user', '์‚ฌ์šฉ์ž'], ['record/' + url_pas(that), 'ํŽธ์ง‘ ๊ธฐ๋ก'], ['topic_record/' + url_pas(that), 'ํ† ๋ก  ๊ธฐ๋ก']]
  2919. ))
  2920. @app.route('/random')
  2921. def random():
  2922. curs.execute("select title from data order by random() limit 1")
  2923. d = curs.fetchall()
  2924. if d:
  2925. return redirect('/w/' + url_pas(d[0][0]))
  2926. else:
  2927. return redirect('/')
  2928. @app.route('/views/<path:name>')
  2929. def views(name = None):
  2930. if re.search('\/', name):
  2931. m = re.search('^(.*)\/(.*)$', name)
  2932. if m:
  2933. n = m.groups()
  2934. plus = '/' + n[0]
  2935. rename = n[1]
  2936. else:
  2937. plus = ''
  2938. rename = name
  2939. else:
  2940. plus = ''
  2941. rename = name
  2942. m = re.search('\.(.+)$', name)
  2943. if m:
  2944. g = m.groups()
  2945. else:
  2946. g = ['']
  2947. if g == 'css':
  2948. return css_minify(send_from_directory('./views' + plus, rename))
  2949. elif g == 'js':
  2950. return js_minify(send_from_directory('./views' + plus, rename))
  2951. elif g == 'html':
  2952. return html_minify(send_from_directory('./views' + plus, rename))
  2953. else:
  2954. return send_from_directory('./views' + plus, rename)
  2955. @app.route('/<test>')
  2956. def main_file(test = None):
  2957. if re.search('\.(txt|html)$', test):
  2958. return send_from_directory('./', test)
  2959. else:
  2960. return ''
  2961. @app.errorhandler(404)
  2962. def error_404(e):
  2963. return '<!-- ๋‚˜๋‹ˆ์นด๊ฐ€ ํ•˜์ง€๋งˆ๋ฃปํ…Œ ์ฝ”ํ† ์™€ ์˜ค์™€๋ฆฌ๋‹ˆ ์ธ ๋‚˜๊ฐ€๋ฃจ๋‹ค๋‚œํ…Œ ์บ‰๊ฐ€์—ํ…Œ๋ชจ ๋ฏธ๋‚˜์บ‡ํƒ€. ์ด์•ผ, ์บ‰์นด์—ํƒ€์ฟ ๋‚˜์บ‡ํƒ„๋‹ค... \
  2964. ์•„๋งˆ์˜คํ†  ๋งˆ๋„์˜ค ํƒ€ํƒ€์ฟ  ์†Œ๋ผ์นด๋ผ ์™€ํƒ€์‹œ๋…ธ ์š”-๋‚˜ ์นด๋‚˜์‹œ๋ฏธ ํ›—ํ…Œ๋ฃจ ํ† ๋ฉ”๋„๋‚˜์ฟ  ์ด๋งˆ์˜ค ๋ˆ„๋ผ์‹œํ…Œ \
  2965. ์˜ค๋ชจ์ด๋ฐ ๋‚œํ…Œ ์ด๋ผ๋‚˜์ด๋…ธ ์ฝ”์ฝ”๋กœ๊ฐ€ ์ฟ ๋ฃจ์‹œ์ฟ ๋‚˜๋ฃจ ๋‹ค์ผ€๋‹คํ†  No more! September Rain No more! September Rain \
  2966. ์ด์ธ ๋‹ทํ…Œ ์•„๋‚˜ํƒ€์™€ ๋ฏธ์ง“์นด๋‹ทํƒ€ ์™€์ž์™€์ž ํ‚ค๋ชจ์น˜์˜ค ํƒ€์‹œ์นด๋ฉ”๋ฃปํ…Œ ์ฝ”ํ† ๋ชจ ํžˆ์ธ ์š”-์Ÿˆ๋‚˜์ฟ ํ…Œ \
  2967. ์‹œ์  ๋‹ˆ ๋‚˜์นด๋ผ์š”์ฟ  ๋‚˜๋ ˆํƒ€์นด๋ผ ์•ˆ์‹ ์‹œํ…Œํƒ€๋…ธ ์นด๋ชจ์‹œ๋ ˆ๋‚˜์ด๋„ค ๋„-์‹œํ…Œ? ๋‚˜๋ฏธ๋‹ˆ ํ† ์ด์นด์ผ€๋ฃจ์ผ€๋„ \
  2968. ๋‚˜์ธ ๋…ธ ํ•˜์ง€๋งˆ๋ฆฌ๊ฐ€ ์ธ ๋ ˆํ…Œํ‚คํƒ€ ์˜ค๋ชจ์ด ๋‚˜์ธ ๊ฐ€ ์˜ค์™€๋ฃจํ† ํ‚ค ํ‚ค์—์ฑ ์šฐ๋ชจ๋…ธ๋‹ทํƒ€ ๋‚œํ…Œ ์‹œ๋ผ๋‚˜์ฟ ํ…Œ \
  2969. ํ† ํ‚ค๋ฉ”์ดํ…Œํƒ€ ์•„์ธ ์ด ํ‚ค์„ธ์ธ  \
  2970. ์šฐ๋ฏธ๋ฒ ๋…ธ ์†Œ๋ผ๊ฐ€ ํžˆ์บ‡ํ…Œ ํ† ์ธ ์   ์ฟ ๋ชจ๊ฐ€ ๋‚˜๊ฐ€๋ ˆ ์˜ค์ธ ๋ถ€๋…ธ ์•„๋ฉ” ์™€ํƒ€์‹œ๋…ธ ๋‚˜์นด๋…ธ ๋‚˜๋ฏธ๋‹ค๋ฏธํƒ€์ด \
  2971. ์ฝ˜๋‚˜๋‹ˆ ํƒ€๋…ธ์‹œ์ด ๋‚˜์ธ ๊ฐ€ ์ฆ›ํ†  ์ธ ์ฆˆ์ดํ…Œ์ฟณํ…Œ ์‹ ์ง€ํ…Œํƒ€์š” But now... September Rain But now... September Rain -->' + \
  2972. redirect('/w/' + url_pas(wiki_set(conn, 2)))
  2973. if __name__=="__main__":
  2974. app.secret_key = rep_key
  2975. http_server = HTTPServer(WSGIContainer(app))
  2976. http_server.listen(rep_port)
  2977. IOLoop.instance().start()