[asp] BSB

Viewer

  1. ### Import the libraries for the creation of the GUI
  2. from tkinter import *
  3. from tkinter import messagebox
  4.  
  5. # Email libraries
  6. from email.message import EmailMessage
  7. import ssl
  8. import smtplib
  9.  
  10.  
  11. ### Import the libraries for web scraping
  12. from selenium import webdriver
  13.  
  14. from selenium.webdriver.chrome.service import Service
  15.  
  16. from selenium.webdriver.common.by import By
  17.  
  18. from selenium.webdriver.support.ui import WebDriverWait
  19.  
  20. from selenium.webdriver.support import expected_conditions as EC
  21.  
  22. from bs4 import BeautifulSoup
  23.  
  24. import codecs
  25.  
  26. import re
  27.  
  28. from webdriver_manager.chrome import ChromeDriverManager
  29.  
  30. import schedule
  31.  
  32. import unittest
  33. import time
  34. from selenium import webdriver
  35. from selenium.webdriver.support.select import Select
  36. from selenium.webdriver.common.by import By
  37. from selenium.webdriver.support.ui import WebDriverWait
  38. from selenium.webdriver.support import expected_conditions as EC
  39.  
  40. import time 
  41.  
  42. from pymongo import MongoClient
  43.  
  44. ### Find the mongoDB host and name the data collection
  45. mongoHost = 'mongodb://localhost:27017/'
  46. dataCollection = "BoutsioukisSolonBox"
  47.  
  48.  
  49. ### Initiate mongo connection
  50. client = MongoClient(mongoHost) # Establish a connection with the server by creating a client
  51. db = client[dataCollection] # or client.anatoliaStudents
  52. coll = db['items'] # or db.items
  53.  
  54. ### Create the root window and Give it a title
  55. root = Tk()
  56. root.title("Boutsioukis Solon Box | Πορεία Δικογραφίας")
  57.  
  58. # setting attribute
  59. root.state('zoomed')
  60.  
  61.  
  62. ### Create the visuals (lines, text, etc.) to be easy-to-read for my client
  63. Label(root, bg="white", width=10000, height=2).place(x=0, y=0)
  64. Label(root, text="BSB", font='Helvetica 10 bold', bg="white", fg="black", width=4, height=2).place(x=0, y=0)
  65. line1 = Frame(root, bg="black", height=2, width=10000).place(x=0, y=28)
  66. line2 = Frame(root, bg="black", height=2, width=10000).place(x=0, y=32)
  67.  
  68. Label(root, bg="#999999", width=10000, height=3).place(x=0, y=33.5)
  69. Label(root, text="Case Database", font='Helvetica 13', bg="#999999", fg="black", width=13, height=1).place(x=0, y=46.5)
  70. line3 = Frame(root, bg="black", height=2, width=10000).place(x=0, y=83)
  71.  
  72.  
  73. ### Make the required input by the client global so it can be used in every funciton 
  74. global tmpJury
  75. global tmpNumber
  76. global tmpYear
  77. global tmpName
  78. global tmpNotes
  79.  
  80. ### Create a counter to move each case's details into the correct place of the ListBox
  81. global counter # Allow the counter to be used everywhere in every function
  82. counter = 0
  83.  
  84. # Create the list that all the case's details are going to be saved
  85. global caseList #Allow the list to be used everywhere in every function
  86. caseList = []
  87.  
  88.  
  89.  
  90.  
  91. def acceptData():
  92.     ### Create a new window (top-level) that is going to accept the case's details
  93.     addCaseWindow = Toplevel(root)
  94.  
  95.     ### Name all the jurys that the client has the option of choosing
  96.     jurysObjects = ["ΑΡΕΙΟΣ ΠΑΓΟΣ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΑΘΗΝΩΝ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΑΜΑΡΟΥΣΙΟΥ"
  97.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΑΧΑΡΝΩΝ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΒΑΣΙΛΙΚΩΝ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ",
  98.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΙΛΙΟΥ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΚΑΛΛΙΘΕΑΣ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΚΟΥΦΑΛΙΩΝ",
  99.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΚΡΩΠΙΑΣ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΛΑΓΚΑΔΑ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΛΑΥΡΙΟΥ"
  100.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΜΑΡΑΘΩΝΟΣ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΜΕΓΑΡΩΝ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΝΕΑΣ ΙΩΝΙΑΣ",
  101.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΠΕΙΡΑΙΑ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΠΕΡΙΣΤΕΡΙΟΥ""ΕΙΡΗΝΟΔΙΚΕΙΟ ΧΑΛΑΝΔΡΙΟΥ",
  102.                     "ΕΙΡΗΝΟΔΙΚΕΙΟ ΧΑΛΚΙΔΑΣ""ΕΦΕΤΕΙΟ ΑΘΗΝΩΝ""ΕΦΕΤΕΙΟ ΕΥΒΟΙΑΣ""ΕΦΕΤΕΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ",
  103.                     "ΕΦΕΤΕΙΟ ΠΕΙΡΑΙΩΣ""ΠΡΩΤΟΔΙΚΕΙΟ ΑΘΗΝΩΝ""ΠΡΩΤΟΔΙΚΕΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ",
  104.                     "ΠΡΩΤΟΔΙΚΕΙΟ ΠΕΙΡΑΙΑ""ΠΡΩΤΟΔΙΚΕΙΟ ΧΑΛΚΙΔΑΣ"]
  105.     
  106.     ### Create a class that provides helper functions for directly creating and accessing such variables in that interpreter
  107.     juryVar = StringVar(addCaseWindow)
  108.  
  109.     ### Set the title of this toplevel window
  110.     addCaseWindow.title("ADD CASE")
  111.  
  112.     ### Set the geometry of the toplevel window
  113.     addCaseWindow.geometry("360x230")
  114.     addCaseWindow.resizable(0,0) # Make window unresizable
  115.  
  116.     ### Set the visual details of the toplevel window
  117.     Label(addCaseWindow, text ="REQUIRED *", fg = "red", font='Helvetica 7',
  118.           width=10, height=1).place(x=0,y=0)
  119.     
  120.     Label(addCaseWindow, text ="JURY", fg = "black", font='Helvetica 9',
  121.           width=14, height=1).place(x=42,y=17)
  122.     Label(addCaseWindow, text ="*", fg = "red", font='Helvetica 9',
  123.           width=1, height=1).place(x=110,y=17)
  124.     
  125.     juryVar.set("                                   ") # Set the default value of dropdownmenu
  126.     juryMenu = OptionMenu(addCaseWindow, juryVar, *jurysObjects)
  127.     juryMenu.place(x=146, y=12) # Create a dropdown/option menu
  128.     
  129.     Label(addCaseWindow, text ="G.A.K. NUMBER", fg = "black", font='Helvetica 9',
  130.           width=14, height=1).place(x=42,y=47)
  131.     Label(addCaseWindow, text ="*", fg = "red", font='Helvetica 9',
  132.           width=1, height=1).place(x=139,y=47)
  133.     numberEntry = Entry(addCaseWindow, font='Helvetica 9')
  134.     numberEntry.place(x=150, y=47)
  135.     
  136.     Label(addCaseWindow, text ="G.A.K. YEAR", fg = "black", font='Helvetica 9',
  137.           width=14, height=1).place(x=42,y=77)
  138.     Label(addCaseWindow, text ="*", fg = "red", font='Helvetica 9',
  139.           width=1, height=1).place(x=128,y=77)
  140.     yearEntry = Entry(addCaseWindow, font='Helvetica 9')
  141.     yearEntry.place(x=150, y=77)
  142.  
  143.     Label(addCaseWindow, text ="UNIQUE NAME", fg = "black", font='Helvetica 9',
  144.           width=14, height=1).place(x=42,y=107)
  145.     nameEntry = Entry(addCaseWindow, font='Helvetica 9')
  146.     nameEntry.place(x=150, y=107)
  147.     
  148.     Label(addCaseWindow, text ="NOTES", fg = "black", font='Helvetica 9',
  149.           width=14, height=1).place(x=42,y=137)
  150.     notesEntry = Entry(addCaseWindow, font='Helvetica 9')
  151.     notesEntry.place(x=150, y=137)
  152.     
  153.     
  154.     ### Create a function to retrieve the user's innput from the toplevel window
  155.     def getValues():
  156.         ### All these local variables are now stored to global variables so that they can be accessed by other functions
  157.         global tmpJury
  158.         global tmpNumber
  159.         global tmpYear
  160.         global tmpName
  161.         global tmpNotes
  162.         
  163.         ### Retrive all the data that the user inputted in the entry variables using the .get() function from the Tkinter library
  164.         tmpJury = juryVar.get()
  165.         tmpNumber = numberEntry.get()
  166.         tmpYear = yearEntry.get()
  167.         tmpName = nameEntry.get()
  168.         tmpNotes=notesEntry.get()
  169.         
  170.         ### Check whether the user has provided a sufficient input to all the required fieldsif not show an error
  171.         if tmpNumber == "":
  172.             messagebox.showerror('BSB Error', 'Error: Please fill all the required fields!')
  173.         elif tmpYear == "":
  174.             messagebox.showerror('BSB Error', 'Error: Please fill all the required fields!')
  175.         elif tmpJury == "":
  176.             messagebox.showerror('BSB Error', 'Error: Please fill all the required fields!')
  177.         else:
  178.             addCaseWindow.destroy()
  179.             inputData()
  180.     
  181.  
  182.     ### Create the button that calls the getValues() function each time its pressed
  183.     finalAdd = Button(addCaseWindow, text= "ADD CASE", bg="#636363", fg="black"
  184.                       activebackground="#535353", font='Helvetica 8', command = getValues).place(x=150, y=190)
  185.  
  186. ### Create a button that call the acceptData function which opens the toplevel window in order for the client to enter the case's details and get the results
  187. addCase = Button(root, text ="ADD CASE", bg="#636363", fg="black", activebackground="#535353"
  188.                    font='Helvetica 8', command = acceptData).place(x=125, y=46.5)
  189.  
  190.  
  191.  
  192.  
  193. def delCaseDatabase():
  194.     global tmpDelCase
  195.     ### Delete a document from the mongoDB database based on wther the field uniqueName has the value tmpDelName
  196.     coll.delete_one({"GAK NUMBER": str(tmpDelCase)})
  197.     
  198.     loadTrueCases()
  199.  
  200.  
  201.  
  202. ### Create a function that inputs to the government's website the case's details, scrape the results, shwo them to the user and store them into the GUI's database
  203. def inputData():
  204.     global combinedDetails
  205.     global counter
  206.     counter = counter + 1
  207.     
  208.     ### Setting up the webdriver and directing the service to its directory
  209.     serv_obj=Service("C:\Drivers\chromedriver_win32\chromedriver.exe")
  210.  
  211.     driver = webdriver.Chrome(service=serv_obj)
  212.     driver.get("https://extapps.solon.gov.gr/mojwp/faces/TrackLdoPublic")
  213.     
  214.     ### Locate the elements in the website and send the user’s data
  215.     driver.find_element(By.NAME"courtOfficeOC").send_keys(str(tmpJury))
  216.     
  217.     driver.find_element(By.NAME"it1").send_keys(str(tmpNumber))
  218.     
  219.     driver.find_element(By.NAME"it2").send_keys(str(tmpYear))
  220.     
  221.     driver.find_element(By.ID,"ldoSearch").click()
  222.  
  223.     time.sleep(10)
  224.  
  225.  
  226.     ### Get the number of rows of the table I want to scrape info from
  227.     rows = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr'))
  228.  
  229.  
  230.     ### Get the number of columns of the table I want to scrape info from
  231.     columns = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td'))
  232.  
  233.  
  234.     ### Create the list that all the case's details are going to get in
  235.     preDetailsList = []
  236.  
  237.  
  238.  
  239.     ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has more than 1 row
  240.     before_XPath = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr['
  241.     aftertd_XPath = ']/td['
  242.     aftertr_XPath = "]"
  243.         
  244.     
  245.     ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has 1 row
  246.     before_XPath2 = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td['
  247.     aftertr_XPath2 = "]"
  248.  
  249.  
  250.     ### Check whether the table has more than one row and accordingly scrape the information
  251.     if rows > 1:
  252.         for t_row in range(1(rows + 1)):
  253.             for t_column in range(1(columns + 1)):
  254.                 FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
  255.                 cell_text = driver.find_element(By.XPATH,FinalXPath).text
  256.                 preDetailsList.append(str(cell_text))
  257.     else:
  258.         for t_column in range(1(columns + 1)):
  259.             FinalXPath = before_XPath2 + str(t_column) + aftertr_XPath2
  260.             cell_text = driver.find_element(By.XPATH,FinalXPath).text
  261.             preDetailsList.append(str(cell_text))
  262.     
  263.     ### Close the browser
  264.     driver.close()
  265.     
  266.     ### Create the string that all the cases info will be present
  267.     combinedDetails = ''
  268.     
  269.     
  270.     ### Add all the list's objects
  271.     for detail in preDetailsList:
  272.         combinedDetails += ' | ' + detail
  273.  
  274.  
  275.     # ### Add this data into the list with all the cases
  276.     # caseList.append(str(combinedDetails))
  277.  
  278.     ### Call the nessesary functions in order for the program to run efficiently
  279.     inputDatabase()
  280.     loadTrueCases()
  281.  
  282.  
  283. def deleteData():
  284.     ### Create a new window (top-level) that is going to delete a case from the database
  285.     deleteCaseWindow = Toplevel(root)
  286.     
  287.     ### Set the title of this toplevel window
  288.     deleteCaseWindow.title("DELETE CASE")
  289.  
  290.     ### Set the geometry of the toplevel window
  291.     deleteCaseWindow.geometry("360x230")
  292.     deleteCaseWindow.resizable(0,0) # Make window unresizable
  293.  
  294.  
  295.     ### Set the visual details of the toplevel window
  296.     Label(deleteCaseWindow, text ="REQUIRED *", fg = "red", font='Helvetica 7',
  297.           width=10, height=1).place(x=0,y=0)
  298.  
  299.  
  300.     descr = Label(deleteCaseWindow, text ="Guide: Type the 'G.A.K. NUMBER' of the case \n"
  301.                   "you want to delete without misspellings.", fg = "black", font='Helvetica 9', 
  302.           width=100, height=2).place(x=-172,y=34)
  303.  
  304.     Label(deleteCaseWindow, text ="G.A.K. NUMBER", fg = "black", font='Helvetica 9',
  305.           width=14, height=1).place(x=38,y=107)
  306.     Label(deleteCaseWindow, text ="*", fg = "red", font='Helvetica 9',
  307.           width=1, height=1).place(x=136,y=107)
  308.     delGAKN = Entry(deleteCaseWindow, font='Helvetica 9')
  309.     delGAKN.place(x=150, y=107)
  310.  
  311.     def getGAKNum():
  312.         global tmpDelCase
  313.         
  314.         ### Retrive the data that the user inputted in the 'Unique Name' entry variable using the .get() function from the Tkinter library
  315.         tmpDelCase = delGAKN.get()
  316.         
  317.         ### Check whether the user has provided a sufficient input to all the required fieldsif not show an error
  318.         if tmpDelCase == "":
  319.             messagebox.showerror('BSB Error', 'Error: Please fill all the required fields!')
  320.         else:
  321.             deleteCaseWindow.destroy()
  322.             delCaseDatabase()
  323.  
  324.  
  325.  
  326.     ### Create the button that calls the getValues() function each time its pressed
  327.     finalDelete = Button(deleteCaseWindow, text= "DELETE CASE", bg="#636363", fg="black"
  328.                       activebackground="#535353", font='Helvetica 8', command = getGAKNum).place(x=150, y=150)
  329.  
  330.  
  331. ### Create a button that calls the deleteData function which deletes a case from the database by 
  332. deleteCase = Button(root, text ="DELETE CASE", bg="#636363", fg="black", activebackground="#535353"
  333.                    font='Helvetica 8', command = deleteData).place(x=195, y=46.5)
  334.  
  335.  
  336. ### Create a function which renews the database in the root window with adding or deleting new cases
  337. def setListbox():
  338.     global caseLB
  339.  
  340.     ### Create a scrollbar in the listbox to make the navigation of the cases easier
  341.     my_scrollbar = Scrollbar(root, orient=HORIZONTAL)
  342.     my_scrollbar.pack(side=BOTTOM, fill=X)
  343.  
  344.     ### Create a listbox with all the cases in the root window
  345.     caseLB = Listbox(root, height=55, width=300, xscrollcommand = my_scrollbar.set)
  346.     caseLB.place(x=0, y=86) # Place it in the correct position of the root window
  347.     caseLB.pack(padx=10,pady=95,fill=BOTH, expand=True) # Adjust its size depending on the dimensions of my client's screen
  348.  
  349.     my_scrollbar.config(command=caseLB.xview)
  350.     
  351.     
  352.  
  353. def inputDatabase():
  354.     global combinedDetails
  355.     
  356.     ## Create and insert new dictionary
  357.     newDict = {"GAK NUMBER":str(tmpNumber),"NAME":str(tmpName),"CASE DETAILS":combinedDetails,"NOTES":str(tmpNotes)"JURY":str(tmpJury)"YEAR":str(tmpYear)}
  358.     try:
  359.         coll.insert_one(newDict)
  360.     except:
  361.         pass
  362.  
  363.  
  364.  
  365. def loadTrueCases():
  366.     
  367.     ### Delete all the cases in the listbox in order to fill it with only what is in the MongoDB database at the moment
  368.     caseLB.delete(0END)
  369.     
  370.     ### Call all the documents in the MongoDB database
  371.     getColl = coll.find()
  372.     
  373.     for details in getColl: # Iterate through all the documents in the MongoDB database
  374.         caseLB.insert(END, details) # Insert all the cases in the listbox
  375.  
  376.  
  377. ### Create a button that calls the loadTrueCases function which loads to the GUI all the cases (documents) that are in the database at the moment
  378. loadCase = Button(root, text ="LOAD CASE", bg="#636363", fg="black", activebackground="#535353"
  379.                    font='Helvetica 8', command = loadTrueCases).place(x=280, y=46.5)
  380.  
  381.  
  382.  
  383.  
  384. def updateCase():
  385.     ### Call all the documents in the MongoDB database
  386.     autoColl = coll.find()
  387.         
  388.     for details in autoColl: # Iterate through all the documents in the MongoDB database
  389.         
  390.         
  391.         ### Get the info required from the MongoDB database in order to be able to search for the case in the governemnt's website
  392.         updateJury = details["JURY"]
  393.         updateNumber = details["GAK NUMBER"]
  394.         updateYear = details["YEAR"]
  395.         updateName = details["NAME"]
  396.         updateDetails = details["CASE DETAILS"]
  397.         updateNotes = details["NOTES"]
  398.  
  399.  
  400.         ### Setting up the webdriver and directing the service to its directory
  401.         serv_obj=Service("C:\Drivers\chromedriver_win32\chromedriver.exe")
  402.  
  403.         driver = webdriver.Chrome(service=serv_obj)
  404.         driver.get("https://extapps.solon.gov.gr/mojwp/faces/TrackLdoPublic")
  405.         
  406.         ### Locate the elements in the website and send the user’s data
  407.         driver.find_element(By.NAME"courtOfficeOC").send_keys(str(updateJury))
  408.         
  409.         driver.find_element(By.NAME"it1").send_keys(str(updateNumber))
  410.         
  411.         driver.find_element(By.NAME"it2").send_keys(str(updateYear))
  412.         
  413.         driver.find_element(By.ID,"ldoSearch").click()
  414.  
  415.         time.sleep(10)
  416.  
  417.  
  418.         ### Get the number of rows of the table I want to scrape info from
  419.         rows = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr'))
  420.  
  421.         ### Get the number of columns of the table I want to scrape info from
  422.         columns = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td'))
  423.  
  424.  
  425.         ### Create the list that all the case's details are going to get in
  426.         preDetailsList = []
  427.  
  428.  
  429.         ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has more than 1 row
  430.         before_XPath = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr['
  431.         aftertd_XPath = ']/td['
  432.         aftertr_XPath = "]"
  433.  
  434.  
  435.         ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has 1 row
  436.         before_XPath2 = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td['
  437.         aftertr_XPath2 = "]"
  438.  
  439.  
  440.         ### Check whether the table has more than one row and accordingly scrape the information
  441.         if rows > 1:
  442.             for t_row in range(1(rows + 1)):
  443.                 for t_column in range(1(columns + 1)):
  444.                     FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
  445.                     cell_text = driver.find_element(By.XPATH,FinalXPath).text
  446.                     preDetailsList.append(str(cell_text))
  447.         else:
  448.             for t_column in range(1(columns + 1)):
  449.                 FinalXPath = before_XPath2 + str(t_column) + aftertr_XPath2
  450.                 cell_text = driver.find_element(By.XPATH,FinalXPath).text
  451.                 preDetailsList.append(str(cell_text))
  452.  
  453.         
  454.  
  455.         ### Close the browser
  456.         driver.close()
  457.         
  458.         ### Create the string that all the cases info will be present
  459.         combinedDetails = ''
  460.         
  461.         
  462.         ### Add all the list's objects
  463.         for detail in preDetailsList:
  464.             combinedDetails += ' | ' + detail
  465.  
  466.         
  467.         # newDict = {"GAK NUMBER":str(updateNumber),"NAME":str(updateName),"CASE DETAILS":combinedDetails,"NOTES":str(updateNotes)"JURY":str(updateJury)"YEAR":str(updateYear)}
  468.  
  469.         newDict = {"CASE DETAILS":combinedDetails}
  470.  
  471.         ### Check whether the old case's details are equal to the new cases details
  472.         if combinedDetails != updateDetails:
  473.             coll.update_one({'CASE DETAILS': updateDetails},{"$set":newDict}) # Update the database with the new details of the case
  474.         
  475.             
  476.         
  477.     ### Load the true cases in the GUI after the mass updating ends
  478.     loadTrueCases() 
  479.  
  480.  
  481.  
  482. ### Create a button that inputs all the current cases in the MongoDB database to the governmnet's website and updates the results
  483. updateCase = Button(root, text ="UPDATE ALL", bg="#CC0000", fg="black", activebackground="#535353"
  484.                     font='Helvetica 8', command = updateCase).place(x=357, y=46.5)
  485.  
  486.  
  487.  
  488.  
  489. def completeAutomation():
  490.     global updateFlag
  491.     updateFlag = False
  492.  
  493.     def autoSearch():
  494.         global updateFlag
  495.         
  496.         ### Call all the documents in the MongoDB database
  497.         autoColl = coll.find()
  498.         
  499.         for details in autoColl: # Iterate through all the documents in the MongoDB database
  500.         
  501.             ### Get the info required from the MongoDB database in order to be able to search for the case in the governemnt's website
  502.             autoJury = details["JURY"]
  503.             autoNumber = details["GAK NUMBER"]
  504.             autoYear = details["YEAR"]
  505.             autoName = details["NAME"]
  506.             autoDetails = details["CASE DETAILS"]
  507.             autoNotes = details["NOTES"]
  508.  
  509.  
  510.             ### Setting up the webdriver and directing the service to its directory
  511.             serv_obj=Service("C:\Drivers\chromedriver_win32\chromedriver.exe")
  512.  
  513.             driver = webdriver.Chrome(service=serv_obj)
  514.             driver.get("https://extapps.solon.gov.gr/mojwp/faces/TrackLdoPublic")
  515.             
  516.             ### Locate the elements in the website and send the user’s data
  517.             driver.find_element(By.NAME"courtOfficeOC").send_keys(str(autoJury))
  518.             
  519.             driver.find_element(By.NAME"it1").send_keys(str(autoNumber))
  520.             
  521.             driver.find_element(By.NAME"it2").send_keys(str(autoYear))
  522.             
  523.             driver.find_element(By.ID,"ldoSearch").click()
  524.  
  525.             time.sleep(10)
  526.         
  527.             ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has more than 1 row
  528.             before_XPath = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr['
  529.             aftertd_XPath = ']/td['
  530.             aftertr_XPath = "]"
  531.  
  532.  
  533.             ### Get the structure of the XPath of the table I want to scrape in the goverments website in the case it has 1 row
  534.             before_XPath2 = '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td['
  535.             aftertr_XPath2 = "]"
  536.  
  537.             ### Get the number of rows of the table I want to scrape info from
  538.             rows = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr'))
  539.  
  540.  
  541.             ### Get the number of columns of the table I want to scrape info from
  542.             columns = len (driver.find_elements(By.XPATH'//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td'))
  543.             
  544.             ### Create the list that all the case's details are going to get in
  545.             preDetailsList = []
  546.             
  547.             
  548.             ### Check whether the table has more than one row and accordingly scrape the information
  549.             if rows > 1:
  550.                 for t_row in range(1(rows + 1)):
  551.                     for t_column in range(1(columns + 1)):
  552.                         FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
  553.                         cell_text = driver.find_element(By.XPATH,FinalXPath).text
  554.                         preDetailsList.append(str(cell_text))
  555.             else:
  556.                 for t_column in range(1(columns + 1)):
  557.                     FinalXPath = before_XPath2 + str(t_column) + aftertr_XPath2
  558.                     cell_text = driver.find_element(By.XPATH,FinalXPath).text
  559.                     preDetailsList.append(str(cell_text))
  560.             
  561.             pinakiouXPath= '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td[6]'
  562.             pinakiouInfo = driver.find_element(By.XPATH, pinakiouXPath).text
  563.  
  564.             apofasisXPath= '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td[7]'
  565.             apofasisInfo = driver.find_element(By.XPATH, apofasisXPath).text
  566.             
  567.             apotelesmaXPath= '//*[@id="pc1:ldoTable::db"]/table/tbody/tr/td[2]/div/table/tbody/tr/td[8]'
  568.             apotelesmaInfo = driver.find_element(By.XPATH, apotelesmaXPath).text
  569.             
  570.             ### Close the browser
  571.             driver.close()
  572.             
  573.             ### Create the string that all the cases info will be present
  574.             combinedDetails = ''
  575.             
  576.             
  577.             ### Add all the list's objects
  578.             for detail in preDetailsList:
  579.                 combinedDetails += ' | ' + detail
  580.  
  581.             newDict = {"CASE DETAILS":combinedDetails}
  582.          
  583.             
  584.             if combinedDetails != autoDetails:
  585.                 coll.update_one({'CASE DETAILS': autoDetails},{"$set":newDict}) # Update the database with the new details of the case
  586.  
  587.         
  588.                 email_sender = '[email protected]'
  589.                 email_password = 'mtrouqobdtbqgaeq'
  590.                 email_receiver = '[email protected]'
  591.                 
  592.                 subjectString = 'Boutsioukis Solon Box | Πορεία Δικογραφίας [Αλλαγή πορείας υπόθεσης με Γ.Α.Κ. αριθμό: ' + str(autoNumber) + ']'
  593.                 
  594.                 subject = subjectString
  595.    
  596.                 bodyString = 'Άλλαξε η πορεία της υπόθεσης' + str(autoName) + ' του καταστήματος: ' + str(autoJury) + ', με Γ.Α.Κ. αριθμό: ' + str(autoNumber) + ', και Γ.Α.Κ. έτος: ' + str(autoYear) + '\n\nΟ νέος Αριθμός Πινακίου είναι: ' + str(pinakiouInfo) +'\n\nΟ νέος Αριθμός Aπόφασης/Ετος - Είδος Διατακτικού είναι: '+ str(apofasisInfo) + '\n\nΤο νέο Αποτέλεσμα Συζήτησης είναι: ' + str(apotelesmaInfo)
  597.                 
  598.                 body = bodyString
  599.                 
  600.                 em = EmailMessage()
  601.                 em['From'] = email_sender
  602.                 em['To'] = email_receiver
  603.                 em['Subject'] = subject
  604.                 em.set_content(body)
  605.  
  606.  
  607.                 context = ssl.create_default_context()
  608.  
  609.                 with smtplib.SMTP_SSL('smtp.gmail.com', 465, context=context) as smtp:
  610.                     smtp.login(email_sender, email_password)
  611.                     smtp.sendmail(email_sender, email_receiver, em.as_string())
  612.  
  613.  
  614.     ### Schedule the function autoSearch to run every 1800 seconds
  615.     schedule.every(50).seconds.do(autoSearch)
  616.  
  617.     while 1:
  618.         schedule.run_pending()
  619.         time.sleep(1)
  620.  
  621.  
  622.  
  623. checkbox = Checkbutton(root, text='Activate Automate Search', command=completeAutomation)
  624. checkbox.deselect()
  625. checkbox.place(x=457, y=46.5)
  626.  
  627.  
  628.  
  629. ### Call the nessesary functions in order for the program to run efficiently
  630. setListbox()
  631. loadTrueCases()
  632. root.mainloop()

Editor

You can edit this paste and save as new:


File Description
  • BSB
  • Paste Code
  • 30 Nov-2022
  • 26.6 Kb
You can Share it: