app.py 140 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819
  1. from bottle import route, run, template, error, request, static_file, app, BaseRequest
  2. from bottle.ext import beaker
  3. import bcrypt
  4. import os
  5. import difflib
  6. import hashlib
  7. import json
  8. import pymysql
  9. try:
  10. json_data = open('set.json').read()
  11. set_data = json.loads(json_data)
  12. except:
  13. new_json = []
  14. print('DB 이름 : ', end = '')
  15. new_json += [input()]
  16. print('DB 사용자 : ', end = '')
  17. new_json += [input()]
  18. print('DB 비밀번호 : ', end = '')
  19. new_json += [input()]
  20. print('위키 이름 : ', end = '')
  21. new_json += [input()]
  22. print('대문 : ', end = '')
  23. new_json += [input()]
  24. print('라이선스 : ', end = '')
  25. new_json += [input()]
  26. print('비밀 키 : ', end = '')
  27. new_json += [input()]
  28. print('업로드 제한 (MB) : ', end = '')
  29. new_json += [input()]
  30. print('위키 포트 : ', end = '')
  31. new_json += [input()]
  32. with open("set.json", "w") as f:
  33. f.write('{ \
  34. "db" : "' + new_json[0] + '", \
  35. "user" : "' + new_json[1] + '", \
  36. "pw" : "' + new_json[2] + '", \
  37. "name" : "' + new_json[3] + '", \
  38. "frontpage" : "' + new_json[4] + '", \
  39. "license" : "' + new_json[5] + '", \
  40. "key" : "' + new_json[6] + '", \
  41. "upload" : "' + new_json[7] + '", \
  42. "port" : "' + new_json[8] + '" \
  43. }')
  44. json_data = open('set.json').read()
  45. set_data = json.loads(json_data)
  46. session_opts = {
  47. 'session.type': 'file',
  48. 'session.data_dir': './app_session/',
  49. 'session.auto': True
  50. }
  51. app = beaker.middleware.SessionMiddleware(app(), session_opts)
  52. BaseRequest.MEMFILE_MAX = 1024 * 1024
  53. def redirect(data):
  54. return('<meta http-equiv="refresh" content="0;url=' + data + '" />')
  55. from func import *
  56. r_ver = '2.1.7'
  57. try:
  58. conn = pymysql.connect(
  59. user = set_data['user'],
  60. password = set_data['pw'],
  61. charset = 'utf8mb4',
  62. db = set_data['db']
  63. )
  64. curs = conn.cursor(pymysql.cursors.DictCursor)
  65. curs.execute('select data from other where name = "version"')
  66. version = curs.fetchall()
  67. if(version):
  68. t_ver = re.sub('\.', '', version[0]['data'])
  69. r_t_ver = re.sub('\.', '', r_ver)
  70. if(int(t_ver) <= int(r_t_ver)):
  71. curs.execute("update other set data = '" + pymysql.escape_string(r_ver) + "' where name = 'version'")
  72. conn.commit()
  73. conn.close()
  74. except:
  75. pass
  76. @route('/setup', method=['GET', 'POST'])
  77. def setup():
  78. conn = pymysql.connect(
  79. user = set_data['user'],
  80. password = set_data['pw'],
  81. charset = 'utf8mb4'
  82. )
  83. curs = conn.cursor(pymysql.cursors.DictCursor)
  84. if(request.method == 'POST'):
  85. if(request.forms.owner != set_data['pw']):
  86. conn.close()
  87. return(redirect('/error/3'))
  88. else:
  89. try:
  90. curs.execute("use " + set_data['db'])
  91. except:
  92. curs.execute("create database " + set_data['db'])
  93. curs.execute("use " + set_data['db'])
  94. curs.execute("alter database " + set_data['db'] + " character set = utf8mb4 collate = utf8mb4_unicode_ci")
  95. curs.execute("create table data(title text, data longtext, acl text)")
  96. curs.execute("create table history(id text, title text, data longtext, date text, ip text, send text, leng text)")
  97. curs.execute("create table rd(title text, sub text, date text)")
  98. curs.execute("create table user(id text, pw text, acl text)")
  99. curs.execute("create table ban(block text, end text, why text, band text)")
  100. curs.execute("create table topic(id text, title text, sub text, data longtext, date text, ip text, block text, top text)")
  101. curs.execute("create table stop(title text, sub text, close text)")
  102. curs.execute("create table rb(block text, end text, today text, blocker text, why text)")
  103. curs.execute("create table login(user text, ip text, today text)")
  104. curs.execute("create table back(title text, link text, type text)")
  105. curs.execute("create table cat(title text, cat text)")
  106. curs.execute("create table hidhi(title text, re text)")
  107. curs.execute("create table agreedis(title text, sub text)")
  108. curs.execute("create table custom(user text, css longtext)")
  109. curs.execute("create table other(name text, data text)")
  110. curs.execute("create table alist(name text, acl text)")
  111. curs.execute("delete from alist where name = 'owner'")
  112. curs.execute("insert into alist (name, acl) value ('owner', 'owner')")
  113. curs.execute("delete from other where name = 'version'")
  114. curs.execute("insert into other (name, data) value ('version', '" + pymysql.escape_string(r_ver) + "')")
  115. conn.commit()
  116. conn.close()
  117. return(redirect('/'))
  118. else:
  119. conn.close()
  120. return(
  121. template('other',
  122. custom = custom_css_user(),
  123. license = set_data['license'],
  124. login = login_check(),
  125. logo = set_data['name'],
  126. data = '<form method="post"> \
  127. <input name="owner" type="password"> <button class="btn btn-primary" type="submit">저장</button> \
  128. </form>',
  129. title = '오픈나무 설치'
  130. )
  131. )
  132. @route('/image/<name:path>')
  133. def static(name = None):
  134. if(os.path.exists(os.path.join('image', name))):
  135. return(static_file(name, root = 'image'))
  136. else:
  137. return(redirect('/'))
  138. @route('/acl_list')
  139. def acl_list():
  140. conn = pymysql.connect(
  141. user = set_data['user'],
  142. password = set_data['pw'],
  143. charset = 'utf8mb4',
  144. db = set_data['db']
  145. )
  146. curs = conn.cursor(pymysql.cursors.DictCursor)
  147. div = '<div>'
  148. i = 0
  149. curs.execute("select title, acl from data where acl = 'admin' or acl = 'user' order by acl desc")
  150. list_data = curs.fetchall()
  151. if(list_data):
  152. for data in list_data:
  153. if(data['acl'] == 'admin'):
  154. acl = '관리자'
  155. else:
  156. acl = '로그인'
  157. div += '<li>' + str(i + 1) + '. <a href="/w/' + url_pas(data['title']) + '">' + data['title'] + '</a> (' + acl + ')</li>'
  158. i += 1
  159. else:
  160. div += '</div>'
  161. else:
  162. div = ''
  163. conn.close()
  164. return(
  165. template('other',
  166. custom = custom_css_user(),
  167. license = set_data['license'],
  168. login = login_check(),
  169. logo = set_data['name'],
  170. data = div,
  171. title = 'ACL 문서 목록'
  172. )
  173. )
  174. @route('/listacl')
  175. def list_acl():
  176. conn = pymysql.connect(
  177. user = set_data['user'],
  178. password = set_data['pw'],
  179. charset = 'utf8mb4',
  180. db = set_data['db']
  181. )
  182. curs = conn.cursor(pymysql.cursors.DictCursor)
  183. div = ''
  184. i = 0
  185. curs.execute("select * from alist order by name desc")
  186. list_data = curs.fetchall()
  187. if(list_data):
  188. for data in list_data:
  189. if(data['acl'] == 'ban'):
  190. acl = '차단'
  191. elif(data['acl'] == 'mdel'):
  192. acl = '많은 문서 삭제'
  193. elif(data['acl'] == 'toron'):
  194. acl = '토론 관리'
  195. elif(data['acl'] == 'check'):
  196. acl = '사용자 검사'
  197. elif(data['acl'] == 'acl'):
  198. acl = '문서 ACL'
  199. elif(data['acl'] == 'hidel'):
  200. acl = '역사 숨김'
  201. elif(data['acl'] == 'owner'):
  202. acl = '소유자'
  203. div += '<li>' + str(i + 1) + '. <a href="/adminplus/' + url_pas(data['name']) + '">' + data['name'] + '</a> (' + acl + ')</li>'
  204. i += 1
  205. else:
  206. div += '<br> \
  207. <a href="/manager/8">(생성)</a>'
  208. else:
  209. div += '<a href="/manager/8">(생성)</a>'
  210. conn.close()
  211. return(
  212. template('other',
  213. custom = custom_css_user(),
  214. license = set_data['license'],
  215. login = login_check(),
  216. logo = set_data['name'],
  217. data = div,
  218. title = 'ACL 목록'
  219. )
  220. )
  221. @route('/adminplus/<name:path>', method=['POST', 'GET'])
  222. def admin_plus(name = None):
  223. conn = pymysql.connect(
  224. user = set_data['user'],
  225. password = set_data['pw'],
  226. charset = 'utf8mb4',
  227. db = set_data['db']
  228. )
  229. curs = conn.cursor(pymysql.cursors.DictCursor)
  230. if(admin_check(None) == 1):
  231. if(request.method == 'POST'):
  232. curs.execute("delete from alist where name = '" + pymysql.escape_string(name) + "'")
  233. if(request.forms.ban):
  234. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'ban')")
  235. if(request.forms.mdel):
  236. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'mdel')")
  237. if(request.forms.toron):
  238. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'toron')")
  239. if(request.forms.check):
  240. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'check')")
  241. if(request.forms.acl):
  242. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'acl')")
  243. if(request.forms.hidel):
  244. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'hidel')")
  245. if(request.forms.owner):
  246. curs.execute("insert into alist (name, acl) value ('" + pymysql.escape_string(name) + "', 'owner')")
  247. conn.commit()
  248. conn.close()
  249. return(redirect('/adminplus/admin'))
  250. else:
  251. curs.execute('select acl from alist where name = "' + pymysql.escape_string(name) + '"')
  252. test = curs.fetchall()
  253. data = ''
  254. exist_list = ['', '', '', '', '', '', '', '', '']
  255. for go in test:
  256. if(go['acl'] == 'ban'):
  257. exist_list[0] = 'checked="checked"'
  258. elif(go['acl'] == 'mdel'):
  259. exist_list[1] = 'checked="checked"'
  260. elif(go['acl'] == 'toron'):
  261. exist_list[2] = 'checked="checked"'
  262. elif(go['acl'] == 'check'):
  263. exist_list[3] = 'checked="checked"'
  264. elif(go['acl'] == 'acl'):
  265. exist_list[4] = 'checked="checked"'
  266. elif(go['acl'] == 'hidel'):
  267. exist_list[5] = 'checked="checked"'
  268. elif(go['acl'] == 'owner'):
  269. exist_list[7] = 'checked="checked"'
  270. data += '<li><input type="checkbox" name="ban" ' + exist_list[0] + '> 차단</li>'
  271. data += '<li><input type="checkbox" name="mdel" ' + exist_list[1] + '> 많은 문서 삭제</li>'
  272. data += '<li><input type="checkbox" name="toron" ' + exist_list[2] + '> 토론 관리</li>'
  273. data += '<li><input type="checkbox" name="check" ' + exist_list[3] + '> 사용자 검사</li>'
  274. data += '<li><input type="checkbox" name="acl" ' + exist_list[4] + '> 문서 ACL</li>'
  275. data += '<li><input type="checkbox" name="hidel" ' + exist_list[5] + '> 역사 숨김</li>'
  276. data += '<li><input type="checkbox" name="owner" ' + exist_list[7] + '> 소유자</li>'
  277. conn.close()
  278. return(
  279. template('other',
  280. custom = custom_css_user(),
  281. license = set_data['license'],
  282. login = login_check(),
  283. title = '관리 그룹 추가',
  284. logo = set_data['name'],
  285. data = '<form method="post">' \
  286. + data + \
  287. '<div class="form-actions"> \
  288. <button class="btn btn-primary" type="submit">저장</button> \
  289. </div> \
  290. </form>'
  291. )
  292. )
  293. else:
  294. conn.close()
  295. return(redirect('/error/3'))
  296. @route('/admin_list')
  297. def admin_list():
  298. conn = pymysql.connect(
  299. user = set_data['user'],
  300. password = set_data['pw'],
  301. charset = 'utf8mb4',
  302. db = set_data['db']
  303. )
  304. curs = conn.cursor(pymysql.cursors.DictCursor)
  305. i = 1
  306. div = ''
  307. curs.execute("select * from user where not acl = 'user'")
  308. user_data = curs.fetchall()
  309. if(user_data):
  310. for data in user_data:
  311. name = ip_pas(data['id'], 2) + ' (' + data['acl'] + ')'
  312. div += '<li>' + str(i) + '. ' + name + '</li>'
  313. i += 1
  314. conn.close()
  315. return(
  316. template('other',
  317. custom = custom_css_user(),
  318. license = set_data['license'],
  319. login = login_check(),
  320. logo = set_data['name'],
  321. data = div,
  322. title = '관리자 목록'
  323. )
  324. )
  325. @route('/recentchanges')
  326. def recentchanges():
  327. conn = pymysql.connect(
  328. user = set_data['user'],
  329. password = set_data['pw'],
  330. charset = 'utf8mb4',
  331. db = set_data['db']
  332. )
  333. curs = conn.cursor(pymysql.cursors.DictCursor)
  334. ydmin = admin_check(1)
  335. zdmin = admin_check(6)
  336. div = '<table style="width: 100%; text-align: center;"> \
  337. <tbody> \
  338. <tr> \
  339. <td style="width: 33.3%;">문서명</td> \
  340. <td style="width: 33.3%;">기여자</td> \
  341. <td style="width: 33.3%;">시간</td> \
  342. </tr>'
  343. curs.execute("select id, title, date, ip, send, leng from history order by date desc limit 50")
  344. rows = curs.fetchall()
  345. if(rows):
  346. for data in rows:
  347. if(data['send']):
  348. if(re.search("^(?: *)$", data['send'])):
  349. send = '<br>'
  350. else:
  351. send = data['send']
  352. else:
  353. send = '<br>'
  354. title = data['title']
  355. title = re.sub('<', '&lt;', title)
  356. title = re.sub('>', '&gt;', title)
  357. title = re.sub('"', '&quot;', title)
  358. m = re.search("\+", data['leng'])
  359. n = re.search("\-", data['leng'])
  360. if(m):
  361. leng = '<span style="color:green;">' + data['leng'] + '</span>'
  362. elif(n):
  363. leng = '<span style="color:red;">' + data['leng'] + '</span>'
  364. else:
  365. leng = '<span style="color:gray;">' + data['leng'] + '</span>'
  366. if(ydmin == 1):
  367. curs.execute("select * from ban where block = '" + pymysql.escape_string(data['ip']) + "'")
  368. row = curs.fetchall()
  369. if(row):
  370. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(해제)</a>'
  371. else:
  372. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(차단)</a>'
  373. else:
  374. ban = ''
  375. ip = ip_pas(data['ip'], None)
  376. if((int(data['id']) - 1) == 0):
  377. revert = ''
  378. else:
  379. revert = '<a href="/w/' + url_pas(data['title']) + '/r/' + str(int(data['id']) - 1) + '/diff/' + data['id'] + '">(비교)</a> <a href="/revert/' + url_pas(data['title']) + '/r/' + str(int(data['id']) - 1) + '">(되돌리기)</a>'
  380. style = ''
  381. if(zdmin == 1):
  382. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(data['title']) + "' and re = '" + pymysql.escape_string(data['id']) + "'")
  383. row = curs.fetchall()
  384. if(row):
  385. ip += ' (숨김)'
  386. hidden = ' <a href="/history/' + url_pas(data['title']) + '/r/' + data['id'] + '/hidden">(공개)'
  387. else:
  388. hidden = ' <a href="/history/' + url_pas(data['title']) + '/r/' + data['id'] + '/hidden">(숨김)'
  389. else:
  390. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(data['title']) + "' and re = '" + pymysql.escape_string(data['id']) + "'")
  391. row = curs.fetchall()
  392. if(row):
  393. ip = '숨김'
  394. hidden = ''
  395. send = '숨김'
  396. ban = ''
  397. style = 'display:none;'
  398. else:
  399. hidden = ''
  400. div += '<tr style="' + style + '"> \
  401. <td> \
  402. <a href="/w/' + url_pas(data['title']) + '">' + title + '</a> (<a href="/history/' + url_pas(data['title']) + '">' + data['id'] + '판</a>) ' + revert + ' (' + leng + ') \
  403. </td> \
  404. <td>' + ip + ban + hidden + '</td> \
  405. <td>' + data['date'] + '</td> \
  406. </tr> \
  407. <tr> \
  408. <td colspan="3">' + send + '</td> \
  409. </tr>'
  410. else:
  411. div += '</tbody> \
  412. </table>'
  413. else:
  414. div = ''
  415. conn.close()
  416. return(
  417. template('other',
  418. custom = custom_css_user(),
  419. license = set_data['license'],
  420. login = login_check(),
  421. logo = set_data['name'],
  422. data = div,
  423. title = '최근 변경내역'
  424. )
  425. )
  426. @route('/history/<name:path>/r/<num:int>/hidden')
  427. def history_hidden(name = None, num = None):
  428. conn = pymysql.connect(
  429. user = set_data['user'],
  430. password = set_data['pw'],
  431. charset = 'utf8mb4',
  432. db = set_data['db']
  433. )
  434. curs = conn.cursor(pymysql.cursors.DictCursor)
  435. if(admin_check(6) == 1):
  436. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  437. exist = curs.fetchall()
  438. if(exist):
  439. curs.execute("delete from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  440. else:
  441. curs.execute("insert into hidhi (title, re) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(str(num)) + "')")
  442. conn.commit()
  443. conn.close()
  444. return(redirect('/history/' + url_pas(name)))
  445. @route('/record/<name:path>')
  446. @route('/record/<name:path>/n/<num:int>')
  447. def user_record(name = None, num = 1):
  448. conn = pymysql.connect(
  449. user = set_data['user'],
  450. password = set_data['pw'],
  451. charset = 'utf8mb4',
  452. db = set_data['db']
  453. )
  454. curs = conn.cursor(pymysql.cursors.DictCursor)
  455. if(num * 50 <= 0):
  456. v = 50
  457. else:
  458. v = num * 50
  459. i = v - 50
  460. ydmin = admin_check(1)
  461. zdmin = admin_check(6)
  462. div = '<table style="width: 100%; text-align: center;"> \
  463. <tbody> \
  464. <tr> \
  465. <td style="width: 33.3%;">문서명</td> \
  466. <td style="width: 33.3%;">기여자</td> \
  467. <td style="width: 33.3%;">시간</td> \
  468. </tr>'
  469. curs.execute("select * from history where ip = '" + pymysql.escape_string(name) + "' order by date desc limit " + str(i) + ", " + str(v))
  470. rows = curs.fetchall()
  471. if(rows):
  472. for data in rows:
  473. if(data['send']):
  474. send = data['send']
  475. send = re.sub('<a href="\/w\/(?P<in>[^"]*)">(?P<out>[^&]*)<\/a>', '<a href="/w/\g<in>">\g<out></a>', send)
  476. else:
  477. send = '<br>'
  478. title = data['title']
  479. title = re.sub('<', '&lt;', title)
  480. title = re.sub('>', '&gt;', title)
  481. title = re.sub('"', '&quot;', title)
  482. m = re.search("\+", data['leng'])
  483. n = re.search("\-", data['leng'])
  484. if(m):
  485. leng = '<span style="color:green;">' + data['leng'] + '</span>'
  486. elif(n):
  487. leng = '<span style="color:red;">' + data['leng'] + '</span>'
  488. else:
  489. leng = '<span style="color:gray;">' + data['leng'] + '</span>'
  490. if(ydmin == 1):
  491. curs.execute("select * from ban where block = '" + pymysql.escape_string(data['ip']) + "'")
  492. row = curs.fetchall()
  493. if(row):
  494. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(해제)</a>'
  495. else:
  496. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(차단)</a>'
  497. else:
  498. ban = ''
  499. ip = ip_pas(data['ip'], None)
  500. if((int(data['id']) - 1) == 0):
  501. revert = ''
  502. else:
  503. revert = '<a href="/revert/' + url_pas(data['title']) + '/r/' + str(int(data['id']) - 1) + '">(되돌리기)</a>'
  504. style = ''
  505. if(zdmin == 1):
  506. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(data['title']) + "' and re = '" + pymysql.escape_string(data['id']) + "'")
  507. row = curs.fetchall()
  508. if(row):
  509. ip += ' (숨김)'
  510. hidden = ' <a href="/history/' + url_pas(data['title']) + '/r/' + data['id'] + '/hidden">(공개)'
  511. else:
  512. hidden = ' <a href="/history/' + url_pas(data['title']) + '/r/' + data['id'] + '/hidden">(숨김)'
  513. else:
  514. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(data['title']) + "' and re = '" + pymysql.escape_string(data['id']) + "'")
  515. row = curs.fetchall()
  516. if(row):
  517. ip = '숨김'
  518. hidden = ''
  519. send = '숨김'
  520. ban = ''
  521. style = 'display:none;'
  522. else:
  523. hidden = ''
  524. div += '<tr style="' + style + '"> \
  525. <td> \
  526. <a href="/w/' + url_pas(data['title']) + '">' + title + '</a> (<a href="/history/' + url_pas(data['title']) + '">' + data['id'] + '판</a>) \
  527. <a href="/w/' + url_pas(data['title']) + '/r/' + str(int(data['id']) - 1) + '/diff/' + data['id'] + '">(비교)</a> ' + revert + ' (' + leng + ') \
  528. </td> \
  529. <td>' + ip + ban + hidden + '</td> \
  530. <td>' + data['date'] + '</td> \
  531. </tr> \
  532. <tr> \
  533. <td colspan="3">' + send + '</td> \
  534. </tr>'
  535. else:
  536. div += '</tbody> \
  537. </table>'
  538. else:
  539. div = ''
  540. div += '<br> \
  541. <a href="/record/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)</a> <a href="/record/' + url_pas(name) + '/n/' + str(num + 1) + '">(이후)</a>'
  542. curs.execute("select end, why from ban where block = '" + pymysql.escape_string(name) + "'")
  543. ban_it = curs.fetchall()
  544. if(ban_it):
  545. sub = '차단'
  546. else:
  547. sub = None
  548. conn.close()
  549. return(
  550. template('other',
  551. custom = custom_css_user(),
  552. license = set_data['license'],
  553. login = login_check(),
  554. logo = set_data['name'],
  555. data = div,
  556. title = '사용자 기록',
  557. sub = sub
  558. )
  559. )
  560. @route('/userlog')
  561. @route('/userlog/n/<num:int>')
  562. def user_log(num = 1):
  563. conn = pymysql.connect(
  564. user = set_data['user'],
  565. password = set_data['pw'],
  566. charset = 'utf8mb4',
  567. db = set_data['db']
  568. )
  569. curs = conn.cursor(pymysql.cursors.DictCursor)
  570. if(num * 50 <= 0):
  571. i = 50
  572. else:
  573. i = num * 50
  574. j = i - 50
  575. list_data = ''
  576. ydmin = admin_check(1)
  577. curs.execute("select * from user limit " + str(j) + ", " + str(i))
  578. user_list = curs.fetchall()
  579. for data in user_list:
  580. if(ydmin == 1):
  581. curs.execute("select * from ban where block = '" + pymysql.escape_string(data['id']) + "'")
  582. ban_exist = curs.fetchall()
  583. if(ban_exist):
  584. ban_button = ' <a href="/ban/' + url_pas(data['id']) + '">(해제)</a>'
  585. else:
  586. ban_button = ' <a href="/ban/' + url_pas(data['id']) + '">(차단)</a>'
  587. else:
  588. ban_button = ''
  589. ip = ip_pas(data['id'], None)
  590. list_data += '<li>' + str(j + 1) + '. ' + ip + ban_button + '</li>'
  591. j += 1
  592. else:
  593. list_data += '<br> \
  594. <a href="/userlog/n/' + str(num - 1) + '">(이전)</a> <a href="/userlog/n/' + str(num + 1) + '">(이후)</a>'
  595. conn.close()
  596. return(
  597. template('other',
  598. custom = custom_css_user(),
  599. license = set_data['license'],
  600. login = login_check(),
  601. logo = set_data['name'],
  602. data = list_data,
  603. title = '사용자 가입 기록'
  604. )
  605. )
  606. @route('/backreset')
  607. def xref_reset():
  608. conn = pymysql.connect(
  609. user = set_data['user'],
  610. password = set_data['pw'],
  611. charset = 'utf8mb4',
  612. db = set_data['db']
  613. )
  614. curs = conn.cursor(pymysql.cursors.DictCursor)
  615. if(admin_check(None) == 1):
  616. curs.execute("delete from back")
  617. curs.execute("delete from cat")
  618. conn.commit()
  619. curs.execute("select title, data from data")
  620. data = curs.fetchall()
  621. for end in data:
  622. print(end['title'])
  623. namumark(end['title'], end['data'], 1)
  624. conn.close()
  625. return(redirect('/'))
  626. else:
  627. conn.close()
  628. return(redirect('/error/3'))
  629. @route('/xref/<name:path>')
  630. @route('/xref/<name:path>/n/<num:int>')
  631. def xref(name = None, num = 1):
  632. conn = pymysql.connect(
  633. user = set_data['user'],
  634. password = set_data['pw'],
  635. charset = 'utf8mb4',
  636. db = set_data['db']
  637. )
  638. curs = conn.cursor(pymysql.cursors.DictCursor)
  639. if(num * 50 <= 0):
  640. v = 50
  641. else:
  642. v = num * 50
  643. i = v - 50
  644. div = ''
  645. curs.execute("delete from back where title = '" + pymysql.escape_string(name) + "' and link = ''")
  646. conn.commit()
  647. curs.execute("select * from back where title = '" + pymysql.escape_string(name) + "' order by link asc limit " + str(i) + ", " + str(v))
  648. rows = curs.fetchall()
  649. for data in rows:
  650. div += '<li><a href="/w/' + url_pas(data['link']) + '">' + data['link'] + '</a>'
  651. if(data['type']):
  652. div += ' (' + data['type'] + ')</li>'
  653. else:
  654. div += '</li>'
  655. else:
  656. div += '<br> \
  657. <a href="/xref/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)</a> <a href="/xref/' + url_pas(name) + '/n/' + str(num + 1) + '">(이후)</a>'
  658. conn.close()
  659. return(
  660. template('other',
  661. custom = custom_css_user(),
  662. license = set_data['license'],
  663. login = login_check(),
  664. logo = set_data['name'],
  665. data = div,
  666. title = name,
  667. page = url_pas(name),
  668. sub = '역링크'
  669. )
  670. )
  671. @route('/recentdiscuss')
  672. def recentdiscuss():
  673. conn = pymysql.connect(
  674. user = set_data['user'],
  675. password = set_data['pw'],
  676. charset = 'utf8mb4',
  677. db = set_data['db']
  678. )
  679. curs = conn.cursor(pymysql.cursors.DictCursor)
  680. div = '<table style="width: 100%; text-align: center;"> \
  681. <tbody> \
  682. <tr> \
  683. <td style="width: 50%;">토론명</td> \
  684. <td style="width: 50%;">시간</td> \
  685. </tr>'
  686. curs.execute("select * from rd order by date desc limit 50")
  687. rows = curs.fetchall()
  688. for data in rows:
  689. title = data['title']
  690. title = re.sub('<', '&lt;', title)
  691. title = re.sub('>', '&gt;', title)
  692. title = re.sub('"', '&quot;', title)
  693. sub = data['sub']
  694. sub = re.sub('<', '&lt;', sub)
  695. sub = re.sub('>', '&gt;', sub)
  696. sub = re.sub('"', '&quot;', sub)
  697. div += '<tr> \
  698. <td> \
  699. <a href="/topic/' + url_pas(data['title']) + '/sub/' + url_pas(data['sub']) + '">' + title + '</a> (' + sub + ') \
  700. </td> \
  701. <td>' + data['date'] + '</td> \
  702. </tr>'
  703. else:
  704. div += '</tbody> \
  705. </table>'
  706. conn.close()
  707. return(
  708. template('other',
  709. custom = custom_css_user(),
  710. license = set_data['license'],
  711. login = login_check(),
  712. logo = set_data['name'],
  713. data = div,
  714. title = '최근 토론내역'
  715. )
  716. )
  717. @route('/blocklog')
  718. @route('/blocklog/n/<number:int>')
  719. def blocklog(num = 1):
  720. conn = pymysql.connect(
  721. user = set_data['user'],
  722. password = set_data['pw'],
  723. charset = 'utf8mb4',
  724. db = set_data['db']
  725. )
  726. curs = conn.cursor(pymysql.cursors.DictCursor)
  727. if(num * 50 <= 0):
  728. v = 50
  729. else:
  730. v = num * 50
  731. i = v - 50
  732. div = '<table style="width: 100%; text-align: center;"> \
  733. <tbody> \
  734. <tr> \
  735. <td style="width: 20%;">차단자</td> \
  736. <td style="width: 20%;">관리자</td> \
  737. <td style="width: 20%;">기간</td> \
  738. <td style="width: 20%;">이유</td> \
  739. <td style="width: 20%;">시간</td> \
  740. </tr>'
  741. curs.execute("select * from rb order by today desc limit " + str(i) + ", " + str(v))
  742. rows = curs.fetchall()
  743. for data in rows:
  744. why = data['why']
  745. why = re.sub('<', '&lt;', why)
  746. why = re.sub('>', '&gt;', why)
  747. why = re.sub('"', '&quot;', why)
  748. b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data['block'])
  749. if(b):
  750. ip = data['block'] + ' (대역)'
  751. else:
  752. ip = data['block']
  753. div += '<tr> \
  754. <td>' + ip + '</td> \
  755. <td>' + data['blocker'] + '</td> \
  756. <td>' + data['end'] + '</td> \
  757. <td>' + data['why'] + '</td> \
  758. <td>' + data['today'] + '</td> \
  759. </tr>'
  760. else:
  761. div += '</tbody> \
  762. </table> \
  763. <br> \
  764. <a href="/xref/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)</a> <a href="/xref/' + url_pas(name) + '/n/' + str(num + 1) + '">(이후)</a>'
  765. conn.close()
  766. return(
  767. template('other',
  768. custom = custom_css_user(),
  769. license = set_data['license'],
  770. login = login_check(),
  771. logo = set_data['name'],
  772. data = div,
  773. title = '사용자 차단 기록'
  774. )
  775. )
  776. @route('/history/<name:path>', method=['POST', 'GET'])
  777. @route('/history/<name:path>/n/<num:int>', method=['POST', 'GET'])
  778. def history_view(name = None, num = 1):
  779. conn = pymysql.connect(
  780. user = set_data['user'],
  781. password = set_data['pw'],
  782. charset = 'utf8mb4',
  783. db = set_data['db']
  784. )
  785. curs = conn.cursor(pymysql.cursors.DictCursor)
  786. if(request.method == 'POST'):
  787. conn.close()
  788. return(redirect('/w/' + url_pas(name) + '/r/' + request.forms.b + '/diff/' + request.forms.a))
  789. else:
  790. select = ''
  791. if(num * 50 <= 0):
  792. i = 50
  793. else:
  794. i = num * 50
  795. j = i - 50
  796. admin1 = admin_check(1)
  797. admin2 = admin_check(6)
  798. div = '<table style="width: 100%; text-align: center;"> \
  799. <tbody> \
  800. <tr> \
  801. <td style="width: 33.3%;">판</td> \
  802. <td style="width: 33.3%;">기여자</td> \
  803. <td style="width: 33.3%;">시간</td> \
  804. </tr>'
  805. curs.execute("select send, leng, ip, date, title, id from history where title = '" + pymysql.escape_string(name) + "' order by id + 0 desc limit " + str(j) + ", " + str(i))
  806. all_data = curs.fetchall()
  807. for data in all_data:
  808. select += '<option value="' + data['id'] + '">' + data['id'] + '</option>'
  809. if(data['send']):
  810. send = data['send']
  811. else:
  812. send = '<br>'
  813. if(re.search("^\+", data['leng'])):
  814. leng = '<span style="color:green;">' + data['leng'] + '</span>'
  815. elif(re.search("^\-", data['leng'])):
  816. leng = '<span style="color:red;">' + data['leng'] + '</span>'
  817. else:
  818. leng = '<span style="color:gray;">' + data['leng'] + '</span>'
  819. ip = ip_pas(data['ip'], None)
  820. curs.execute("select block from ban where block = '" + pymysql.escape_string(data['ip']) + "'")
  821. ban_it = curs.fetchall()
  822. if(ban_it):
  823. if(admin1 == 1):
  824. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(해제)</a>'
  825. else:
  826. ban = ' (X)'
  827. else:
  828. if(admin1 == 1):
  829. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(차단)</a>'
  830. else:
  831. ban = ''
  832. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(data['id']) + "'")
  833. hid_it = curs.fetchall()
  834. if(hid_it):
  835. if(admin2):
  836. hidden = ' <a href="/history/' + url_pas(name) + '/r/' + url_pas(data['id']) + '/hidden">(공개)'
  837. hid = 0
  838. else:
  839. hid = 1
  840. else:
  841. if(admin2):
  842. hidden = ' <a href="/history/' + url_pas(name) + '/r/' + url_pas(data['id']) + '/hidden">(숨김)'
  843. hid = 0
  844. else:
  845. hidden = ''
  846. hid = 0
  847. if(hid == 1):
  848. div += '<tr> \
  849. <td colspan="3">숨김</td> \
  850. </tr>'
  851. else:
  852. div += '<tr> \
  853. <td> \
  854. ' + data['id'] + '판</a> <a href="/w/' + url_pas(data['title']) + '/r/' + url_pas(data['id']) + '">(보기)</a> \
  855. <a href="/raw/' + url_pas(data['title']) + '/r/' + url_pas(data['id']) + '">(원본)</a> \
  856. <a href="/revert/' + url_pas(data['title']) + '/r/' + url_pas(data['id']) + '">(되돌리기)</a> (' + leng + ') \
  857. </td> \
  858. <td>' + ip + ban + hidden + '</td> \
  859. <td>' + data['date'] + '</td> \
  860. </tr> \
  861. <tr> \
  862. <td colspan="3">' + send + '</td> \
  863. </tr>'
  864. else:
  865. div += '</tbody> \
  866. </table> \
  867. <br> \
  868. <a href="/history/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)</a> <a href="/history/' + url_pas(name) + '/n/' + str(num + 1) + '">(이후)</a>'
  869. conn.close()
  870. return(
  871. template('other',
  872. custom = custom_css_user(),
  873. license = set_data['license'],
  874. login = login_check(),
  875. logo = set_data['name'],
  876. data = div,
  877. title = name,
  878. page = url_pas(name),
  879. select = select,
  880. sub = '역사'
  881. )
  882. )
  883. @route('/search', method=['POST'])
  884. def search():
  885. return(redirect('/search/' + url_pas(request.forms.search)))
  886. @route('/goto', method=['POST'])
  887. def goto():
  888. conn = pymysql.connect(
  889. user = set_data['user'],
  890. password = set_data['pw'],
  891. charset = 'utf8mb4',
  892. db = set_data['db']
  893. )
  894. curs = conn.cursor(pymysql.cursors.DictCursor)
  895. curs.execute("select title from data where title = '" + pymysql.escape_string(request.forms.search) + "'")
  896. data = curs.fetchall()
  897. conn.close()
  898. if(data):
  899. return(redirect('/w/' + url_pas(request.forms.search)))
  900. else:
  901. return(redirect('/search/' + url_pas(request.forms.search)))
  902. @route('/search/<name:path>')
  903. @route('/search/<name:path>/n/<num:int>')
  904. def deep_search(name = None, num = 1):
  905. conn = pymysql.connect(
  906. user = set_data['user'],
  907. password = set_data['pw'],
  908. charset = 'utf8mb4',
  909. db = set_data['db']
  910. )
  911. curs = conn.cursor(pymysql.cursors.DictCursor)
  912. if(num * 50 <= 0):
  913. v = num * 50
  914. else:
  915. v = 50
  916. i = v - 50
  917. div = ''
  918. div_plus = ''
  919. end = ''
  920. curs.execute("select title from data where title like '%" + pymysql.escape_string(name) + "%'")
  921. title_list = curs.fetchall()
  922. curs.execute("select title from data where data like '%" + pymysql.escape_string(name) + "%'")
  923. data_list = curs.fetchall()
  924. curs.execute("select title from data where title = '" + pymysql.escape_string(name) + "'")
  925. exist = curs.fetchall()
  926. if(exist):
  927. div = '<li>문서로 <a href="/w/' + url_pas(name) + '">바로가기</a></li> \
  928. <br>'
  929. else:
  930. div = '<li>문서가 없습니다. <a class="not_thing" href="/w/' + url_pas(name) + '">바로가기</a></li> \
  931. <br>'
  932. if(title_list):
  933. no = 0
  934. if(data_list):
  935. all_list = title_list + data_list
  936. else:
  937. all_list = title_list
  938. else:
  939. if(data_list):
  940. no = 1
  941. all_list = data_list
  942. else:
  943. all_list = ''
  944. if(all_list != ''):
  945. for data in all_list:
  946. re_title = re.compile(name, re.I)
  947. if(re.search(re_title, data['title'])):
  948. if(no == 0):
  949. div += '<li><a href="/w/' + url_pas(data['title']) + '">' + data['title'] + '</a> (문서명)</li>'
  950. else:
  951. div_plus += '<li><a href="/w/' + url_pas(data['title']) + '">' + data['title'] + '</a> (내용)</li>'
  952. else:
  953. no = 1
  954. div_plus += '<li><a href="/w/' + url_pas(data['title']) + '">' + data['title'] + '</a> (내용)</li>'
  955. else:
  956. div += '<li>검색 결과 없음</li>'
  957. div += div_plus + end
  958. div += '<br> \
  959. <a href="/search/' + url_pas(name) + '/n/' + str(num - 1) + '">(이전)</a> <a href="/search/' + url_pas(name) + '/n/' + str(num + 1) + '">(이후)</a>'
  960. conn.close()
  961. return(
  962. template('other',
  963. custom = custom_css_user(),
  964. license = set_data['license'],
  965. login = login_check(),
  966. logo = set_data['name'],
  967. data = div,
  968. title = name,
  969. sub = '검색'
  970. )
  971. )
  972. @route('/raw/<name:path>')
  973. @route('/raw/<name:path>/r/<num:int>')
  974. def raw_view(name = None, num = None):
  975. conn = pymysql.connect(
  976. user = set_data['user'],
  977. password = set_data['pw'],
  978. charset = 'utf8mb4',
  979. db = set_data['db']
  980. )
  981. curs = conn.cursor(pymysql.cursors.DictCursor)
  982. if(num):
  983. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  984. hid = curs.fetchall()
  985. if(hid):
  986. if(admin_check(6) != 1):
  987. conn.close()
  988. return(redirect('/error/3'))
  989. curs.execute("select * from history where title = '" + pymysql.escape_string(name) + "' and id = '" + str(num) + "'")
  990. else:
  991. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  992. rows = curs.fetchall()
  993. if(rows):
  994. enddata = re.sub('<', '&lt;', rows[0]['data'])
  995. enddata = re.sub('>', '&gt;', enddata)
  996. enddata = re.sub('"', '&quot;', enddata)
  997. enddata = '<textarea style="height: 80%;">' + enddata + '</textarea>'
  998. conn.close()
  999. return(
  1000. template('other',
  1001. custom = custom_css_user(),
  1002. license = set_data['license'],
  1003. login = login_check(),
  1004. title = name,
  1005. logo = set_data['name'],
  1006. page = url_pas(name),
  1007. data = enddata,
  1008. sub = '원본'
  1009. )
  1010. )
  1011. else:
  1012. conn.close()
  1013. return(redirect('/w/' + url_pas(name)))
  1014. @route('/revert/<name:path>/r/<num:int>', method=['POST', 'GET'])
  1015. def revert(name = None, num = None):
  1016. conn = pymysql.connect(
  1017. user = set_data['user'],
  1018. password = set_data['pw'],
  1019. charset = 'utf8mb4',
  1020. db = set_data['db']
  1021. )
  1022. curs = conn.cursor(pymysql.cursors.DictCursor)
  1023. ip = ip_check()
  1024. can = acl_check(ip, name)
  1025. today = get_time()
  1026. if(request.method == 'POST'):
  1027. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  1028. row = curs.fetchall()
  1029. if(row):
  1030. if(admin_check(6) != 1):
  1031. conn.close()
  1032. return(redirect('/error/3'))
  1033. if(can == 1):
  1034. conn.close()
  1035. return(redirect('/ban'))
  1036. else:
  1037. curs.execute("delete from back where link = '" + pymysql.escape_string(name) + "'")
  1038. curs.execute("delete from cat where cat = '" + pymysql.escape_string(name) + "'")
  1039. conn.commit()
  1040. curs.execute("select * from history where title = '" + pymysql.escape_string(name) + "' and id = '" + str(num) + "'")
  1041. rows = curs.fetchall()
  1042. if(rows):
  1043. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1044. row = curs.fetchall()
  1045. if(row):
  1046. leng = leng_check(len(row[0]['data']), len(rows[0]['data']))
  1047. curs.execute("update data set data = '" + pymysql.escape_string(rows[0]['data']) + "' where title = '" + pymysql.escape_string(name) + "'")
  1048. conn.commit()
  1049. else:
  1050. leng = '+' + str(len(rows[0]['data']))
  1051. curs.execute("insert into data (title, data, acl) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(rows[0]['data']) + "', '')")
  1052. conn.commit()
  1053. history_plus(
  1054. name,
  1055. rows[0]['data'],
  1056. today,
  1057. ip,
  1058. '문서를 ' + str(num) + '판으로 되돌렸습니다.',
  1059. leng
  1060. )
  1061. conn.close()
  1062. return(redirect('/w/' + url_pas(name)))
  1063. else:
  1064. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  1065. row = curs.fetchall()
  1066. if(row):
  1067. if(admin_check(6) != 1):
  1068. conn.close()
  1069. return(redirect('/error/3'))
  1070. if(can == 1):
  1071. conn.close()
  1072. return(redirect('/ban'))
  1073. else:
  1074. curs.execute("select * from history where title = '" + pymysql.escape_string(name) + "' and id = '" + str(num) + "'")
  1075. rows = curs.fetchall()
  1076. if(rows):
  1077. conn.close()
  1078. return(
  1079. template('revert',
  1080. custom = custom_css_user(),
  1081. license = set_data['license'],
  1082. login = login_check(),
  1083. title = name,
  1084. logo = set_data['name'],
  1085. page = url_pas(name),
  1086. r = url_pas(str(num)),
  1087. plus = '정말 되돌리시겠습니까?',
  1088. sub = '되돌리기'
  1089. )
  1090. )
  1091. else:
  1092. conn.close()
  1093. return(redirect('/w/' + url_pas(name)))
  1094. @route('/mdel', method=['POST', 'GET'])
  1095. def many_del():
  1096. conn = pymysql.connect(
  1097. user = set_data['user'],
  1098. password = set_data['pw'],
  1099. charset = 'utf8mb4',
  1100. db = set_data['db']
  1101. )
  1102. curs = conn.cursor(pymysql.cursors.DictCursor)
  1103. today = get_time()
  1104. ip = ip_check()
  1105. if(admin_check(2) == 1):
  1106. if(request.method == 'POST'):
  1107. data = request.forms.content + '\r\n'
  1108. m = re.findall('(.*)\r\n', data)
  1109. for g in m:
  1110. curs.execute("select data from data where title = '" + pymysql.escape_string(g) + "'")
  1111. rows = curs.fetchall()
  1112. if(rows):
  1113. curs.execute("delete from back where title = '" + pymysql.escape_string(g) + "'")
  1114. curs.execute("delete from cat where title = '" + pymysql.escape_string(g) + "'")
  1115. leng = '-' + str(len(rows[0]['data']))
  1116. curs.execute("delete from data where title = '" + pymysql.escape_string(g) + "'")
  1117. history_plus(
  1118. g,
  1119. '',
  1120. today,
  1121. ip,
  1122. request.forms.send + ' (대량 삭제)',
  1123. leng
  1124. )
  1125. data = re.sub('(.*)\r\n', '', data, 1)
  1126. conn.commit()
  1127. conn.close()
  1128. return(redirect('/'))
  1129. else:
  1130. conn.close()
  1131. return(
  1132. template('mdel',
  1133. custom = custom_css_user(),
  1134. license = set_data['license'],
  1135. login = login_check(),
  1136. title = '많은 문서 삭제',
  1137. logo = set_data['name']
  1138. )
  1139. )
  1140. else:
  1141. conn.close()
  1142. return(redirect('/error/3'))
  1143. @route('/edit/<name:path>/section/<num:int>', method=['POST', 'GET'])
  1144. def section_edit(name = None, num = None):
  1145. conn = pymysql.connect(
  1146. user = set_data['user'],
  1147. password = set_data['pw'],
  1148. charset = 'utf8mb4',
  1149. db = set_data['db']
  1150. )
  1151. curs = conn.cursor(pymysql.cursors.DictCursor)
  1152. ip = ip_check()
  1153. can = acl_check(ip, name)
  1154. if(request.method == 'POST'):
  1155. if(len(request.forms.send) > 500):
  1156. conn.close()
  1157. return(redirect('/error/15'))
  1158. else:
  1159. today = get_time()
  1160. content = savemark(request.forms.content)
  1161. curs.execute("delete from back where link = '" + pymysql.escape_string(name) + "'")
  1162. curs.execute("delete from cat where cat = '" + pymysql.escape_string(name) + "'")
  1163. conn.commit()
  1164. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1165. rows = curs.fetchall()
  1166. if(rows):
  1167. if(request.forms.otent == content):
  1168. conn.close()
  1169. return(redirect('/error/18'))
  1170. else:
  1171. if(can == 1):
  1172. conn.close()
  1173. return(redirect('/ban'))
  1174. else:
  1175. leng = leng_check(len(request.forms.otent), len(content))
  1176. content = rows[0]['data'].replace(request.forms.otent, content)
  1177. history_plus(
  1178. name,
  1179. content,
  1180. today,
  1181. ip,
  1182. html_pas(request.forms.send, 2),
  1183. leng
  1184. )
  1185. curs.execute("update data set data = '" + pymysql.escape_string(content) + "' where title = '" + pymysql.escape_string(name) + "'")
  1186. conn.commit()
  1187. include_check(name, content)
  1188. conn.close()
  1189. return(redirect('/w/' + url_pas(name)))
  1190. else:
  1191. conn.close()
  1192. return(redirect('/w/' + url_pas(name)))
  1193. else:
  1194. if(can == 1):
  1195. conn.close()
  1196. return(redirect('/ban'))
  1197. else:
  1198. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1199. rows = curs.fetchall()
  1200. if(rows):
  1201. i = 0
  1202. j = 0
  1203. gdata = rows[0]['data'] + '\r\n'
  1204. while(1):
  1205. m = re.search("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", gdata)
  1206. if(m):
  1207. if(i == num - 1):
  1208. g = m.groups()
  1209. gdata = re.sub("\r\n$", "", g[0])
  1210. break
  1211. else:
  1212. gdata = re.sub("((?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n(?:(?:(?:(?!(?:={1,6})\s?(?:[^=]*)\s?(?:={1,6})(?:\s+)?\n).)*)(?:\n)?)+)", "", gdata, 1)
  1213. i += 1
  1214. else:
  1215. j = 1
  1216. break
  1217. if(j == 0):
  1218. gdata = re.sub("\r\n$", "", gdata)
  1219. conn.close()
  1220. return(
  1221. template('edit',
  1222. custom = custom_css_user(),
  1223. license = set_data['license'],
  1224. login = login_check(),
  1225. title = name,
  1226. logo = set_data['name'],
  1227. page = url_pas(name),
  1228. data = gdata,
  1229. section = 1,
  1230. number = num,
  1231. sub = '편집'
  1232. )
  1233. )
  1234. else:
  1235. conn.close()
  1236. return(redirect('/w/' + url_pas(name)))
  1237. else:
  1238. conn.close()
  1239. return(redirect('/w/' + url_pas(name)))
  1240. @route('/edit/<name:path>', method=['POST', 'GET'])
  1241. def edit(name = None):
  1242. conn = pymysql.connect(
  1243. user = set_data['user'],
  1244. password = set_data['pw'],
  1245. charset = 'utf8mb4',
  1246. db = set_data['db']
  1247. )
  1248. curs = conn.cursor(pymysql.cursors.DictCursor)
  1249. ip = ip_check()
  1250. can = acl_check(ip, name)
  1251. if(request.method == 'POST'):
  1252. if(len(request.forms.send) > 500):
  1253. conn.close()
  1254. return(redirect('/error/15'))
  1255. else:
  1256. today = get_time()
  1257. content = savemark(request.forms.content)
  1258. curs.execute("delete from back where link = '" + pymysql.escape_string(name) + "'")
  1259. curs.execute("delete from cat where cat = '" + pymysql.escape_string(name) + "'")
  1260. conn.commit()
  1261. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1262. rows = curs.fetchall()
  1263. if(rows):
  1264. if(rows[0]['data'] == content):
  1265. conn.close()
  1266. return(redirect('/error/18'))
  1267. else:
  1268. if(can == 1):
  1269. conn.close()
  1270. return(redirect('/ban'))
  1271. else:
  1272. leng = leng_check(len(rows[0]['data']), len(content))
  1273. history_plus(
  1274. name,
  1275. content,
  1276. today,
  1277. ip,
  1278. html_pas(request.forms.send, 2),
  1279. leng
  1280. )
  1281. curs.execute("update data set data = '" + pymysql.escape_string(content) + "' where title = '" + pymysql.escape_string(name) + "'")
  1282. conn.commit()
  1283. else:
  1284. if(can == 1):
  1285. conn.close()
  1286. return(redirect('/ban'))
  1287. else:
  1288. leng = '+' + str(len(content))
  1289. history_plus(
  1290. name,
  1291. content,
  1292. today,
  1293. ip,
  1294. html_pas(request.forms.send, 2),
  1295. leng
  1296. )
  1297. curs.execute("insert into data (title, data, acl) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(content) + "', '')")
  1298. conn.commit()
  1299. include_check(name, content)
  1300. conn.close()
  1301. return(redirect('/w/' + url_pas(name)))
  1302. else:
  1303. if(can == 1):
  1304. conn.close()
  1305. return(redirect('/ban'))
  1306. else:
  1307. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1308. rows = curs.fetchall()
  1309. if(rows):
  1310. data = rows[0]['data']
  1311. else:
  1312. data = ''
  1313. conn.close()
  1314. return(
  1315. template('edit',
  1316. custom = custom_css_user(),
  1317. license = set_data['license'],
  1318. login = login_check(),
  1319. title = name,
  1320. logo = set_data['name'],
  1321. page = url_pas(name),
  1322. data = data,
  1323. sub = '편집'
  1324. )
  1325. )
  1326. @route('/preview/<name:path>/section/<num:int>', method=['POST'])
  1327. def section_preview(name = None, num = None):
  1328. conn = pymysql.connect(
  1329. user = set_data['user'],
  1330. password = set_data['pw'],
  1331. charset = 'utf8mb4',
  1332. db = set_data['db']
  1333. )
  1334. curs = conn.cursor(pymysql.cursors.DictCursor)
  1335. ip = ip_check()
  1336. can = acl_check(ip, name)
  1337. if(can == 1):
  1338. conn.close()
  1339. return(redirect('/ban'))
  1340. else:
  1341. newdata = request.forms.content
  1342. newdata = re.sub('^#(?:redirect|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', newdata)
  1343. enddata = namumark(name, newdata, 0)
  1344. conn.close()
  1345. return(
  1346. template('edit',
  1347. custom = custom_css_user(),
  1348. license = set_data['license'],
  1349. login = login_check(),
  1350. title = name,
  1351. logo = set_data['name'],
  1352. page = url_pas(name),
  1353. data = request.forms.content,
  1354. preview = 1,
  1355. enddata = enddata,
  1356. section = 1,
  1357. number = num,
  1358. odata = request.forms.otent,
  1359. sub = '미리보기'
  1360. )
  1361. )
  1362. @route('/preview/<name:path>', method=['POST'])
  1363. def preview(name = None):
  1364. conn = pymysql.connect(
  1365. user = set_data['user'],
  1366. password = set_data['pw'],
  1367. charset = 'utf8mb4',
  1368. db = set_data['db']
  1369. )
  1370. curs = conn.cursor(pymysql.cursors.DictCursor)
  1371. ip = ip_check()
  1372. can = acl_check(ip, name)
  1373. if(can == 1):
  1374. conn.close()
  1375. return(redirect('/ban'))
  1376. else:
  1377. newdata = request.forms.content
  1378. newdata = re.sub('^#(?:redirect|넘겨주기)\s(?P<in>[^\n]*)', ' * [[\g<in>]] 문서로 넘겨주기', newdata)
  1379. enddata = namumark(name, newdata, 0)
  1380. conn.close()
  1381. return(
  1382. template('edit',
  1383. custom = custom_css_user(),
  1384. license = set_data['license'],
  1385. login = login_check(),
  1386. title = name,
  1387. logo = set_data['name'],
  1388. page = url_pas(name),
  1389. data = request.forms.content,
  1390. preview = 1,
  1391. enddata = enddata,
  1392. sub = '미리보기'
  1393. )
  1394. )
  1395. @route('/delete/<name:path>', method=['POST', 'GET'])
  1396. def delete(name = None):
  1397. conn = pymysql.connect(
  1398. user = set_data['user'],
  1399. password = set_data['pw'],
  1400. charset = 'utf8mb4',
  1401. db = set_data['db']
  1402. )
  1403. curs = conn.cursor(pymysql.cursors.DictCursor)
  1404. ip = ip_check()
  1405. can = acl_check(ip, name)
  1406. if(request.method == 'POST'):
  1407. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1408. rows = curs.fetchall()
  1409. if(rows):
  1410. if(can == 1):
  1411. conn.close()
  1412. return(redirect('/ban'))
  1413. else:
  1414. today = get_time()
  1415. curs.execute("delete from back where link = '" + pymysql.escape_string(name) + "'")
  1416. curs.execute("delete from cat where cat = '" + pymysql.escape_string(name) + "'")
  1417. leng = '-' + str(len(rows[0]['data']))
  1418. history_plus(
  1419. name,
  1420. '',
  1421. today,
  1422. ip,
  1423. request.forms.send + ' (삭제)',
  1424. leng
  1425. )
  1426. curs.execute("delete from data where title = '" + pymysql.escape_string(name) + "'")
  1427. conn.commit()
  1428. conn.close()
  1429. return(redirect('/w/' + url_pas(name)))
  1430. else:
  1431. conn.close()
  1432. return(redirect('/w/' + url_pas(name)))
  1433. else:
  1434. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1435. rows = curs.fetchall()
  1436. if(rows):
  1437. if(can == 1):
  1438. conn.close()
  1439. return(redirect('/ban'))
  1440. else:
  1441. conn.close()
  1442. return(
  1443. template('del',
  1444. custom = custom_css_user(),
  1445. license = set_data['license'],
  1446. login = login_check(),
  1447. title = name,
  1448. logo = set_data['name'],
  1449. page = url_pas(name),
  1450. plus = '정말 삭제 하시겠습니까?',
  1451. sub = '삭제'
  1452. )
  1453. )
  1454. else:
  1455. conn.close()
  1456. return(redirect('/w/' + url_pas(name)))
  1457. @route('/move/<name:path>', method=['POST', 'GET'])
  1458. def move(name = None):
  1459. conn = pymysql.connect(
  1460. user = set_data['user'],
  1461. password = set_data['pw'],
  1462. charset = 'utf8mb4',
  1463. db = set_data['db']
  1464. )
  1465. curs = conn.cursor(pymysql.cursors.DictCursor)
  1466. ip = ip_check()
  1467. can = acl_check(ip, name)
  1468. today = get_time()
  1469. if(request.method == 'POST'):
  1470. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  1471. rows = curs.fetchall()
  1472. if(can == 1):
  1473. conn.close()
  1474. return(redirect('/ban'))
  1475. else:
  1476. leng = '0'
  1477. curs.execute("select * from history where title = '" + pymysql.escape_string(request.forms.title) + "'")
  1478. row = curs.fetchall()
  1479. if(row):
  1480. conn.close()
  1481. return(redirect('/error/19'))
  1482. else:
  1483. history_plus(
  1484. name,
  1485. rows[0]['data'],
  1486. today,
  1487. ip,
  1488. request.forms.send + ' (<a href="/w/' + url_pas(name) + '">' + name + '</a> - <a href="/w/' + url_pas(request.forms.title) + '">' + request.forms.title + '</a> 이동)',
  1489. leng
  1490. )
  1491. if(rows):
  1492. curs.execute("update data set title = '" + pymysql.escape_string(request.forms.title) + "' where title = '" + pymysql.escape_string(name) + "'")
  1493. curs.execute("delete from back where link = '" + pymysql.escape_string(name) + "'")
  1494. curs.execute("delete from cat where cat = '" + pymysql.escape_string(name) + "'")
  1495. curs.execute("update history set title = '" + pymysql.escape_string(request.forms.title) + "' where title = '" + pymysql.escape_string(name) + "'")
  1496. conn.commit()
  1497. conn.close()
  1498. return(redirect('/w/' + url_pas(request.forms.title)))
  1499. else:
  1500. if(can == 1):
  1501. conn.close()
  1502. return(redirect('/ban'))
  1503. else:
  1504. conn.close()
  1505. return(
  1506. template('move',
  1507. custom = custom_css_user(),
  1508. license = set_data['license'],
  1509. login = login_check(),
  1510. title = name,
  1511. logo = set_data['name'],
  1512. page = url_pas(name),
  1513. plus = '정말 이동 하시겠습니까?',
  1514. sub = '이동'
  1515. )
  1516. )
  1517. @route('/other')
  1518. def other():
  1519. return(
  1520. template(
  1521. 'other',
  1522. custom = custom_css_user(),
  1523. license = set_data['license'],
  1524. login = login_check(),
  1525. title = '기타 메뉴',
  1526. logo = set_data['name'],
  1527. data = '<h2 style="margin-top: 0px;">기록</h2> \
  1528. <li><a href="/blocklog">사용자 차단 기록</a></li> \
  1529. <li><a href="/userlog">사용자 가입 기록</a></li> \
  1530. <li><a href="/manager/6">사용자 기록</a></li> \
  1531. <li><a href="/manager/7">사용자 토론 기록</a></li> \
  1532. <h2>기타</h2> \
  1533. <li><a href="/titleindex">모든 문서</a></li> \
  1534. <li><a href="/acl_list">ACL 문서 목록</a></li> \
  1535. <li><a href="/admin_list">관리자 목록</a></li> \
  1536. <li><a href="/manager/1">관리자 메뉴</a></li> \
  1537. <br> \
  1538. 이 오픈나무의 버전은 <a href="https://github.com/2DU/openNAMU/blob/normal/version.md">v' + r_ver + '</a> 입니다.'
  1539. )
  1540. )
  1541. @route('/manager/<num:int>', method=['POST', 'GET'])
  1542. def manager(num = None):
  1543. if(num == 1):
  1544. return(
  1545. template('other',
  1546. custom = custom_css_user(),
  1547. license = set_data['license'],
  1548. login = login_check(),
  1549. title = '관리자 메뉴',
  1550. logo = set_data['name'],
  1551. data = '<h2 style="margin-top: 0px;">목록</h2> \
  1552. <li><a href="/manager/2">문서 ACL</a></li> \
  1553. <li><a href="/manager/3">사용자 체크</a></li> \
  1554. <li><a href="/manager/4">사용자 차단</a></li> \
  1555. <li><a href="/manager/5">관리자 권한 주기</a></li> \
  1556. <li><a href="/mdel">많은 문서 삭제</a></li> \
  1557. <h2>소유자</h2> \
  1558. <li><a href="/backreset">역링크, 분류 다시 생성</a></li> \
  1559. <li><a href="/manager/8">관리 그룹 생성</a></li> \
  1560. <h2>기타</h2> \
  1561. <li>이 메뉴에 없는 기능은 해당 문서의 역사나 토론에서 바로 사용 가능함</li>'
  1562. )
  1563. )
  1564. elif(num == 2):
  1565. if(request.method == 'POST'):
  1566. return(redirect('/acl/' + url_pas(request.forms.name)))
  1567. else:
  1568. return(
  1569. template('other',
  1570. custom = custom_css_user(),
  1571. license = set_data['license'],
  1572. login = login_check(),
  1573. title = 'ACL 이동',
  1574. logo = set_data['name'],
  1575. data = '<form method="post"> \
  1576. <input name="name" type="text"> \
  1577. <br> \
  1578. <br> \
  1579. <button class="btn btn-primary" type="submit">이동</button> \
  1580. </form>'
  1581. )
  1582. )
  1583. elif(num == 3):
  1584. if(request.method == 'POST'):
  1585. return(redirect('/check/' + url_pas(request.forms.name)))
  1586. else:
  1587. return(
  1588. template('other',
  1589. custom = custom_css_user(),
  1590. license = set_data['license'],
  1591. login = login_check(),
  1592. title = '체크 이동',
  1593. logo = set_data['name'],
  1594. data = '<form method="post"> \
  1595. <input name="name" type="text"> \
  1596. <br> \
  1597. <br> \
  1598. <button class="btn btn-primary" type="submit">이동</button> \
  1599. </form>'
  1600. )
  1601. )
  1602. elif(num == 4):
  1603. if(request.method == 'POST'):
  1604. return(redirect('/ban/' + url_pas(request.forms.name)))
  1605. else:
  1606. return(
  1607. template('other',
  1608. custom = custom_css_user(),
  1609. license = set_data['license'],
  1610. login = login_check(),
  1611. title = '차단 이동',
  1612. logo = set_data['name'],
  1613. data = '<form method="post"> \
  1614. <input name="name" type="text"> \
  1615. <br> \
  1616. <br> \
  1617. <button class="btn btn-primary" type="submit">이동</button> \
  1618. <br> \
  1619. <br> \
  1620. <span>아이피 앞 두자리 (XXX.XXX) 입력하면 대역 차단</span> \
  1621. </form>'
  1622. )
  1623. )
  1624. elif(num == 5):
  1625. if(request.method == 'POST'):
  1626. return(redirect('/admin/' + url_pas(request.forms.name)))
  1627. else:
  1628. return(
  1629. template('other',
  1630. custom = custom_css_user(),
  1631. license = set_data['license'],
  1632. login = login_check(),
  1633. title = '권한 이동',
  1634. logo = set_data['name'],
  1635. data = '<form method="post"> \
  1636. <input name="name" type="text"> \
  1637. <br> \
  1638. <br> \
  1639. <button class="btn btn-primary" type="submit">이동</button> \
  1640. </form>'
  1641. )
  1642. )
  1643. elif(num == 6):
  1644. if(request.method == 'POST'):
  1645. return(redirect('/record/' + url_pas(request.forms.name)))
  1646. else:
  1647. return(
  1648. template('other',
  1649. custom = custom_css_user(),
  1650. license = set_data['license'],
  1651. login = login_check(),
  1652. title = '기록 이동',
  1653. logo = set_data['name'],
  1654. data = '<form method="post"> \
  1655. <input name="name" type="text"> \
  1656. <br> \
  1657. <br> \
  1658. <button class="btn btn-primary" type="submit">이동</button> \
  1659. </form>'
  1660. )
  1661. )
  1662. elif(num == 7):
  1663. if(request.method == 'POST'):
  1664. return(redirect('/user/' + url_pas(request.forms.name) + '/topic'))
  1665. else:
  1666. return(
  1667. template('other',
  1668. custom = custom_css_user(),
  1669. license = set_data['license'],
  1670. login = login_check(),
  1671. title = '토론 기록 이동',
  1672. logo = set_data['name'],
  1673. data = '<form method="post"> \
  1674. <input name="name" type="text"> \
  1675. <br> \
  1676. <br> \
  1677. <button class="btn btn-primary" type="submit">이동</button> \
  1678. </form>'
  1679. )
  1680. )
  1681. elif(num == 8):
  1682. if(request.method == 'POST'):
  1683. return(redirect('/adminplus/' + url_pas(request.forms.name)))
  1684. else:
  1685. return(
  1686. template('other',
  1687. custom = custom_css_user(),
  1688. license = set_data['license'],
  1689. login = login_check(),
  1690. title = '그룹 생성 이동',
  1691. logo = set_data['name'],
  1692. data = '<form method="post"> \
  1693. <input name="name" type="text"> \
  1694. <br> \
  1695. <br> \
  1696. <button class="btn btn-primary" type="submit">이동</button> \
  1697. </form>'
  1698. )
  1699. )
  1700. else:
  1701. return(redirect('/'))
  1702. @route('/titleindex')
  1703. def title_index():
  1704. conn = pymysql.connect(
  1705. user = set_data['user'],
  1706. password = set_data['pw'],
  1707. charset = 'utf8mb4',
  1708. db = set_data['db']
  1709. )
  1710. curs = conn.cursor(pymysql.cursors.DictCursor)
  1711. i = [0, 0, 0, 0, 0, 0]
  1712. data = '<div>'
  1713. curs.execute("select title from data order by title asc")
  1714. title_list = curs.fetchall()
  1715. if(title_list):
  1716. for list_data in title_list:
  1717. data += '<li>' + str(i[0] + 1) + '. <a href="/w/' + url_pas(list_data['title']) + '">' + list_data['title'] + '</a></li>'
  1718. if(re.search('^분류:', list_data['title'])):
  1719. i[1] += 1
  1720. elif(re.search('^사용자:', list_data['title'])):
  1721. i[2] += 1
  1722. elif(re.search('^틀:', list_data['title'])):
  1723. i[3] += 1
  1724. elif(re.search('^파일:', list_data['title'])):
  1725. i[4] += 1
  1726. else:
  1727. i[5] += 1
  1728. i[0] += 1
  1729. else:
  1730. data += '</div>'
  1731. data += '<br> \
  1732. <li>이 위키에는 총 ' + str(i[0]) + '개의 문서가 있습니다.</li> \
  1733. <br> \
  1734. <li>틀 문서는 총 ' + str(i[3]) + '개의 문서가 있습니다.</li> \
  1735. <li>분류 문서는 총 ' + str(i[1]) + '개의 문서가 있습니다.</li> \
  1736. <li>사용자 문서는 총 ' + str(i[2]) + '개의 문서가 있습니다.</li> \
  1737. <li>파일 문서는 총 ' + str(i[4]) + '개의 문서가 있습니다.</li> \
  1738. <li>나머지 문서는 총 ' + str(i[5]) + '개의 문서가 있습니다.</li>'
  1739. else:
  1740. data = ''
  1741. conn.close()
  1742. return(
  1743. template('other',
  1744. custom = custom_css_user(),
  1745. license = set_data['license'],
  1746. login = login_check(),
  1747. logo = set_data['name'],
  1748. data = data,
  1749. title = '모든 문서'
  1750. )
  1751. )
  1752. @route('/topic/<name:path>/sub/<sub:path>/b/<num:int>')
  1753. def topic_block(name = None, sub = None, num = None):
  1754. conn = pymysql.connect(
  1755. user = set_data['user'],
  1756. password = set_data['pw'],
  1757. charset = 'utf8mb4',
  1758. db = set_data['db']
  1759. )
  1760. curs = conn.cursor(pymysql.cursors.DictCursor)
  1761. if(admin_check(3) == 1):
  1762. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1763. block = curs.fetchall()
  1764. if(block):
  1765. if(block[0]['block'] == 'O'):
  1766. curs.execute("update topic set block = '' where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1767. else:
  1768. curs.execute("update topic set block = 'O' where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1769. conn.commit()
  1770. rd_plus(
  1771. name,
  1772. sub,
  1773. get_time()
  1774. )
  1775. conn.close()
  1776. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1777. else:
  1778. conn.close()
  1779. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1780. else:
  1781. conn.close()
  1782. return(redirect('/error/3'))
  1783. @route('/topic/<name:path>/sub/<sub:path>/notice/<num:int>')
  1784. def topic_top(name = None, sub = None, num = None):
  1785. conn = pymysql.connect(
  1786. user = set_data['user'],
  1787. password = set_data['pw'],
  1788. charset = 'utf8mb4',
  1789. db = set_data['db']
  1790. )
  1791. curs = conn.cursor(pymysql.cursors.DictCursor)
  1792. if(admin_check(3) == 1):
  1793. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1794. topic_data = curs.fetchall()
  1795. if(topic_data):
  1796. curs.execute("select * from topic where id = '" + str(num) + "' and title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "'")
  1797. top_data = curs.fetchall()
  1798. if(top_data):
  1799. if(top_data[0]['top'] == 'O'):
  1800. curs.execute("update topic set top = '' where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1801. else:
  1802. curs.execute("update topic set top = 'O' where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + str(num) + "'")
  1803. conn.commit()
  1804. rd_plus(
  1805. name,
  1806. sub,
  1807. get_time()
  1808. )
  1809. conn.close()
  1810. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1811. else:
  1812. conn.close()
  1813. return(redirect('/error/3'))
  1814. @route('/topic/<name:path>/sub/<sub:path>/<tool:path>')
  1815. def topic_stop(name = None, sub = None, tool = None):
  1816. conn = pymysql.connect(
  1817. user = set_data['user'],
  1818. password = set_data['pw'],
  1819. charset = 'utf8mb4',
  1820. db = set_data['db']
  1821. )
  1822. curs = conn.cursor(pymysql.cursors.DictCursor)
  1823. if(tool == 'close'):
  1824. close = 'O'
  1825. n_close = ''
  1826. data = '토론 닫음'
  1827. n_data = '토론 다시 열기'
  1828. elif(tool == 'stop'):
  1829. close = ''
  1830. n_close = 'O'
  1831. data = '토론 정지'
  1832. n_data = '토론 재 시작'
  1833. else:
  1834. conn.close()
  1835. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1836. if(admin_check(3) == 1):
  1837. ip = ip_check()
  1838. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' order by id + 0 desc limit 1")
  1839. topic_check = curs.fetchall()
  1840. if(topic_check):
  1841. time = get_time()
  1842. curs.execute("select * from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and close = '" + pymysql.escape_string(close) + "'")
  1843. stop = curs.fetchall()
  1844. if(stop):
  1845. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) value ('" + pymysql.escape_string(str(int(topic_check[0]['id']) + 1)) + "', '" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '" + pymysql.escape_string(n_data) + "', '" + pymysql.escape_string(time) + "', '" + pymysql.escape_string(ip) + "', '', '1')")
  1846. curs.execute("delete from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and close = '" + pymysql.escape_string(close) + "'")
  1847. else:
  1848. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) value ('" + pymysql.escape_string(str(int(topic_check[0]['id']) + 1)) + "', '" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '" + pymysql.escape_string(data) + "', '" + pymysql.escape_string(time) + "', '" + pymysql.escape_string(ip) + "', '', '1')")
  1849. curs.execute("insert into stop (title, sub, close) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '" + close + "')")
  1850. curs.execute("delete from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and close = '" + pymysql.escape_string(n_close) + "'")
  1851. conn.commit()
  1852. rd_plus(
  1853. name,
  1854. sub,
  1855. time
  1856. )
  1857. conn.close()
  1858. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1859. else:
  1860. conn.close()
  1861. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1862. else:
  1863. conn.close()
  1864. return(redirect('/error/3'))
  1865. @route('/topic/<name:path>/sub/<sub:path>/agree')
  1866. def topic_agree(name = None, sub = None):
  1867. conn = pymysql.connect(
  1868. user = set_data['user'],
  1869. password = set_data['pw'],
  1870. charset = 'utf8mb4',
  1871. db = set_data['db']
  1872. )
  1873. curs = conn.cursor(pymysql.cursors.DictCursor)
  1874. if(admin_check(3) == 1):
  1875. ip = ip_check()
  1876. curs.execute("select id from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' order by id + 0 desc limit 1")
  1877. topic_check = curs.fetchall()
  1878. if(topic_check):
  1879. time = get_time()
  1880. curs.execute("select * from agreedis where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "'")
  1881. agree = curs.fetchall()
  1882. if(agree):
  1883. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) value ('" + pymysql.escape_string(str(int(topic_check[0]['id']) + 1)) + "', '" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '합의 결렬', '" + pymysql.escape_string(time) + "', '" + pymysql.escape_string(ip) + "', '', '1')")
  1884. curs.execute("delete from agreedis where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "'")
  1885. else:
  1886. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) value ('" + pymysql.escape_string(str(int(topic_check[0]['id']) + 1)) + "', '" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '합의 완료', '" + pymysql.escape_string(time) + "', '" + pymysql.escape_string(ip) + "', '', '1')")
  1887. curs.execute("insert into agreedis (title, sub) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "')")
  1888. conn.commit()
  1889. rd_plus(
  1890. name,
  1891. sub,
  1892. time
  1893. )
  1894. conn.close()
  1895. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1896. else:
  1897. conn.close()
  1898. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1899. else:
  1900. conn.close()
  1901. return(redirect('/error/3'))
  1902. @route('/topic/<name:path>/sub/<sub:path>', method=['POST', 'GET'])
  1903. def topic(name = None, sub = None):
  1904. conn = pymysql.connect(
  1905. user = set_data['user'],
  1906. password = set_data['pw'],
  1907. charset = 'utf8mb4',
  1908. db = set_data['db']
  1909. )
  1910. curs = conn.cursor(pymysql.cursors.DictCursor)
  1911. ip = ip_check()
  1912. ban = topic_check(ip, name, sub)
  1913. admin = admin_check(3)
  1914. if(request.method == 'POST'):
  1915. curs.execute("select id from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' order by id + 0 desc limit 1")
  1916. rows = curs.fetchall()
  1917. if(rows):
  1918. num = int(rows[0]['id']) + 1
  1919. else:
  1920. num = 1
  1921. if(ban == 1 and admin != 1):
  1922. conn.close()
  1923. return(redirect('/ban'))
  1924. else:
  1925. today = get_time()
  1926. rd_plus(
  1927. name,
  1928. sub,
  1929. today
  1930. )
  1931. aa = re.sub("\[\[(분류:(?:(?:(?!\]\]).)*))\]\]", "[br]", request.forms.content)
  1932. aa = savemark(aa)
  1933. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) value ('" + str(num) + "', '" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(sub) + "', '" + pymysql.escape_string(aa) + "', '" + today + "', '" + ip + "', '', '')")
  1934. conn.commit()
  1935. conn.close()
  1936. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub)))
  1937. else:
  1938. style = ''
  1939. curs.execute("select * from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and close = 'O'")
  1940. close = curs.fetchall()
  1941. curs.execute("select * from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and close = ''")
  1942. stop = curs.fetchall()
  1943. if(admin == 1):
  1944. div = '<div>'
  1945. if(close):
  1946. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/close">(토론 열기)</a> '
  1947. else:
  1948. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/close">(토론 닫기)</a> '
  1949. if(stop):
  1950. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/stop">(토론 재개)</a> '
  1951. else:
  1952. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/stop">(토론 정지)</a> '
  1953. curs.execute("select * from agreedis where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "'")
  1954. agree = curs.fetchall()
  1955. if(agree):
  1956. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/agree">(합의 취소)</a>'
  1957. else:
  1958. div += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/agree">(합의 완료)</a>'
  1959. div += '<br><br>'
  1960. else:
  1961. div = '<div>'
  1962. if(stop or close):
  1963. if(admin != 1):
  1964. style = 'display:none;'
  1965. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' order by id + 0 asc")
  1966. toda = curs.fetchall()
  1967. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and top = 'O' order by id + 0 asc")
  1968. top = curs.fetchall()
  1969. if(top):
  1970. for dain in top:
  1971. top_data = namumark('', dain['data'], 0)
  1972. top_data = re.sub("(?P<in>#(?:[0-9]*))", '<a href="\g<in>">\g<in></a>', top_data)
  1973. ip = ip_pas(dain['ip'], 1)
  1974. div += '<table id="toron"> \
  1975. <tbody> \
  1976. <tr> \
  1977. <td id="toroncolorred"> \
  1978. <a href="#' + dain['id'] + '">#' + dain['id'] + '</a> ' + ip + ' <span style="float:right;">' + dain['date'] + '</span> \
  1979. </td> \
  1980. </tr> \
  1981. <tr> \
  1982. <td>' + top_data + '</td> \
  1983. </tr> \
  1984. </tbody> \
  1985. </table> \
  1986. <br>'
  1987. i = 0
  1988. for dain in toda:
  1989. if(i == 0):
  1990. start = dain['ip']
  1991. indata = namumark('', dain['data'], 0)
  1992. indata = re.sub("(?P<in>#(?:[0-9]*))", '<a href="\g<in>">\g<in></a>', indata)
  1993. if(dain['block'] == 'O'):
  1994. indata = '<br>'
  1995. block = 'id="block"'
  1996. else:
  1997. block = ''
  1998. if(admin == 1):
  1999. if(dain['block'] == 'O'):
  2000. isblock = ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(i + 1) + '">(해제)</a>'
  2001. else:
  2002. isblock = ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(i + 1) + '">(가림)</a>'
  2003. curs.execute("select id from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(sub) + "' and id = '" + pymysql.escape_string(str(i + 1)) + "' and top = 'O'")
  2004. row = curs.fetchall()
  2005. if(row):
  2006. isblock = isblock + ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(i + 1) + '">(해제)</a>'
  2007. else:
  2008. isblock = isblock + ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(i + 1) + '">(공지)</a>'
  2009. curs.execute("select end from ban where block = '" + pymysql.escape_string(dain['ip']) + "'")
  2010. ban_it = curs.fetchall()
  2011. if(ban_it):
  2012. ban = ' <a href="/ban/' + url_pas(dain['ip']) + '">(해제)</a>' + isblock
  2013. else:
  2014. ban = ' <a href="/ban/' + url_pas(dain['ip']) + '">(차단)</a>' + isblock
  2015. else:
  2016. curs.execute("select end from ban where block = '" + pymysql.escape_string(dain['ip']) + "'")
  2017. ban_it = curs.fetchall()
  2018. if(ban_it):
  2019. ban = ' (X)'
  2020. else:
  2021. ban = ''
  2022. chad = ''
  2023. curs.execute('select acl from user where id = "' + pymysql.escape_string(dain['ip']) + '"')
  2024. adch = curs.fetchall()
  2025. if(adch):
  2026. if(adch[0]['acl'] != 'user'):
  2027. chad = ' ★'
  2028. ip = ip_pas(dain['ip'], 1)
  2029. if(dain['top'] == '1'):
  2030. color = 'blue'
  2031. elif(dain['ip'] == start):
  2032. color = 'green'
  2033. else:
  2034. color = ''
  2035. div += '<table id="toron"> \
  2036. <tbody> \
  2037. <tr> \
  2038. <td id="toroncolor' + color + '"> \
  2039. <a href="javascript:void(0);" id="' + str(i + 1) + '">#' + str(i + 1) + '</a> ' + ip + chad + ban + ' <span style="float:right;">' + dain['date'] + '</span> \
  2040. </td> \
  2041. </tr> \
  2042. <tr> \
  2043. <td ' + block + '>' + indata + '</td> \
  2044. </tr> \
  2045. </tbody> \
  2046. </table> \
  2047. <br>'
  2048. i += 1
  2049. conn.close()
  2050. return(
  2051. template('vstopic',
  2052. custom = custom_css_user(),
  2053. license = set_data['license'],
  2054. login = login_check(),
  2055. title = name,
  2056. page = url_pas(name),
  2057. suburl = url_pas(sub),
  2058. toron = sub,
  2059. logo = set_data['name'],
  2060. rows = div,
  2061. ban = ban,
  2062. style = style,
  2063. sub = '토론'
  2064. )
  2065. )
  2066. @route('/topic/<name:path>/close')
  2067. def close_topic_list(name = None):
  2068. conn = pymysql.connect(
  2069. user = set_data['user'],
  2070. password = set_data['pw'],
  2071. charset = 'utf8mb4',
  2072. db = set_data['db']
  2073. )
  2074. curs = conn.cursor(pymysql.cursors.DictCursor)
  2075. div = '<div>'
  2076. i = 0
  2077. curs.execute("select * from stop where title = '" + pymysql.escape_string(name) + "' and close = 'O' order by sub asc")
  2078. rows = curs.fetchall()
  2079. for data in rows:
  2080. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(data['sub']) + "' and id = '1'")
  2081. row = curs.fetchall()
  2082. if(row):
  2083. indata = namumark(name, row[0]['data'], 0)
  2084. if(row[0]['block'] == 'O'):
  2085. indata = '<br>'
  2086. block = 'id="block"'
  2087. else:
  2088. block = ''
  2089. ip = ip_pas(row[0]['ip'], 1)
  2090. div += '<h2> \
  2091. <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(data['sub']) + '">' + str((i + 1)) + '. ' + data['sub'] + '</a> \
  2092. </h2> \
  2093. <table id="toron"> \
  2094. <tbody> \
  2095. <tr> \
  2096. <td id="toroncolorgreen"> \
  2097. <a href="javascript:void(0);" id="1">#1</a> ' + ip + ' <span style="float:right;">' + row[0]['date'] + '</span> \
  2098. </td> \
  2099. </tr> \
  2100. <tr> \
  2101. <td ' + block + '>' + indata + '</td> \
  2102. </tr> \
  2103. </tbody> \
  2104. </table> \
  2105. <br>'
  2106. i += 1
  2107. else:
  2108. div += '</div>'
  2109. conn.close()
  2110. return(
  2111. template('topic',
  2112. custom = custom_css_user(),
  2113. license = set_data['license'],
  2114. login = login_check(),
  2115. title = name,
  2116. page = url_pas(name),
  2117. logo = set_data['name'],
  2118. plus = div,
  2119. sub = '닫힘'
  2120. )
  2121. )
  2122. @route('/topic/<name:path>/agree')
  2123. def agree_topic_list(name = None):
  2124. conn = pymysql.connect(
  2125. user = set_data['user'],
  2126. password = set_data['pw'],
  2127. charset = 'utf8mb4',
  2128. db = set_data['db']
  2129. )
  2130. curs = conn.cursor(pymysql.cursors.DictCursor)
  2131. div = '<div>'
  2132. i = 0
  2133. curs.execute("select * from agreedis where title = '" + pymysql.escape_string(name) + "' order by sub asc")
  2134. agree_list = curs.fetchall()
  2135. for data in agree_list:
  2136. curs.execute("select * from topic where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(data['sub']) + "' and id = '1'")
  2137. topic_data = curs.fetchall()
  2138. if(topic_data):
  2139. indata = namumark(name, topic_data[0]['data'], 0)
  2140. if(topic_data[0]['block'] == 'O'):
  2141. indata = '<br>'
  2142. block = 'id="block"'
  2143. else:
  2144. block = ''
  2145. ip = ip_pas(topic_data[0]['ip'], 1)
  2146. div += '<h2> \
  2147. <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(data['sub']) + '">' + str(i + 1) + '. ' + data['sub'] + '</a> \
  2148. </h2> \
  2149. <table id="toron"> \
  2150. <tbody> \
  2151. <tr> \
  2152. <td id="toroncolorgreen"> \
  2153. <a href="javascript:void(0);" id="1">#1</a> ' + ip + ' <span style="float:right;">' + topic_data[0]['date'] + '</span> \
  2154. </td> \
  2155. </tr> \
  2156. <tr> \
  2157. <td ' + block + '>' + indata + '</td> \
  2158. </tr> \
  2159. </tbody> \
  2160. </table> \
  2161. <br>'
  2162. i += 1
  2163. else:
  2164. div += '</div>'
  2165. conn.close()
  2166. return(
  2167. template('topic',
  2168. custom = custom_css_user(),
  2169. license = set_data['license'],
  2170. login = login_check(),
  2171. title = name,
  2172. page = url_pas(name),
  2173. logo = set_data['name'],
  2174. plus = div,
  2175. sub = '합의'
  2176. )
  2177. )
  2178. @route('/topic/<name:path>', method=['POST', 'GET'])
  2179. def topic_list(name = None):
  2180. conn = pymysql.connect(
  2181. user = set_data['user'],
  2182. password = set_data['pw'],
  2183. charset = 'utf8mb4',
  2184. db = set_data['db']
  2185. )
  2186. curs = conn.cursor(pymysql.cursors.DictCursor)
  2187. if(request.method == 'POST'):
  2188. conn.close()
  2189. return(redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(request.forms.topic)))
  2190. else:
  2191. div = '<div>'
  2192. j = 1
  2193. curs.execute("select * from rd where title = '" + pymysql.escape_string(name) + "' order by date asc")
  2194. rows = curs.fetchall()
  2195. for data in rows:
  2196. curs.execute("select * from topic where title = '" + pymysql.escape_string(data['title']) + "' and sub = '" + pymysql.escape_string(data['sub']) + "' and id = '1' order by sub asc")
  2197. aa = curs.fetchall()
  2198. indata = namumark(name, aa[0]['data'], 0)
  2199. if(aa[0]['block'] == 'O'):
  2200. indata = '<br>'
  2201. block = 'id="block"'
  2202. else:
  2203. block = ''
  2204. ip = ip_pas(aa[0]['ip'], 1)
  2205. curs.execute("select * from stop where title = '" + pymysql.escape_string(data['title']) + "' and sub = '" + pymysql.escape_string(data['sub']) + "' and close = 'O'")
  2206. row = curs.fetchall()
  2207. if(not row):
  2208. div += '<h2> \
  2209. <a href="/topic/' + url_pas(data['title']) + '/sub/' + url_pas(data['sub']) + '">' + str(j) + '. ' + data['sub'] + '</a> \
  2210. </h2> \
  2211. <table id="toron"> \
  2212. <tbody> \
  2213. <tr> \
  2214. <td id="toroncolorgreen"> \
  2215. <a href="javascript:void(0);" id="1">#1</a> ' + ip + ' <span style="float:right;">' + aa[0]['date'] + '</span> \
  2216. </td> \
  2217. </tr> \
  2218. <tr> \
  2219. <td ' + block + '>' + indata + '</td> \
  2220. </tr> \
  2221. </tbody> \
  2222. </table> \
  2223. <br>'
  2224. j += 1
  2225. else:
  2226. div += '</div>'
  2227. conn.close()
  2228. return(
  2229. template('topic',
  2230. custom = custom_css_user(),
  2231. license = set_data['license'],
  2232. login = login_check(),
  2233. title = name,
  2234. page = url_pas(name),
  2235. logo = set_data['name'],
  2236. plus = div,
  2237. list = 1,
  2238. sub = '토론 목록'
  2239. )
  2240. )
  2241. @route('/login', method=['POST', 'GET'])
  2242. def login():
  2243. conn = pymysql.connect(
  2244. user = set_data['user'],
  2245. password = set_data['pw'],
  2246. charset = 'utf8mb4',
  2247. db = set_data['db']
  2248. )
  2249. curs = conn.cursor(pymysql.cursors.DictCursor)
  2250. session = request.environ.get('beaker.session')
  2251. ip = ip_check()
  2252. ban = ban_check(ip)
  2253. if(request.method == 'POST'):
  2254. if(ban == 1):
  2255. conn.close()
  2256. return(redirect('/ban'))
  2257. else:
  2258. curs.execute("select * from user where id = '" + pymysql.escape_string(request.forms.id) + "'")
  2259. user = curs.fetchall()
  2260. if(user):
  2261. if(session.get('Now') == 1):
  2262. conn.close()
  2263. return(redirect('/error/11'))
  2264. elif(bcrypt.checkpw(bytes(request.forms.pw, 'utf-8'), bytes(user[0]['pw'], 'utf-8'))):
  2265. session['Now'] = 1
  2266. session['DREAMER'] = request.forms.id
  2267. curs.execute("select * from custom where user = '" + pymysql.escape_string(request.forms.id) + "'")
  2268. css_data = curs.fetchall()
  2269. if(css_data):
  2270. session['Daydream'] = css_data[0]['css']
  2271. else:
  2272. session['Daydream'] = ''
  2273. curs.execute("insert into login (user, ip, today) value ('" + pymysql.escape_string(request.forms.id) + "', '" + pymysql.escape_string(ip) + "', '" + pymysql.escape_string(get_time()) + "')")
  2274. conn.commit()
  2275. conn.close()
  2276. return(redirect('/user'))
  2277. else:
  2278. conn.close()
  2279. return(redirect('/error/13'))
  2280. else:
  2281. conn.close()
  2282. return(redirect('/error/12'))
  2283. else:
  2284. if(ban == 1):
  2285. conn.close()
  2286. return(redirect('/ban'))
  2287. else:
  2288. if(session.get('Now') == 1):
  2289. conn.close()
  2290. return(redirect('/error/11'))
  2291. else:
  2292. conn.close()
  2293. return(
  2294. template('login',
  2295. custom = custom_css_user(),
  2296. license = set_data['license'],
  2297. login = login_check(),
  2298. title = '로그인',
  2299. enter = '로그인',
  2300. logo = set_data['name']
  2301. )
  2302. )
  2303. @route('/change', method=['POST', 'GET'])
  2304. def change_password():
  2305. conn = pymysql.connect(
  2306. user = set_data['user'],
  2307. password = set_data['pw'],
  2308. charset = 'utf8mb4',
  2309. db = set_data['db']
  2310. )
  2311. curs = conn.cursor(pymysql.cursors.DictCursor)
  2312. ip = ip_check()
  2313. ban = ban_check(ip)
  2314. if(request.method == 'POST'):
  2315. if(request.forms.pw2 == request.forms.pw3):
  2316. if(ban == 1):
  2317. conn.close()
  2318. return(redirect('/ban'))
  2319. else:
  2320. curs.execute("select * from user where id = '" + pymysql.escape_string(request.forms.id) + "'")
  2321. user = curs.fetchall()
  2322. if(user):
  2323. if(not re.search('(\.|:)', ip)):
  2324. conn.close()
  2325. return(redirect('/logout'))
  2326. elif(bcrypt.checkpw(bytes(request.forms.pw, 'utf-8'), bytes(user[0]['pw'], 'utf-8'))):
  2327. hashed = bcrypt.hashpw(bytes(request.forms.pw2, 'utf-8'), bcrypt.gensalt())
  2328. curs.execute("update user set pw = '" + pymysql.escape_string(hashed.decode()) + "' where id = '" + pymysql.escape_string(request.forms.id) + "'")
  2329. conn.commit()
  2330. conn.close()
  2331. return(redirect('/login'))
  2332. else:
  2333. conn.close()
  2334. return(redirect('/error/10'))
  2335. else:
  2336. conn.close()
  2337. return(redirect('/error/9'))
  2338. else:
  2339. conn.close()
  2340. return(redirect('/error/20'))
  2341. else:
  2342. if(ban == 1):
  2343. conn.close()
  2344. return(redirect('/ban'))
  2345. else:
  2346. if(not re.search('(\.|:)', ip)):
  2347. conn.close()
  2348. return(redirect('/logout'))
  2349. else:
  2350. conn.close()
  2351. return(
  2352. template('login',
  2353. custom = custom_css_user(),
  2354. license = set_data['license'],
  2355. login = login_check(),
  2356. title = '비밀번호 변경',
  2357. enter = '변경',
  2358. logo = set_data['name']
  2359. )
  2360. )
  2361. @route('/check/<name:path>')
  2362. def user_check(name = None):
  2363. conn = pymysql.connect(
  2364. user = set_data['user'],
  2365. password = set_data['pw'],
  2366. charset = 'utf8mb4',
  2367. db = set_data['db']
  2368. )
  2369. curs = conn.cursor(pymysql.cursors.DictCursor)
  2370. curs.execute("select * from user where id = '" + pymysql.escape_string(name) + "'")
  2371. user = curs.fetchall()
  2372. if(user and user[0]['acl'] != 'user'):
  2373. conn.close()
  2374. return(redirect('/error/4'))
  2375. else:
  2376. if(admin_check(4) == 1):
  2377. m = re.search('^(?:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}?)$', name)
  2378. if(m):
  2379. sql = 'ip'
  2380. else:
  2381. sql = 'user'
  2382. curs.execute("select * from login where " + sql + " = '" + pymysql.escape_string(name) + "' order by today desc")
  2383. row = curs.fetchall()
  2384. if(row):
  2385. c = '<div> \
  2386. <table style="width: 100%; text-align: center;"> \
  2387. <tbody> \
  2388. <tr> \
  2389. <td style="width: 33.3%;">이름</td> \
  2390. <td style="width: 33.3%;">아이피</td> \
  2391. <td style="width: 33.3%;">언제</td> \
  2392. </tr>'
  2393. for data in row:
  2394. c += '<tr> \
  2395. <td>' + data['user'] + '</td> \
  2396. <td>' + data['ip'] + '</td> \
  2397. <td>' + data['today'] + '</td> \
  2398. </tr>'
  2399. else:
  2400. c += '</tbody> \
  2401. </table> \
  2402. </div>'
  2403. else:
  2404. c = ''
  2405. conn.close()
  2406. return(
  2407. template('other',
  2408. custom = custom_css_user(),
  2409. license = set_data['license'],
  2410. login = login_check(),
  2411. title = '다중 검사',
  2412. logo = set_data['name'],
  2413. data = c
  2414. )
  2415. )
  2416. else:
  2417. conn.close()
  2418. return(redirect('/error/3'))
  2419. @route('/register', method=['POST', 'GET'])
  2420. def register():
  2421. conn = pymysql.connect(
  2422. user = set_data['user'],
  2423. password = set_data['pw'],
  2424. charset = 'utf8mb4',
  2425. db = set_data['db']
  2426. )
  2427. curs = conn.cursor(pymysql.cursors.DictCursor)
  2428. ip = ip_check()
  2429. ban = ban_check(ip)
  2430. if(request.method == 'POST'):
  2431. if(request.forms.pw == request.forms.pw2):
  2432. if(ban == 1):
  2433. conn.close()
  2434. return(redirect('/ban'))
  2435. else:
  2436. m = re.search('(?:[^A-Za-zㄱ-힣0-9 ])', request.forms.id)
  2437. if(m):
  2438. conn.close()
  2439. return(redirect('/error/8'))
  2440. else:
  2441. if(len(request.forms.id) > 20):
  2442. conn.close()
  2443. return(redirect('/error/7'))
  2444. else:
  2445. curs.execute("select * from user where id = '" + pymysql.escape_string(request.forms.id) + "'")
  2446. rows = curs.fetchall()
  2447. if(rows):
  2448. conn.close()
  2449. return(redirect('/error/6'))
  2450. else:
  2451. hashed = bcrypt.hashpw(bytes(request.forms.pw, 'utf-8'), bcrypt.gensalt())
  2452. curs.execute("select id from user limit 1")
  2453. user_ex = curs.fetchall()
  2454. if(not user_ex):
  2455. curs.execute("insert into user (id, pw, acl) value ('" + pymysql.escape_string(request.forms.id) + "', '" + pymysql.escape_string(hashed.decode()) + "', 'owner')")
  2456. else:
  2457. curs.execute("insert into user (id, pw, acl) value ('" + pymysql.escape_string(request.forms.id) + "', '" + pymysql.escape_string(hashed.decode()) + "', 'user')")
  2458. conn.commit()
  2459. conn.close()
  2460. return(redirect('/login'))
  2461. else:
  2462. conn.close()
  2463. return(redirect('/error/20'))
  2464. else:
  2465. if(ban == 1):
  2466. conn.close()
  2467. return(redirect('/ban'))
  2468. else:
  2469. conn.close()
  2470. return(
  2471. template('login',
  2472. custom = custom_css_user(),
  2473. license = set_data['license'],
  2474. login = login_check(),
  2475. title = '회원가입',
  2476. enter = '회원가입',
  2477. logo = set_data['name']
  2478. )
  2479. )
  2480. @route('/logout')
  2481. def logout():
  2482. session = request.environ.get('beaker.session')
  2483. session['Now'] = 0
  2484. session.pop('DREAMER', None)
  2485. return(redirect('/user'))
  2486. @route('/ban/<name:path>', method=['POST', 'GET'])
  2487. def user_ban(name = None):
  2488. conn = pymysql.connect(
  2489. user = set_data['user'],
  2490. password = set_data['pw'],
  2491. charset = 'utf8mb4',
  2492. db = set_data['db']
  2493. )
  2494. curs = conn.cursor(pymysql.cursors.DictCursor)
  2495. curs.execute("select * from user where id = '" + pymysql.escape_string(name) + "'")
  2496. user = curs.fetchall()
  2497. if(user and user[0]['acl'] != 'user'):
  2498. conn.close()
  2499. return(redirect('/error/4'))
  2500. else:
  2501. if(request.method == 'POST'):
  2502. if(admin_check(1) == 1):
  2503. ip = ip_check()
  2504. if(not re.search("[0-9]{4}-[0-9]{2}-[0-9]{2}", request.forms.end)):
  2505. end = ''
  2506. else:
  2507. end = request.forms.end
  2508. curs.execute("select * from ban where block = '" + pymysql.escape_string(name) + "'")
  2509. row = curs.fetchall()
  2510. if(row):
  2511. rb_plus(name, '해제', get_time(), ip, '')
  2512. curs.execute("delete from ban where block = '" + pymysql.escape_string(name) + "'")
  2513. else:
  2514. b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name)
  2515. if(b):
  2516. rb_plus(name, end, get_time(), ip, request.forms.why)
  2517. curs.execute("insert into ban (block, end, why, band) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(end) + "', '" + pymysql.escape_string(request.forms.why) + "', 'O')")
  2518. else:
  2519. rb_plus(name, end, get_time(), ip, request.forms.why)
  2520. curs.execute("insert into ban (block, end, why, band) value ('" + pymysql.escape_string(name) + "', '" + pymysql.escape_string(end) + "', '" + pymysql.escape_string(request.forms.why) + "', '')")
  2521. conn.commit()
  2522. conn.close()
  2523. return(redirect('/ban/' + url_pas(name)))
  2524. else:
  2525. conn.close()
  2526. return(redirect('/error/3'))
  2527. else:
  2528. if(admin_check(1) == 1):
  2529. curs.execute("select * from ban where block = '" + pymysql.escape_string(name) + "'")
  2530. row = curs.fetchall()
  2531. if(row):
  2532. now = '차단 해제'
  2533. else:
  2534. b = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name)
  2535. if(b):
  2536. now = '대역 차단'
  2537. else:
  2538. now = '차단'
  2539. conn.close()
  2540. return(
  2541. template('ban',
  2542. custom = custom_css_user(),
  2543. license = set_data['license'],
  2544. login = login_check(),
  2545. title = name,
  2546. page = url_pas(name),
  2547. logo = set_data['name'],
  2548. now = now,
  2549. today = get_time(),
  2550. sub = '차단'
  2551. )
  2552. )
  2553. else:
  2554. conn.close()
  2555. return(redirect('/error/3'))
  2556. @route('/acl/<name:path>', method=['POST', 'GET'])
  2557. def acl(name = None):
  2558. conn = pymysql.connect(
  2559. user = set_data['user'],
  2560. password = set_data['pw'],
  2561. charset = 'utf8mb4',
  2562. db = set_data['db']
  2563. )
  2564. curs = conn.cursor(pymysql.cursors.DictCursor)
  2565. if(request.method == 'POST'):
  2566. if(admin_check(5) == 1):
  2567. curs.execute("select acl from data where title = '" + pymysql.escape_string(name) + "'")
  2568. row = curs.fetchall()
  2569. if(row):
  2570. if(request.forms.select == 'admin'):
  2571. curs.execute("update data set acl = 'admin' where title = '" + pymysql.escape_string(name) + "'")
  2572. elif(request.forms.select == 'user'):
  2573. curs.execute("update data set acl = 'user' where title = '" + pymysql.escape_string(name) + "'")
  2574. else:
  2575. curs.execute("update data set acl = '' where title = '" + pymysql.escape_string(name) + "'")
  2576. conn.commit()
  2577. conn.close()
  2578. return(redirect('/w/' + url_pas(name)) )
  2579. else:
  2580. conn.close()
  2581. return(redirect('/error/3'))
  2582. else:
  2583. if(admin_check(5) == 1):
  2584. curs.execute("select acl from data where title = '" + pymysql.escape_string(name) + "'")
  2585. row = curs.fetchall()
  2586. if(row):
  2587. if(row[0]['acl'] == 'admin'):
  2588. now = '관리자만'
  2589. elif(row[0]['acl'] == 'user'):
  2590. now = '로그인 이상'
  2591. else:
  2592. now = '일반'
  2593. conn.close()
  2594. return(
  2595. template('acl',
  2596. custom = custom_css_user(),
  2597. license = set_data['license'],
  2598. login = login_check(),
  2599. title = name,
  2600. page = url_pas(name),
  2601. logo = set_data['name'],
  2602. now = '현재 ACL 상태는 ' + now,
  2603. sub = 'ACL'
  2604. )
  2605. )
  2606. else:
  2607. conn.close()
  2608. return(redirect('/w/' + url_pas(name)) )
  2609. else:
  2610. conn.close()
  2611. return(redirect('/error/3'))
  2612. @route('/admin/<name:path>', method=['POST', 'GET'])
  2613. def user_admin(name = None):
  2614. conn = pymysql.connect(
  2615. user = set_data['user'],
  2616. password = set_data['pw'],
  2617. charset = 'utf8mb4',
  2618. db = set_data['db']
  2619. )
  2620. curs = conn.cursor(pymysql.cursors.DictCursor)
  2621. if(request.method == 'POST'):
  2622. if(admin_check(None) == 1):
  2623. curs.execute("select * from user where id = '" + pymysql.escape_string(name) + "'")
  2624. user = curs.fetchall()
  2625. if(user):
  2626. if(user[0]['acl'] != 'user'):
  2627. curs.execute("update user set acl = 'user' where id = '" + pymysql.escape_string(name) + "'")
  2628. else:
  2629. curs.execute("update user set acl = '" + pymysql.escape_string(request.forms.select) + "' where id = '" + pymysql.escape_string(name) + "'")
  2630. conn.commit()
  2631. conn.close()
  2632. return(redirect('/'))
  2633. else:
  2634. conn.close()
  2635. return(redirect('/error/5'))
  2636. else:
  2637. conn.close()
  2638. return(redirect('/error/3'))
  2639. else:
  2640. if(admin_check(None) == 1):
  2641. curs.execute("select * from user where id = '" + pymysql.escape_string(name) + "'")
  2642. user = curs.fetchall()
  2643. if(user):
  2644. if(user[0]['acl'] != 'user'):
  2645. now = '권한 해제'
  2646. else:
  2647. now = '권한 부여'
  2648. div = ''
  2649. curs.execute('select name from alist order by name asc')
  2650. get_alist = curs.fetchall()
  2651. if(get_alist):
  2652. i = 0
  2653. name_rem = ''
  2654. for data in get_alist:
  2655. if(name_rem != data['name']):
  2656. name_rem = data['name']
  2657. div += '<option value="' + data['name'] + '" selected="selected">' + data['name'] + '</option>'
  2658. conn.close()
  2659. return(
  2660. template('admin',
  2661. custom = custom_css_user(),
  2662. license = set_data['license'],
  2663. login = login_check(),
  2664. title = name,
  2665. page = url_pas(name),
  2666. datalist = div,
  2667. logo = set_data['name'],
  2668. now = now,
  2669. sub = '권한 부여'
  2670. )
  2671. )
  2672. else:
  2673. conn.close()
  2674. return(redirect('/error/5'))
  2675. else:
  2676. conn.close()
  2677. return(redirect('/error/3'))
  2678. @route('/ban')
  2679. def are_you_ban():
  2680. conn = pymysql.connect(
  2681. user = set_data['user'],
  2682. password = set_data['pw'],
  2683. charset = 'utf8mb4',
  2684. db = set_data['db']
  2685. )
  2686. curs = conn.cursor(pymysql.cursors.DictCursor)
  2687. ip = ip_check()
  2688. if(ban_check(ip) == 1):
  2689. curs.execute("select * from ban where block = '" + pymysql.escape_string(ip) + "'")
  2690. rows = curs.fetchall()
  2691. if(rows):
  2692. if(rows[0]['end']):
  2693. end = rows[0]['end'] + ' 까지 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  2694. now = re.sub(':', '', get_time())
  2695. now = re.sub('\-', '', now)
  2696. now = int(re.sub(' ', '', now))
  2697. day = re.sub('\-', '', rows[0]['end'])
  2698. if(now >= int(day + '000000')):
  2699. curs.execute("delete from ban where block = '" + pymysql.escape_string(ip) + "'")
  2700. conn.commit()
  2701. end = '차단이 풀렸습니다. 다시 시도 해 보세요.'
  2702. else:
  2703. end = '영구 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  2704. else:
  2705. b = re.search("^([0-9](?:[0-9]?[0-9]?)\.[0-9](?:[0-9]?[0-9]?))", ip)
  2706. if(b):
  2707. results = b.groups()
  2708. curs.execute("select * from ban where block = '" + pymysql.escape_string(results[0]) + "' and band = 'O'")
  2709. row = curs.fetchall()
  2710. if(row):
  2711. if(row[0]['end']):
  2712. end = row[0]['end'] + ' 까지 차단 상태 입니다. / 사유 : ' + rows[0]['why']
  2713. now = re.sub(':', '', get_time())
  2714. now = re.sub('\-', '', now)
  2715. now = int(re.sub(' ', '', now))
  2716. day = re.sub('\-', '', row[0]['end'])
  2717. if(now >= int(day + '000000')):
  2718. curs.execute("delete from ban where block = '" + pymysql.escape_string(results[0]) + "' and band = 'O'")
  2719. conn.commit()
  2720. end = '차단이 풀렸습니다. 다시 시도 해 보세요.'
  2721. else:
  2722. end = '영구 차단 상태 입니다. / 사유 : ' + row[0]['why']
  2723. else:
  2724. end = '권한이 맞지 않는 상태 입니다.'
  2725. conn.close()
  2726. return(
  2727. template('other',
  2728. custom = custom_css_user(),
  2729. license = set_data['license'],
  2730. login = login_check(),
  2731. title = '권한 오류',
  2732. logo = set_data['name'],
  2733. data = end
  2734. )
  2735. )
  2736. @route('/w/<name:path>/r/<a:int>/diff/<b:int>')
  2737. def diff_data(name = None, a = None, b = None):
  2738. conn = pymysql.connect(
  2739. user = set_data['user'],
  2740. password = set_data['pw'],
  2741. charset = 'utf8mb4',
  2742. db = set_data['db']
  2743. )
  2744. curs = conn.cursor(pymysql.cursors.DictCursor)
  2745. curs.execute("select * from history where id = '" + pymysql.escape_string(str(a)) + "' and title = '" + pymysql.escape_string(name) + "'")
  2746. a_raw_data = curs.fetchall()
  2747. if(a_raw_data):
  2748. curs.execute("select * from history where id = '" + pymysql.escape_string(str(b)) + "' and title = '" + pymysql.escape_string(name) + "'")
  2749. b_raw_data = curs.fetchall()
  2750. if(b_raw_data):
  2751. a_data = re.sub('<', '&lt;', a_raw_data[0]['data'])
  2752. a_data = re.sub('>', '&gt;', a_data)
  2753. a_data = re.sub('"', '&quot;', a_data)
  2754. b_data = re.sub('<', '&lt;', b_raw_data[0]['data'])
  2755. b_data = re.sub('>', '&gt;', b_data)
  2756. b_data = re.sub('"', '&quot;', b_data)
  2757. diff_data = difflib.SequenceMatcher(None, a_data, b_data)
  2758. result = diff(diff_data)
  2759. result = '<pre>' + result + '</pre>'
  2760. conn.close()
  2761. return(
  2762. template('other',
  2763. custom = custom_css_user(),
  2764. license = set_data['license'],
  2765. login = login_check(),
  2766. title = name,
  2767. logo = set_data['name'],
  2768. data = result,
  2769. sub = '비교',
  2770. page = url_pas(name)
  2771. )
  2772. )
  2773. else:
  2774. conn.close()
  2775. return(redirect('/history/' + url_pas(name)))
  2776. else:
  2777. conn.close()
  2778. return(redirect('/history/' + url_pas(name)))
  2779. @route('/down/<name:path>')
  2780. def down(name = None):
  2781. conn = pymysql.connect(
  2782. user = set_data['user'],
  2783. password = set_data['pw'],
  2784. charset = 'utf8mb4',
  2785. db = set_data['db']
  2786. )
  2787. curs = conn.cursor(pymysql.cursors.DictCursor)
  2788. curs.execute("select title from data where title like '%" + pymysql.escape_string(name) + "/%'")
  2789. under = curs.fetchall()
  2790. div = ''
  2791. i = 0
  2792. for data in under:
  2793. div += '<li>' + str(i + 1) + '. <a href="/w/' + url_pas(data['title']) + '">' + data['title'] + '</a></li>'
  2794. i += 1
  2795. conn.close()
  2796. return(
  2797. template('other',
  2798. custom = custom_css_user(),
  2799. license = set_data['license'],
  2800. login = login_check(),
  2801. title = name,
  2802. logo = set_data['name'],
  2803. data = div,
  2804. sub = '하위 문서',
  2805. page = url_pas(name)
  2806. )
  2807. )
  2808. @route('/w/<name:path>')
  2809. @route('/w/<name:path>/r/<num:int>')
  2810. @route('/w/<name:path>/from/<redirect:path>')
  2811. def read_view(name = None, num = None, redirect = None):
  2812. conn = pymysql.connect(
  2813. user = set_data['user'],
  2814. password = set_data['pw'],
  2815. charset = 'utf8mb4',
  2816. db = set_data['db']
  2817. )
  2818. curs = conn.cursor(pymysql.cursors.DictCursor)
  2819. data_none = 0
  2820. sub = 0
  2821. acl = ''
  2822. div = ''
  2823. topic = ''
  2824. curs.execute("select sub from rd where title = '" + pymysql.escape_string(name) + "' order by date asc")
  2825. rows = curs.fetchall()
  2826. for data in rows:
  2827. curs.execute("select title from stop where title = '" + pymysql.escape_string(name) + "' and sub = '" + pymysql.escape_string(data['sub']) + "' and close = 'O'")
  2828. row = curs.fetchall()
  2829. if(not row):
  2830. topic = "open"
  2831. break
  2832. curs.execute("select title from data where title like '%" + pymysql.escape_string(name) + "/%'")
  2833. under = curs.fetchall()
  2834. if(under):
  2835. down = 1
  2836. else:
  2837. down = 0
  2838. m = re.search("^(.*)\/(.*)$", name)
  2839. if(m):
  2840. uppage = m.groups()[0]
  2841. else:
  2842. uppage = 0
  2843. if(admin_check(5) == 1):
  2844. admin_memu = 'ACL'
  2845. else:
  2846. admin_memu = ''
  2847. if(re.search("^분류:", name)):
  2848. curs.execute("delete from cat where title = '" + pymysql.escape_string(name) + "' and cat = ''")
  2849. conn.commit()
  2850. curs.execute("select * from cat where title = '" + pymysql.escape_string(name) + "' order by cat asc")
  2851. rows = curs.fetchall()
  2852. if(rows):
  2853. div = '<h2>분류</h2>'
  2854. i = 0
  2855. for data in rows:
  2856. div += '<li><a href="/w/' + url_pas(data['cat']) + '">' + data['cat'] + '</a></li>'
  2857. if(num):
  2858. curs.execute("select * from hidhi where title = '" + pymysql.escape_string(name) + "' and re = '" + pymysql.escape_string(str(num)) + "'")
  2859. hid = curs.fetchall()
  2860. if(hid):
  2861. if(admin_check(6) != 1):
  2862. conn.close()
  2863. return(redirect('/history/' + url_pas(name)))
  2864. curs.execute("select * from history where title = '" + pymysql.escape_string(name) + "' and id = '" + str(num) + "'")
  2865. else:
  2866. curs.execute("select * from data where title = '" + pymysql.escape_string(name) + "'")
  2867. rows = curs.fetchall()
  2868. if(rows):
  2869. if(not num):
  2870. if(rows[0]['acl'] == 'admin'):
  2871. acl = '(관리자)'
  2872. elif(rows[0]['acl'] == 'user'):
  2873. acl = '(로그인)'
  2874. elsedata = rows[0]['data']
  2875. else:
  2876. data_none = 1
  2877. elsedata = ''
  2878. m = re.search("^사용자:([^/]*)", name)
  2879. if(m):
  2880. g = m.groups()
  2881. curs.execute("select acl from user where id = '" + pymysql.escape_string(g[0]) + "'")
  2882. test = curs.fetchall()
  2883. if(test):
  2884. if(test[0]['acl'] != 'user'):
  2885. acl = '(관리자)'
  2886. curs.execute("select block from ban where block = '" + pymysql.escape_string(g[0]) + "'")
  2887. user = curs.fetchall()
  2888. if(user):
  2889. sub = '차단'
  2890. if(redirect):
  2891. elsedata = re.sub("^#(?:redirect|넘겨주기)\s(?P<in>[^\n]*)", " * [[\g<in>]] 문서로 넘겨주기", elsedata)
  2892. enddata = namumark(name, elsedata, 1)
  2893. conn.close()
  2894. return(
  2895. template('read',
  2896. custom = custom_css_user(),
  2897. license = set_data['license'],
  2898. login = login_check(),
  2899. title = name,
  2900. logo = set_data['name'],
  2901. page = url_pas(name),
  2902. data = enddata + div,
  2903. uppage = uppage,
  2904. acl = acl,
  2905. topic = topic,
  2906. redirect = redirect,
  2907. admin = admin_memu,
  2908. data_none = data_none,
  2909. sub = sub,
  2910. down = down
  2911. )
  2912. )
  2913. @route('/user/<name:path>/topic')
  2914. @route('/user/<name:path>/topic/<num:int>')
  2915. def user_topic_list(name = None, num = 1):
  2916. conn = pymysql.connect(
  2917. user = set_data['user'],
  2918. password = set_data['pw'],
  2919. charset = 'utf8mb4',
  2920. db = set_data['db']
  2921. )
  2922. curs = conn.cursor(pymysql.cursors.DictCursor)
  2923. if(num * 50 <= 0):
  2924. v = 50
  2925. else:
  2926. v = num * 50
  2927. i = v - 50
  2928. ydmin = admin_check(1)
  2929. div = '<table style="width: 100%; text-align: center;"> \
  2930. <tbody> \
  2931. <tr> \
  2932. <td style="width: 33.3%;">토론명</td> \
  2933. <td style="width: 33.3%;">작성자</td> \
  2934. <td style="width: 33.3%;">시간</td> \
  2935. </tr>'
  2936. curs.execute("select title, id, sub, ip, date from topic where ip = '" + pymysql.escape_string(name) + "' order by date desc limit " + str(i) + ", " + str(v))
  2937. rows = curs.fetchall()
  2938. if(rows):
  2939. for data in rows:
  2940. title = re.sub('<', '&lt;', data['title'])
  2941. title = re.sub('>', '&gt;', title)
  2942. title = re.sub('"', '&quot;', title)
  2943. sub = re.sub('<', '&lt;', data['sub'])
  2944. sub = re.sub('>', '&gt;', sub)
  2945. sub = re.sub('"', '&quot;', sub)
  2946. if(ydmin == 1):
  2947. curs.execute("select * from ban where block = '" + pymysql.escape_string(data['ip']) + "'")
  2948. row = curs.fetchall()
  2949. if(row):
  2950. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(해제)</a>'
  2951. else:
  2952. ban = ' <a href="/ban/' + url_pas(data['ip']) + '">(차단)</a>'
  2953. else:
  2954. ban = ''
  2955. ip = ip_pas(data['ip'], 1)
  2956. div += '<tr> \
  2957. <td> \
  2958. <a href="/topic/' + url_pas(data['title']) + '/sub/' + url_pas(data['sub']) + '#' + data['id'] + '">' + title + '#' + data['id'] + '</a> (' + sub + ') \
  2959. </td> \
  2960. <td>' + ip + ban + '</td> \
  2961. <td>' + data['date'] + '</td> \
  2962. </tr>'
  2963. else:
  2964. div += '</tbody> \
  2965. </table>'
  2966. else:
  2967. div = ''
  2968. div += '<br> \
  2969. <a href="/user/' + url_pas(name) + '/topic/' + str(num - 1) + '">(이전)</a> <a href="/user/' + url_pas(name) + '/topic/' + str(num + 1) + '">(이후)</a>'
  2970. curs.execute("select end, why from ban where block = '" + pymysql.escape_string(name) + "'")
  2971. ban_it = curs.fetchall()
  2972. if(ban_it):
  2973. sub = '차단'
  2974. else:
  2975. sub = None
  2976. conn.close()
  2977. return(
  2978. template('other',
  2979. custom = custom_css_user(),
  2980. license = set_data['license'],
  2981. login = login_check(),
  2982. logo = set_data['name'],
  2983. data = div,
  2984. title = '사용자 토론 기록',
  2985. sub = sub
  2986. )
  2987. )
  2988. @route('/user')
  2989. def user_info():
  2990. conn = pymysql.connect(
  2991. user = set_data['user'],
  2992. password = set_data['pw'],
  2993. charset = 'utf8mb4',
  2994. db = set_data['db']
  2995. )
  2996. curs = conn.cursor(pymysql.cursors.DictCursor)
  2997. ip = ip_check()
  2998. raw_ip = ip
  2999. curs.execute("select * from user where id = '" + pymysql.escape_string(ip) + "'")
  3000. rows = curs.fetchall()
  3001. if(ban_check(ip) == 0):
  3002. if(rows):
  3003. if(rows[0]['acl'] != 'user'):
  3004. acl = rows[0]['acl']
  3005. else:
  3006. acl = '로그인'
  3007. else:
  3008. acl = '일반'
  3009. else:
  3010. acl = '차단'
  3011. ip = ip_pas(ip, 2)
  3012. conn.close()
  3013. return(
  3014. template('other',
  3015. custom = custom_css_user(),
  3016. license = set_data['license'],
  3017. login = login_check(),
  3018. title = '사용자 메뉴',
  3019. logo = set_data['name'],
  3020. data = ip + \
  3021. '<br> \
  3022. <br> \
  3023. <span>권한 상태 : ' + acl + '</span> \
  3024. <h2>로그인 관련</h2> \
  3025. <li><a href="/login">로그인</a></li> \
  3026. <li><a href="/logout">로그아웃</a></li> \
  3027. <li><a href="/register">회원가입</a></li> \
  3028. <h2>기타</h2> \
  3029. <li><a href="/change">비밀번호 변경</a></li> \
  3030. <li><a href="/count">기여 횟수</a></li> \
  3031. <li><a href="/custom">커스텀 CSS</a></li>'
  3032. )
  3033. )
  3034. @route('/custom', method=['GET', 'POST'])
  3035. def custom_css():
  3036. conn = pymysql.connect(
  3037. user = set_data['user'],
  3038. password = set_data['pw'],
  3039. charset = 'utf8mb4',
  3040. db = set_data['db']
  3041. )
  3042. curs = conn.cursor(pymysql.cursors.DictCursor)
  3043. session = request.environ.get('beaker.session')
  3044. ip = ip_check()
  3045. if(request.method == 'POST'):
  3046. if(not re.search('(\.|:)', ip)):
  3047. curs.execute("select * from custom where user = '" + pymysql.escape_string(ip) + "'")
  3048. css_data = curs.fetchall()
  3049. if(css_data):
  3050. curs.execute("update custom set css = '" + pymysql.escape_string(request.forms.content) + "' where user = '" + pymysql.escape_string(ip) + "'")
  3051. else:
  3052. curs.execute("insert into custom (user, css) value ('" + pymysql.escape_string(ip) + "', '" + pymysql.escape_string(request.forms.content) + "')")
  3053. conn.commit()
  3054. session['Daydream'] = request.forms.content
  3055. conn.close()
  3056. return(redirect('/user'))
  3057. else:
  3058. if(not re.search('(\.|:)', ip)):
  3059. start = ''
  3060. curs.execute("select * from custom where user = '" + pymysql.escape_string(ip) + "'")
  3061. css_data = curs.fetchall()
  3062. if(css_data):
  3063. data = css_data[0]['css']
  3064. else:
  3065. data = ''
  3066. else:
  3067. start = '<span>비 로그인의 경우에는 로그인하면 날아갑니다.</span><br><br>'
  3068. try:
  3069. data = session['Daydream']
  3070. except:
  3071. data = ''
  3072. conn.close()
  3073. return(
  3074. template('other',
  3075. custom = custom_css_user(),
  3076. license = set_data['license'],
  3077. login = login_check(),
  3078. title = '커스텀 CSS',
  3079. logo = set_data['name'],
  3080. data = start + \
  3081. '<form method="post"> \
  3082. <textarea rows="30" cols="100" name="content" form="usrform">'\
  3083. + data + \
  3084. '</textarea> \
  3085. <br> \
  3086. <br> \
  3087. <div class="form-actions"> \
  3088. <button class="btn btn-primary" type="submit">저장</button> \
  3089. </div> \
  3090. </form>'
  3091. )
  3092. )
  3093. @route('/count')
  3094. def count_edit():
  3095. conn = pymysql.connect(
  3096. user = set_data['user'],
  3097. password = set_data['pw'],
  3098. charset = 'utf8mb4',
  3099. db = set_data['db']
  3100. )
  3101. curs = conn.cursor(pymysql.cursors.DictCursor)
  3102. curs.execute("select count(title) from history where ip = '" + ip_check() + "'")
  3103. count = curs.fetchall()
  3104. if(count):
  3105. data = count[0]["count(title)"]
  3106. else:
  3107. data = 0
  3108. conn.close()
  3109. return(
  3110. template('other',
  3111. custom = custom_css_user(),
  3112. license = set_data['license'],
  3113. login = login_check(),
  3114. title = '기여 횟수',
  3115. logo = set_data['name'],
  3116. data = "기여 횟수 : " + str(data)
  3117. )
  3118. )
  3119. @route('/random')
  3120. def random():
  3121. conn = pymysql.connect(
  3122. user = set_data['user'],
  3123. password = set_data['pw'],
  3124. charset = 'utf8mb4',
  3125. db = set_data['db']
  3126. )
  3127. curs = conn.cursor(pymysql.cursors.DictCursor)
  3128. curs.execute("select title from data order by rand() limit 1")
  3129. rows = curs.fetchall()
  3130. if(rows):
  3131. conn.close()
  3132. return(redirect('/w/' + url_pas(rows[0]['title'])))
  3133. else:
  3134. conn.close()
  3135. return(redirect('/'))
  3136. @route('/views/<name:path>')
  3137. def views(name = None):
  3138. if(re.search('\/', name)):
  3139. m = re.search('^(.*)\/(.*)$', name)
  3140. if(m):
  3141. n = m.groups()
  3142. plus = '/' + n[0]
  3143. rename = n[1]
  3144. else:
  3145. plus = ''
  3146. rename = name
  3147. else:
  3148. plus = ''
  3149. rename = name
  3150. return(
  3151. static_file(rename,
  3152. root = './views' + plus
  3153. )
  3154. )
  3155. @route('/error/<num:int>')
  3156. def error_test(num = None):
  3157. if(num == 1):
  3158. return(
  3159. template('other',
  3160. custom = custom_css_user(),
  3161. license = set_data['license'],
  3162. login = login_check(),
  3163. title = '권한 오류',
  3164. logo = set_data['name'],
  3165. data = '비 로그인 상태 입니다.'
  3166. )
  3167. )
  3168. elif(num == 2):
  3169. return(
  3170. template('other',
  3171. custom = custom_css_user(),
  3172. license = set_data['license'],
  3173. login = login_check(),
  3174. title = '권한 오류',
  3175. logo = set_data['name'],
  3176. data = '이 계정이 없습니다.'
  3177. )
  3178. )
  3179. elif(num == 3):
  3180. return(
  3181. template('other',
  3182. custom = custom_css_user(),
  3183. license = set_data['license'],
  3184. login = login_check(),
  3185. title = '권한 오류',
  3186. logo = set_data['name'],
  3187. data = '권한이 모자랍니다.'
  3188. )
  3189. )
  3190. elif(num == 4):
  3191. return(
  3192. template('other',
  3193. custom = custom_css_user(),
  3194. license = set_data['license'],
  3195. login = login_check(),
  3196. title = '권한 오류',
  3197. logo = set_data['name'],
  3198. data = '관리자는 차단, 검사 할 수 없습니다.'
  3199. )
  3200. )
  3201. elif(num == 5):
  3202. return(
  3203. template('other',
  3204. custom = custom_css_user(),
  3205. license = set_data['license'],
  3206. login = login_check(),
  3207. title = '사용자 오류',
  3208. logo = set_data['name'],
  3209. data = '그런 계정이 없습니다.'
  3210. )
  3211. )
  3212. elif(num == 6):
  3213. return(
  3214. template('other',
  3215. custom = custom_css_user(),
  3216. license = set_data['license'],
  3217. login = login_check(),
  3218. title = '가입 오류',
  3219. logo = set_data['name'],
  3220. data = '동일한 아이디의 사용자가 있습니다.'
  3221. )
  3222. )
  3223. elif(num == 7):
  3224. return(
  3225. template('other',
  3226. custom = custom_css_user(),
  3227. license = set_data['license'],
  3228. login = login_check(),
  3229. title = '가입 오류',
  3230. logo = set_data['name'],
  3231. data = '아이디는 20글자보다 짧아야 합니다.'
  3232. )
  3233. )
  3234. elif(num == 8):
  3235. return(
  3236. template('other',
  3237. custom = custom_css_user(),
  3238. license = set_data['license'],
  3239. login = login_check(),
  3240. title = '가입 오류',
  3241. logo = set_data['name'],
  3242. data = '아이디에는 한글과 알파벳과 공백만 허용 됩니다.'
  3243. )
  3244. )
  3245. elif(num == 9):
  3246. return(
  3247. template('other',
  3248. custom = custom_css_user(),
  3249. license = set_data['license'],
  3250. login = login_check(),
  3251. title = '변경 오류',
  3252. logo = set_data['name'],
  3253. data = '그런 계정이 없습니다.'
  3254. )
  3255. )
  3256. elif(num == 10):
  3257. return(
  3258. template('other',
  3259. custom = custom_css_user(),
  3260. license = set_data['license'],
  3261. login = login_check(),
  3262. title = '변경 오류',
  3263. logo = set_data['name'],
  3264. data = '비밀번호가 다릅니다.'
  3265. )
  3266. )
  3267. elif(num == 11):
  3268. return(
  3269. template('other',
  3270. custom = custom_css_user(),
  3271. license = set_data['license'],
  3272. login = login_check(),
  3273. title = '로그인 오류',
  3274. logo = set_data['name'],
  3275. data = '이미 로그인 되어 있습니다.'
  3276. )
  3277. )
  3278. elif(num == 12):
  3279. return(
  3280. template('other',
  3281. custom = custom_css_user(),
  3282. license = set_data['license'],
  3283. login = login_check(),
  3284. title = '로그인 오류',
  3285. logo = set_data['name'],
  3286. data = '그런 계정이 없습니다.'
  3287. )
  3288. )
  3289. elif(num == 13):
  3290. return(
  3291. template('other',
  3292. custom = custom_css_user(),
  3293. license = set_data['license'],
  3294. login = login_check(),
  3295. title = '로그인 오류',
  3296. logo = set_data['name'],
  3297. data = '비밀번호가 다릅니다.'
  3298. )
  3299. )
  3300. elif(num == 14):
  3301. return(
  3302. template('other',
  3303. custom = custom_css_user(),
  3304. license = set_data['license'],
  3305. login = login_check(),
  3306. title = '업로드 오류',
  3307. logo = set_data['name'],
  3308. data = 'jpg, gif, jpeg, png만 가능 합니다.'
  3309. )
  3310. )
  3311. elif(num == 15):
  3312. return(
  3313. template('other',
  3314. custom = custom_css_user(),
  3315. license = set_data['license'],
  3316. login = login_check(),
  3317. title = '편집 오류',
  3318. logo = set_data['name'],
  3319. data = '편집 기록은 500자를 넘을 수 없습니다.'
  3320. )
  3321. )
  3322. elif(num == 16):
  3323. return(
  3324. template('other',
  3325. custom = custom_css_user(),
  3326. license = set_data['license'],
  3327. login = login_check(),
  3328. title = '업로드 오류',
  3329. logo = set_data['name'],
  3330. data = '동일한 이름의 파일이 있습니다.'
  3331. )
  3332. )
  3333. elif(num == 17):
  3334. return(
  3335. template('other',
  3336. custom = custom_css_user(),
  3337. license = set_data['license'],
  3338. login = login_check(),
  3339. title = '업로드 오류',
  3340. logo = set_data['name'],
  3341. data = '파일 용량은 ' + set_data['upload'] + 'MB를 넘길 수 없습니다.'
  3342. )
  3343. )
  3344. elif(num == 18):
  3345. return(
  3346. template('other',
  3347. custom = custom_css_user(),
  3348. license = set_data['license'],
  3349. login = login_check(),
  3350. title = '편집 오류',
  3351. logo = set_data['name'],
  3352. data = '내용이 원래 문서와 동일 합니다.'
  3353. )
  3354. )
  3355. elif(num == 19):
  3356. return(
  3357. template('other',
  3358. custom = custom_css_user(),
  3359. license = set_data['license'],
  3360. login = login_check(),
  3361. title = '이동 오류',
  3362. logo = set_data['name'],
  3363. data = '이동 하려는 곳에 문서가 이미 있습니다.'
  3364. )
  3365. )
  3366. elif(num == 20):
  3367. return(
  3368. template('other',
  3369. custom = custom_css_user(),
  3370. license = set_data['license'],
  3371. login = login_check(),
  3372. title = '비밀번호 오류',
  3373. logo = set_data['name'],
  3374. data = '재 확인이랑 비밀번호가 다릅니다.'
  3375. )
  3376. )
  3377. else:
  3378. return(redirect('/'))
  3379. @error(404)
  3380. def error_404(error):
  3381. return(redirect('/w/' + url_pas(set_data['frontpage'])))
  3382. run(
  3383. app = app,
  3384. server='tornado',
  3385. host = '0.0.0.0',
  3386. port = int(set_data['port'])
  3387. )