app.py 130 KB

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