fetchmirrorsgui.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. """
  5. The MIT License (MIT)
  6. Copyright (c) Andrew Brookes 2021
  7. andybrookestar[small snail]gmail[period]com
  8. aka captainsensible
  9. aka andybrookestar
  10. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  11. documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to
  12. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom
  13. the Software is furnished to do so, subject to the following conditions:
  14. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  19. DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. See https://opensource.org/licenses/MIT for details
  23. """
  24. import operator
  25. from operator import itemgetter
  26. import requests
  27. import time
  28. import os
  29. import tkinter as tk
  30. from tkinter import ttk
  31. import re
  32. import sys
  33. from tkinter.messagebox import showinfo
  34. from tkinter import font
  35. user = os.getenv("SUDO_USER")
  36. if user is None:
  37. print (" re-run this program using 'sudo'" )
  38. sys.exit()
  39. Worldwide1="""#Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
  40. #Server = https://mirror.rackspace.com/archlinux/$repo/os/$arch
  41. """
  42. # next def is evoked by process button
  43. def button_clicked():
  44. var.set('ok working on it ')
  45. # res = requests.get('https://archlinux.org/mirrorlist/all/')
  46. t=selected.get()
  47. print(t)
  48. #choice 1 populate mirrorlist none enabled
  49. if t =="1":
  50. res = requests.get('https://archlinux.org/mirrorlist/all/')
  51. myvar= res.text
  52. file = open('/etc/pacman.d/mirrorlist' , 'w')
  53. file.write(myvar)
  54. file.close()
  55. var.set("done ")
  56. #choice 2 populate and enable all
  57. elif t =='2':
  58. res = requests.get('https://archlinux.org/mirrorlist/all/')
  59. myvar= res.text
  60. newvar = re.sub(r'[#](?!#)', " ", myvar)
  61. file = open('/etc/pacman.d/mirrorlist' , 'w')
  62. file.write(newvar)
  63. file.close()
  64. var.set("done ")
  65. elif t=='3':
  66. d= countries.get()
  67. if d=="select nearest Country":
  68. var.set("please also choose a country from drop down")
  69. elif d=="Worldwide":
  70. t=countryMirrors(Worldwide1)
  71. if t =="done":
  72. var.set("done written to /etc/pacman.d/mirrorlist")
  73. elif d=="Australia":
  74. t=countryMirrorsLive('AU')
  75. if t =="done":
  76. var.set("done written to /etc/pacman.d/mirrorlist")
  77. elif d=="Austria":
  78. t=countryMirrorsLive('AT')
  79. if t =="done":
  80. var.set("done written to /etc/pacman.d/mirrorlist")
  81. elif d=="Bangladesh":
  82. t=countryMirrorsLive('BD')
  83. if t =="done":
  84. var.set("done written to /etc/pacman.d/mirrorlist")
  85. elif d=="Belarus":
  86. t=countryMirrorsLive('BY')
  87. if t =="done":
  88. var.set("done written to /etc/pacman.d/mirrorlist")
  89. elif d=="Belgium":
  90. t=countryMirrorsLive('BE')
  91. if t =="done":
  92. var.set("done written to /etc/pacman.d/mirrorlist")
  93. elif d=="BosniaNHezegovia":
  94. t=countryMirrorsLive('BA')
  95. if t =="done":
  96. var.set("done written to /etc/pacman.d/mirrorlist")
  97. elif d=="Brazil":
  98. t=countryMirrorsLive('BR')
  99. if t =="done":
  100. var.set("done written to /etc/pacman.d/mirrorlist")
  101. elif d=="Bulgaria":
  102. t=countryMirrorsLive('BG')
  103. if t =="done":
  104. var.set("done written to /etc/pacman.d/mirrorlist")
  105. elif d=="Cambodia":
  106. t=countryMirrorsLive('KH')
  107. if t =="done":
  108. var.set("done written to /etc/pacman.d/mirrorlist")
  109. elif d=="Canada":
  110. t=countryMirrorsLive('CA')
  111. if t =="done":
  112. var.set("done written to /etc/pacman.d/mirrorlist")
  113. elif d=="Chile":
  114. t=countryMirrorsLive('CL')
  115. if t =="done":
  116. var.set("done written to /etc/pacman.d/mirrorlist")
  117. elif d=="China":
  118. t=countryMirrorsLive('CN')
  119. if t =="done":
  120. var.set("done written to /etc/pacman.d/mirrorlist")
  121. elif d=="Colombia":
  122. t=countryMirrorsLive('CO')
  123. if t =="done":
  124. var.set("done written to /etc/pacman.d/mirrorlist")
  125. elif d=="Croatia":
  126. t=countryMirrorsLive('HR')
  127. if t =="done":
  128. var.set("done written to /etc/pacman.d/mirrorlist")
  129. elif d=="Czechia":
  130. t=countryMirrorsLive('CZ')
  131. if t =="done":
  132. var.set("done written to /etc/pacman.d/mirrorlist")
  133. elif d=="Denmark":
  134. t=countryMirrorsLive('DK')
  135. if t =="done":
  136. var.set("done written to /etc/pacman.d/mirrorlist")
  137. elif d=="Ecuador":
  138. t=countryMirrorsLive('EC')
  139. if t =="done":
  140. var.set("done written to /etc/pacman.d/mirrorlist")
  141. elif d=="Estonia":
  142. t=countryMirrorsLive('EE')
  143. if t =="done":
  144. var.set("done written to /etc/pacman.d/mirrorlist")
  145. elif d=="Finland":
  146. t=countryMirrorsLive('FL')
  147. if t =="done":
  148. var.set("done written to /etc/pacman.d/mirrorlist")
  149. elif d=="France":
  150. t=countryMirrorsLive('FR')
  151. if t =="done":
  152. var.set("done written to /etc/pacman.d/mirrorlist")
  153. elif d=="Georgia":
  154. t=countryMirrorsLive('GE')
  155. if t =="done":
  156. var.set("done written to /etc/pacman.d/mirrorlist")
  157. elif d=="Germany":
  158. t=countryMirrorsLive('DE')
  159. if t =="done":
  160. var.set("done written to /etc/pacman.d/mirrorlist")
  161. elif d=="Greece":
  162. t=countryMirrorsLive('GR')
  163. if t =="done":
  164. var.set("done written to /etc/pacman.d/mirrorlist")
  165. elif d=="HongKong":
  166. t=countryMirrorsLive('HK')
  167. if t =="done":
  168. var.set("done written to /etc/pacman.d/mirrorlist")
  169. elif d=="Hungary":
  170. t=countryMirrorsLive('HU')
  171. if t =="done":
  172. var.set("done written to /etc/pacman.d/mirrorlist")
  173. elif d=="Iceland":
  174. t=countryMirrorsLive('IS')
  175. if t =="done":
  176. var.set("done written to /etc/pacman.d/mirrorlist")
  177. elif d=="India":
  178. t=countryMirrorsLive('IN')
  179. if t =="done":
  180. var.set("done written to /etc/pacman.d/mirrorlist")
  181. elif d=="Indonesia":
  182. t=countryMirrorsLive('ID')
  183. if t =="done":
  184. var.set("done written to /etc/pacman.d/mirrorlist")
  185. elif d=="Iran":
  186. t=countryMirrorsLive('IR')
  187. if t =="done":
  188. var.set("done written to /etc/pacman.d/mirrorlist")
  189. elif d=="Ireland":
  190. t=countryMirrorsLive('IE')
  191. if t =="done":
  192. var.set("done written to /etc/pacman.d/mirrorlist")
  193. elif d=="Israel":
  194. t=countryMirrorsLive('IL')
  195. if t =="done":
  196. var.set("done written to /etc/pacman.d/mirrorlist")
  197. elif d=="Italy":
  198. t=countryMirrorsLive('IT')
  199. if t =="done":
  200. var.set("done written to /etc/pacman.d/mirrorlist")
  201. elif d=="Japan":
  202. t=countryMirrorsLive('JP')
  203. if t =="done":
  204. var.set("done written to /etc/pacman.d/mirrorlist")
  205. elif d=="Kazakhstan":
  206. t=countryMirrorsLive('KZ')
  207. if t =="done":
  208. var.set("done written to /etc/pacman.d/mirrorlist")
  209. elif d=="Kenya":
  210. t=countryMirrorsLive('KE')
  211. if t =="done":
  212. var.set("done written to /etc/pacman.d/mirrorlist")
  213. elif d=="Latvia":
  214. t=countryMirrorsLive('LV')
  215. if t =="done":
  216. var.set("done written to /etc/pacman.d/mirrorlist")
  217. elif d=="Lithuania":
  218. t=countryMirrorsLive('LT')
  219. if t =="done":
  220. var.set("done written to /etc/pacman.d/mirrorlist")
  221. elif d=="Luxembourg":
  222. t=countryMirrorsLive('LU')
  223. if t =="done":
  224. var.set("done written to /etc/pacman.d/mirrorlist")
  225. elif d=="Mexico":
  226. t=countryMirrorsLive('MX')
  227. if t =="done":
  228. var.set("done written to /etc/pacman.d/mirrorlist")
  229. elif d=="Moldova":
  230. t=countryMirrorsLive('MD')
  231. if t =="done":
  232. var.set("done written to /etc/pacman.d/mirrorlist")
  233. elif d=="Monaco":
  234. t=countryMirrorsLive('MC')
  235. if t =="done":
  236. var.set("done written to /etc/pacman.d/mirrorlist")
  237. elif d=="Netherlands":
  238. t=countryMirrorsLive('NL')
  239. if t =="done":
  240. var.set("done written to /etc/pacman.d/mirrorlist")
  241. elif d=="NewCaledonia":
  242. t=countryMirrorsLive('NC')
  243. if t =="done":
  244. var.set("done written to /etc/pacman.d/mirrorlist")
  245. elif d=="NewZealand":
  246. t=countryMirrors('NZ')
  247. if t =="done":
  248. var.set("done written to /etc/pacman.d/mirrorlist")
  249. elif d=="North Macedonia":
  250. t=countryMirrorsLive('MK')
  251. if t =="done":
  252. var.set("done written to /etc/pacman.d/mirrorlist")
  253. elif d=="Norway":
  254. t=countryMirrorsLive('NO')
  255. if t =="done":
  256. var.set("done written to /etc/pacman.d/mirrorlist")
  257. elif d=="Pakistan":
  258. t=countryMirrorsLive('PK')
  259. if t =="done":
  260. var.set("done written to /etc/pacman.d/mirrorlist")
  261. elif d=="Paraguay":
  262. t=countryMirrorsLive('PY')
  263. if t =="done":
  264. var.set("done written to /etc/pacman.d/mirrorlist")
  265. elif d=="Poland":
  266. t=countryMirrorsLive('PL')
  267. if t =="done":
  268. var.set("done written to /etc/pacman.d/mirrorlist")
  269. elif d=="Portugal":
  270. t=countryMirrorsLive('PT')
  271. if t =="done":
  272. var.set("done written to /etc/pacman.d/mirrorlist")
  273. elif d=="Romania":
  274. t=countryMirrorsLive('RO')
  275. if t =="done":
  276. var.set("done written to /etc/pacman.d/mirrorlist")
  277. elif d=="'Russia":
  278. t=countryMirrorsLive('RU')
  279. if t =="done":
  280. var.set("done written to /etc/pacman.d/mirrorlist")
  281. elif d=="Reunion":
  282. t=countryMirrorsLive('RE')
  283. if t =="done":
  284. var.set("done written to /etc/pacman.d/mirrorlist")
  285. elif d=="Serbia":
  286. t=countryMirrorsLive('RS')
  287. if t =="done":
  288. var.set("done written to /etc/pacman.d/mirrorlist")
  289. elif d=="Singapore":
  290. t=countryMirrorsLive('SG')
  291. if t =="done":
  292. var.set("done written to /etc/pacman.d/mirrorlist")
  293. elif d=="Slovakia":
  294. t=countryMirrorsLive('SK')
  295. if t =="done":
  296. var.set("done written to /etc/pacman.d/mirrorlist")
  297. elif d=="Slovenia":
  298. t=countryMirrorsLive('SI')
  299. if t =="done":
  300. var.set("done written to /etc/pacman.d/mirrorlist")
  301. elif d=="South Africa":
  302. t=countryMirrorsLive('ZA')
  303. if t =="done":
  304. var.set("done written to /etc/pacman.d/mirrorlist")
  305. elif d=="South Korea":
  306. t=countryMirrorsLive('KR')
  307. if t =="done":
  308. var.set("done written to /etc/pacman.d/mirrorlist")
  309. elif d=="Spain":
  310. t=countryMirrorsLive('ES')
  311. if t =="done":
  312. var.set("done written to /etc/pacman.d/mirrorlist")
  313. elif d=="Sweden":
  314. t=countryMirrorsLive('SE')
  315. if t =="done":
  316. var.set("done written to /etc/pacman.d/mirrorlist")
  317. elif d=="Switzerland":
  318. t=countryMirrorsLive('CH')
  319. if t =="done":
  320. var.set("done written to /etc/pacman.d/mirrorlist")
  321. elif d=="Taiwan":
  322. t=countryMirrorsLive('TW')
  323. if t =="done":
  324. var.set("done written to /etc/pacman.d/mirrorlist")
  325. elif d=="Thailand":
  326. t=countryMirrorsLive('TH')
  327. if t =="done":
  328. var.set("done written to /etc/pacman.d/mirrorlist")
  329. elif d=="Turkey":
  330. t=countryMirrorsLive('TR')
  331. if t =="done":
  332. var.set("done written to /etc/pacman.d/mirrorlist")
  333. elif d=="Ukraine":
  334. t=countryMirrorsLive('UA')
  335. if t =="done":
  336. var.set("done written to /etc/pacman.d/mirrorlist")
  337. elif d=="United Kingdom":
  338. t=countryMirrorsLive('GB')
  339. if t =="done":
  340. var.set("done written to /etc/pacman.d/mirrorlist")
  341. elif d=="USA":
  342. t=countryMirrorsLive('US')
  343. if t =="done":
  344. var.set("done written to /etc/pacman.d/mirrorlist")
  345. elif d=="Vietnam":
  346. t=countryMirrorsLive('VN')
  347. if t =="done":
  348. var.set("done written to /etc/pacman.d/mirrorlist")
  349. else:
  350. print ("i have no clue what you picked")
  351. # here do all filtering of string get time elapsed and write to /etc/pacman.d/mirrors
  352. def countryMirrorsLive(somevar):
  353. myVar=somevar
  354. myDic ={}
  355. res=requests.get('https://archlinux.org/mirrorlist/?country='+myVar)
  356. mirrorString =res.text
  357. lines= mirrorString.splitlines()
  358. for line in lines:
  359. z= re.match(r'[#](?!#)',line)
  360. if z:
  361. print(line)
  362. t=re.sub(r'(#Server\s=)', "",line)
  363. try:
  364. times=(requests.get(t,timeout=2).elapsed.total_seconds())
  365. myDic[t]=times
  366. except:
  367. print ("something went wrong")
  368. print(t)
  369. print(myDic)
  370. sort_dict= dict(sorted(myDic.items(), key=operator.itemgetter(1)))
  371. print("Sorted Dictionary by value: ", sort_dict)
  372. file2 = open('/etc/pacman.d/mirrorlist','w')
  373. for k, v in sort_dict.items():
  374. print(k)
  375. try:
  376. file2.write('Server = '+ k+'\n')
  377. except:
  378. print("a problem occured")
  379. file2.close()
  380. process="done"
  381. return process
  382. # above filters out two ## together
  383. def countryMirrors(someVar):
  384. # here could put all processing
  385. stringOfMirrorsNoHash = ""
  386. myDic= {}
  387. stringOfMirrorsNoHash = re.sub(r'^[##\s]', " ", someVar)
  388. stringOfMirrorsNoHash2 = re.sub(r'(Server\s=)', "", stringOfMirrorsNoHash )
  389. print(stringOfMirrorsNoHash2)
  390. lines = stringOfMirrorsNoHash2.splitlines()
  391. for t in lines:
  392. try:
  393. times=(requests.get(t,timeout=3).elapsed.total_seconds())
  394. myDic[t]=times
  395. except:
  396. print ("there is a problem")
  397. print(myDic)
  398. sort_dict= dict(sorted(myDic.items(), key=operator.itemgetter(1)))
  399. print("Sorted Dictionary by value: ", sort_dict)
  400. file2 = open('/etc/pacman.d/mirrorlist','w')
  401. for k, v in sort_dict.items():
  402. print(k)
  403. try:
  404. file2.write('Server = '+ k+'\n')
  405. except:
  406. print("a problem occured")
  407. file2.close()
  408. process="done"
  409. return process
  410. def radio_selected():
  411. t= selected.get()
  412. print(t)
  413. var.set("waiting")
  414. def testButtonClicked():
  415. print('test button cloicked')
  416. var.set("ok working on it")
  417. def countryPicked(event):
  418. d=countries.get()
  419. print(d)
  420. var.set(' waiting for process button to be clicked')
  421. def _quit():
  422. root.quit()
  423. root.destroy()
  424. """ root """
  425. root = tk.Tk()
  426. root.geometry('500x420')
  427. root.resizable(True,True)
  428. root.title('fetchMirrorsGui')
  429. root.columnconfigure(0,weight=3)
  430. root.columnconfigure(1,weight=1)
  431. root.columnconfigure(2,weight=1)
  432. root.rowconfigure(0,weight=1)
  433. root.rowconfigure(1,weight=1)
  434. root.rowconfigure(2,weight=1)
  435. root.rowconfigure(3,weight=1)
  436. root.rowconfigure(4,weight =1)
  437. root.rowconfigure(5,weight =1)
  438. root.configure(background='LemonChiffon2')
  439. root.option_add("*background", "PaleGoldenrod"),
  440. root.option_add("*foreground", "purple"),
  441. """ style """
  442. style= ttk.Style()
  443. style.configure('TButton',foreground=[("black")],background=["LightGoldenrod1"])
  444. style.map('TButton', foreground=[('hover', 'black')], background=[('hover', 'LimeGreen')])
  445. style.configure("TCombobox", foreground= "purple", activebackground= "purple", font=('Helvetica', 14))
  446. style.map('TCombobox', foreground=[('pressed', 'red'), ('active', 'blue')])
  447. style.map('TCombobox', foreground=[('hover', 'red')], background=[('hover', 'yellow')])
  448. style.configure('TCheckbutton',foreground=[("black")],background=["brown"])
  449. style.map('TCheckbutton', foreground=[('hover', 'black')], background=[('hover', 'yellow')])
  450. HighlightFont = font.Font(family='Times', size=12, weight='bold')
  451. topLable = ttk.Label(root, text =""" Radio button 1 for whole mirror list (needs editing to enable) \n
  452. Radio 2 same but all enabled and .... \n for your Country (or nearest) \n
  453. click radio button 3 first ..then select a Country from drop down list \n
  454. Then as in all 3 cases click button to process """, background='ivory',foreground ="black" , font=HighlightFont)
  455. topLable.grid(column=0,row= 0,columnspan=3)
  456. """label next yellow button """
  457. var = tk.StringVar()
  458. var.set('waiting to process')
  459. """ radio 1 label """
  460. l = ttk.Label(root, text ="populate mirror list and do manual edit to \n activate mirror you want (1) -> ", background='LemonChiffon',foreground ="black" )
  461. l.grid(column=0,row=1)
  462. """ radio 1"""
  463. selected = tk.StringVar()
  464. selected.set('2')
  465. """ radio 2 label """
  466. label = ttk.Label(root, text="populate and have all mirrors enabled (2)->", background='LemonChiffon', foreground='black')
  467. label.grid(column=0,row=2)
  468. inform = ttk.Label(root, textvariable =var , background='gray84', foreground='black', font=HighlightFont)
  469. inform.grid(column=0,row=4)
  470. """ radio buttons """
  471. r = ttk.Radiobutton(root,text='1', value='1', variable=selected,command=radio_selected)
  472. r.grid(column=1, row=1 )
  473. s = ttk.Radiobutton(root,text='2', value='2', variable=selected,command=radio_selected)
  474. s.grid(column=1,row=2)
  475. t= ttk.Radiobutton(root,text='3', value='3', variable=selected,command=radio_selected)
  476. t.grid(column=1, row=3)
  477. """process button"""
  478. Button1 = ttk.Button(root, text='Process Above Selection',command=button_clicked)
  479. Button1.grid(column=0,row=5,columnspan=2)
  480. """ country combobox """
  481. countryVar = tk.StringVar()
  482. countries =ttk.Combobox(root, textvariable= countryVar)
  483. countryVar.set("select nearest Country")
  484. countries.grid(column= 0, row =3)
  485. countries['values']= ('Worldwide','Australia','Austria','Bangladesh' ,'Belarus','Belgium','BosniaNHezegovia',\
  486. 'Brazil', 'Bulgaria', 'Canada','Chile','China','Colombia','Combodia','Croatia','Czechia','Denmark','Ecuador',\
  487. 'Estonia','Finland','France','Georgia','Germany','Greece','HongKong','Hungary','Iceland','India','Indonesia','iran','Ireland',\
  488. 'Israel','Italy','Japan','Kazakhstan', 'Kenya', 'Latvia','Lithuania','Luxembourg','Mexico', 'Moldova','Monaco','Netherlands','NewCaledonia',\
  489. 'NewZealand','North Macedonia','Norway','Pakistan','Paraguay','Poland','Portugal','Romania','Russia','Reunion','Serbia',\
  490. 'Singapore','Slovakia','Slovenia','South Africa','South Korea','Spain','Sweden','Switzerland','Taiwan'\
  491. 'Thailand','Turkey','Ukraine','United Kingdom','USA','Vietnam' )
  492. countries.bind('<<ComboboxSelected>>',countryPicked)
  493. """ testButton
  494. testButton = ttk.Button(root, text='test event button', command=lambda: button_clicked())
  495. testButton.grid(column=1,row=4)
  496. """
  497. """ green exit button """
  498. exit_button = ttk.Button(root, text="Exit", command=_quit)
  499. exit_button.grid(column=2,row=5)
  500. root.mainloop()