Advertisement
Mika_aaa

ping_window.py

Mar 12th, 2023
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.08 KB | None | 0 0
  1. import multiprocessing
  2. from tkinter import messagebox, Frame, Tk, PhotoImage, Label, Text
  3. from threading import Thread
  4. from ping3 import verbose_ping
  5.  
  6.  
  7. class NewProcessPingWindow(multiprocessing.Process):
  8.     def __init__(self, logo_raw,
  9.                  window_size: dict, url,
  10.                  packages, interval,
  11.                  timeout, ttl,
  12.                  size, set_daemon=None):
  13.         super().__init__(daemon=set_daemon)
  14.  
  15.         self.logo_raw = logo_raw
  16.  
  17.         self.url_label_shown = False
  18.         self.exit_flag = False
  19.  
  20.         self.screen_width = window_size['width']
  21.         self.screen_height = window_size['height']
  22.  
  23.         self._url = str(url) if url else 'google.com'
  24.         self._packages = int(packages) if packages else 4
  25.         self._interval = float(interval) if interval else 1
  26.         self._timeout = float(timeout) if timeout else 4
  27.         self._ttl = int(ttl) if ttl else 128
  28.         self._size = int(size) if size else 32
  29.  
  30.         self.console_max_width = 0
  31.         self.font_size = 18
  32.  
  33.     def toggle_widgets(self, mouse_btn):
  34.         self.w.unbind('<Button-3>')
  35.         self.w.unbind('<Button-1>')
  36.  
  37.         if mouse_btn == 'Button-3':
  38.             if self.main_console_frame.winfo_viewable():
  39.                 self.main_console_frame.pack_forget()
  40.                 self.w.geometry(f'{self.screen_width}x{self.screen_height}')
  41.                 self.url_label.pack(expand=True, fill='both') if self.url_label_shown else None
  42.             else:
  43.                 self.screen_width, self.screen_height = self.w.winfo_width(), self.w.winfo_height()
  44.                 self.url_label.pack_forget()
  45.                 self.w.geometry('')
  46.                 self.main_console_frame.pack(fill='both', expand=True, side='top', anchor='n')
  47.         elif mouse_btn == 'Button-1' and not self.main_console_frame.winfo_viewable():
  48.             if self.url_label_shown:
  49.                 self.url_label.pack_forget()
  50.                 self.url_label_shown = False
  51.             else:
  52.                 self.url_label.pack(expand=True, fill='both')
  53.                 self.url_label_shown = True
  54.  
  55.         self.w.bind('<Button-3>', lambda x, arg='Button-3': self.toggle_widgets(arg))
  56.         self.w.bind('<Button-1>', lambda x, arg='Button-1': self.toggle_widgets(arg))
  57.  
  58.     def on_closing(self):
  59.         if not self.exit_flag:
  60.             if messagebox.askyesno("Подумай", "Прервать Ping?"):
  61.                 if not self.exit_flag:  # Duplicate in case of opening message box before changing exit_flag
  62.                     self.exit_flag = True
  63.                     self.calculate_statistics()
  64.                     if not self.main_console_frame.winfo_viewable():
  65.                         self.toggle_widgets('Button-3')
  66.         else:
  67.             self.w.destroy()
  68.  
  69.     def calculate_statistics(self):
  70.         statistics = [f'\n\nСтатистика Ping для {self._url}:',
  71.                       f'    Пакетов: отправлено = {self.sent}, получено = {self.received}, потеряно = {self.sent - self.received}',
  72.                       f'    ({int((100 / self.sent * (self.sent - self.received)) + (0.5 if self.sent != self.received else 0))}% потерь)',
  73.                       f'Приблизительное время приема-передачи в мс:',
  74.                       f'    Минимальное = {self.min_delay if self.min_delay != 100000 else 0}мс, Максимальное = {self.max_delay}мс, Среднее = {(int((self.average_delay / self.received) + 0.5)) if self.received != 0 else 0}мс']
  75.         for _ in statistics:
  76.             if self.console['width'] < len(_):
  77.                 self.console.configure(width=len(_))
  78.             self.console.configure(state='normal')
  79.             self.console.insert('end', _ + '\n')
  80.             self.console.see('end')
  81.             self.console.configure(state='disabled')
  82.  
  83.  
  84.     def resize_font(self, event=None):
  85.         # получаем размеры окна
  86.         width = self.w.winfo_width()
  87.         height = self.w.winfo_height()
  88.         # вычисляем оптимальный размер шрифта
  89.         a = int(height / 2)
  90.         buff = len(self.url_label["text"])
  91.         b = int(width / (buff if buff >= 7 else 7))
  92.         new_font_size = min(a, b)
  93.         if new_font_size != self.font_size:
  94.             self.font_size = new_font_size
  95.             self.url_label.config(font=("Arial", self.font_size))
  96.  
  97.     def run(self):
  98.         self.w = Tk()
  99.  
  100.         self.w.config(bg='#2b2b2b')
  101.         self.w.protocol("WM_DELETE_WINDOW", self.on_closing)
  102.         self.w.title(self._url)
  103.         self.w.pack_propagate(True)
  104.         self.logo_icon = PhotoImage(data=self.logo_raw)
  105.         self.w.iconphoto(False, self.logo_icon)
  106.         self.w.minsize(width=200, height=50)
  107.         self.w.geometry(f'{self.screen_width}x{self.screen_height}')
  108.         self.w.bind('<Button-3>', lambda x, arg='Button-3': self.toggle_widgets(arg))
  109.         self.w.bind('<Button-1>', lambda x, arg='Button-1': self.toggle_widgets(arg))
  110.  
  111.         self.url_label = Label(self.w, text=self._url,
  112.                                font=f'Arial {self.font_size}', fg='#D6ECFF', activeforeground='#90CDFF',
  113.                                background='#2b2b2b', activebackground='#2b2b2b', relief='flat', bd=0)
  114.         self.url_label.bind("<Configure>", self.resize_font)
  115.  
  116.         self.main_console_frame = Frame(self.w, bg='#2b2b2b')
  117.         self.console_frame_outline = Frame(self.main_console_frame, bg='#3c3f41')
  118.         self.console_bg = Frame(self.console_frame_outline, bg='#2b2b2b')
  119.  
  120.         self.console_title_frame = Frame(self.console_bg, bg='#3c3f41')
  121.  
  122.         self.console_address_frame = Frame(self.console_title_frame, bg='#3c3f41')
  123.         self.address_l_0_0 = Label(self.console_address_frame, font='Consolas 14', bg='#3c3f41', fg='#90CDFF', text='Address:')
  124.         self.address_l_0_1 = Label(self.console_address_frame, font='Consolas 14', bg='#3c3f41', fg='#D6ECFF', text=f'{self._url}')
  125.         self.address_l_0_0.grid(row=0, column=0, sticky='e')
  126.         self.address_l_0_1.grid(row=0, column=1, sticky='w')
  127.  
  128.         self.buff_line = Frame(self.console_title_frame, bg='#2b2b2b', height=2)
  129.  
  130.         self.console_info_frame = Frame(self.console_title_frame, bg='#3c3f41')
  131.         self.info_l_0_0 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#90CDFF', text=f'Packages:')
  132.         self.info_l_0_1 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#D6ECFF', text=f'{self._packages if self._packages > 0 else "∞"}')
  133.         self.info_l_0_0.grid(row=0, column=0, sticky='e')
  134.         self.info_l_0_1.grid(row=0, column=1, sticky='w')
  135.         self.info_l_1_0 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#90CDFF', text=f'| Frequency:')
  136.         self.info_l_1_1 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#D6ECFF', text=f'{self._interval}')
  137.         self.info_l_1_0.grid(row=0, column=2, sticky='e')
  138.         self.info_l_1_1.grid(row=0, column=3, sticky='w')
  139.         self.info_l_2_0 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#90CDFF', text=f's | Timeout:')
  140.         self.info_l_2_1 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#D6ECFF', text=f'{self._timeout}')
  141.         self.info_l_2_0.grid(row=0, column=4, sticky='e')
  142.         self.info_l_2_1.grid(row=0, column=5, sticky='w')
  143.         self.info_l_3_0 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#90CDFF', text=f'bytes | TTL:')
  144.         self.info_l_3_1 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#D6ECFF', text=f'{self._ttl}')
  145.         self.info_l_3_0.grid(row=0, column=8, sticky='e')
  146.         self.info_l_3_1.grid(row=0, column=9, sticky='w')
  147.         self.info_l_4_0 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#90CDFF', text=f's | Size:')
  148.         self.info_l_4_1 = Label(self.console_info_frame, font=f'Consolas 11', bg='#3c3f41', fg='#D6ECFF', text=f'{self._size}')
  149.         self.info_l_4_0.grid(row=0, column=6, sticky='e')
  150.         self.info_l_4_1.grid(row=0, column=7, sticky='w')
  151.  
  152.         self.console_frame = Frame(self.console_bg, bg='#2b2b2b')
  153.  
  154.         self.console = Text(self.console_frame, state='disabled',
  155.                                                 bg='#2b2b2b', fg='#D6ECFF', relief='flat',
  156.                                                 font=('Consolas', 11), height=20, width=30)
  157.  
  158.         self.console_frame_outline.pack(expand=True)
  159.         self.console_bg.pack(expand=True, padx=2, pady=2)
  160.         self.console_title_frame.pack(fill='both')
  161.         self.console_address_frame.pack(fill='both', padx=5, pady=3)
  162.         self.buff_line.pack(fill='both')
  163.         self.console_info_frame.pack(side='left', padx=5, pady=6)
  164.         self.console_frame.pack(fill='both')
  165.         self.console.pack(side='left', padx=5, pady=5)
  166.  
  167.         Thread(target=self.ping, daemon=True, name='ping_thread').start()
  168.         self.w.mainloop()
  169.  
  170.     def ping(self):
  171.  
  172.         last_response = None
  173.         self.average_delay = 0
  174.         self.max_delay = 0
  175.         self.min_delay = 100000
  176.         self.sent = 0
  177.         self.received = 0
  178.         for response in verbose_ping(dest_addr=self._url,
  179.                                      count=self._packages,
  180.                                      interval=self._interval,
  181.                                      timeout=self._timeout,
  182.                                      size=self._size,
  183.                                      ttl=self._ttl):
  184.  
  185.             if self.console['width'] < len(response[1]):
  186.                 self.console.configure(width=len(response[1]))
  187.  
  188.             if not self.exit_flag:
  189.                 self.console.configure(state='normal')
  190.                 self.console.insert('end', response[1] + '\n')
  191.                 self.console.see('end')
  192.                 self.console.configure(state='disabled')
  193.             else:
  194.                 break
  195.             if response[0] != last_response:
  196.                 if not response[0]:
  197.                     self.w.config(bg='#ff0000')
  198.                     self.url_label.config(bg='#ff0000')
  199.                 elif response[0]:
  200.                     self.w.config(bg='#008000')
  201.                     self.url_label.config(bg='#008000')
  202.             if response[0]:
  203.                 self.received += 1
  204.                 self.average_delay += response[2]
  205.                 if self.max_delay < response[2]:
  206.                     self.max_delay = response[2]
  207.                 if self.min_delay > response[2]:
  208.                     self.min_delay = response[2]
  209.  
  210.             last_response = response[0]
  211.             self.sent += 1
  212.             if self.exit_flag:
  213.                 break
  214.         if not self.exit_flag:
  215.             self.exit_flag = True
  216.             self.calculate_statistics()
  217.         # print('-----------------------------')
  218.         # print(response)
  219.         # print('current thread:', current_thread())
  220.         # print('current PingObject:', self)
  221.         # print('threads active:', active_count(), enumerate())
  222.         # print('-----------------------------\n')
  223.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement