0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ろうとるがPythonを扱う、、(その12:回線速度checkプログラム )

Posted at

Python+tkinterで回線速度チェックプログラム

件名の内容をつくることがあった時のメモ。

ネットワーク回線Download速度測定

よく見かけるサイトのまねごとである。ここでは、1Mbyte、5Mbyte、10Mbyte、30Mbyte、100Mbyteのファイルを無料のStorageサービスサイトに格納し、そのサイトからのダウンロー時間や速度を測定・表示・ファイル化(CSV)する。

準備

ファイル作成

Linuxコマンドddにより作成。下記は、100Mbyteのファイル作成。

dd if=/dev/zero of=100Mbyte bs=1024 count=100*1024

URL

無料のストレージサービスサイトでは、URLが変更されることがあるようだ(セキュリティ対策と思われる)。そこで、ダウンロードするファイルのURLが変更されてても対応できるよう、別ファイル(url.txt)にURLを格納することにした。

https://himitsu.jp/9114/xxx/contents/1Mbyte
https://himitsu.jp/9123/xxx/contents/5Mbyte
https://himitsu.jp/9345/xxx/contents/10Mbyte
https://himitsu.jp/9534/xxx/contents/30Mbyte
https://himitsu.jp/980a/xxx/contents/100Mbyte

ソースコード

まずは部分的な説明。

import

import logging
import logging.handlers
from datetime import datetime
import time
import urllib.request
import tkinter
from tkinter import *
import tkinter.ttk as ttk

ログ、時間、URL、tkinterなどのライブラリインポート。

定義・リスト

w_width = 450
w_height = 400
speed_list = [1, 5, 10, 30, 100]
file_list = ['1Mbyte', '5Mbyte', '10Mbyte', '30Mbyte', '100Mbyte']

画面サイズ、速度定義のリスト。

URL取得

        f = open('url.txt', 'r')
        url_list = f.readlines()
        f.close()

1行に1つのURLが記載されたファイルから内容を読み込み、リスト化。

表示部分作成

            frm1 = ttk.Frame(frm, width=w_width, height=w_height)
            frm1.Btn1 = ttk.Button(frm1, text=file_list[0], style='W.TButton', command=lambda:ok_clk(1))
            frm1.Btn1.grid(row = 0, column = 0)
            frm1.Btn2 = ttk.Button(frm1, text=file_list[1], style='W.TButton', command=lambda:ok_clk(2))
            frm1.Btn2.grid(row = 0, column = 1)
            frm1.Btn3 = ttk.Button(frm1, text=file_list[2], style='W.TButton', command=lambda:ok_clk(3))
            frm1.Btn3.grid(row = 0, column = 2)
            frm1.Btn4 = ttk.Button(frm1, text=file_list[3], style='W.TButton', command=lambda:ok_clk(4))
            frm1.Btn4.grid(row = 0, column = 3)
            frm1.Btn5 = ttk.Button(frm1, text=file_list[4], style='W.TButton', command=lambda:ok_clk(5))
            frm1.Btn5.grid(row = 0, column = 4)

            frm2 = ttk.Frame(frm, width=w_width, height=w_height)
            frm2.label = ttk.Label(frm2, text = 'Size(Mbyte), Time(ms), Speed(Kbps)')
            frm2.label.grid(row = 0, column = 0)
            frm2.dummy = ttk.Label(frm2, text = '                                                    		')
            frm2.dummy.grid(row = 0, column = 1)

            frm3 = ttk.Frame(frm, width=w_width, height=w_height)
            frm3.prt = Text(frm3, font=("Courier New", 11), width=120, height=33)
            frm3.ysc = tkinter.Scrollbar(frm3, orient=tkinter.VERTICAL, command=frm3.prt.yview)
            frm3.ysc.pack(side=tkinter.RIGHT, fill="y")
            frm3.prt["yscrollcommand"] = frm3.ysc.set
            frm3.prt.config(state='disabled')
            frm3.prt.pack()

            frm1.pack()
            frm2.pack()
            frm3.pack()

.....

        note = ttk.Notebook(self)
        note.pack()
        note0 = ttk.Frame(note, width=w_width, height=w_height)
        note.add(note0, text=" Click Download File Size  ")
        cr_tab(note0)

タブ化、タブ内のフレーム化(3種類:ボタン、テキスト、結果表示部分)の実施。このあたりは、従来からの方式(例えば、「ろうとるがPythonを扱う、、(その5:tkinterでタブ)」を踏襲。

タブは必須ではなかったが、その後のプログラム拡張に備えて、あえてタブ化した。

ボタンクリック時処理

            def ok_clk(arg):
                start_time = time.perf_counter_ns()
                urllib.request.urlretrieve(url_list[arg-1], file_list[arg-1])
                end_time = time.perf_counter_ns()
                elapsed_time = (end_time - start_time) / 1000000
                speed = speed_list[arg-1]*8*1024*1024/elapsed_time
                output = str(speed_list[arg-1]) + ', ' + str(elapsed_time) + ', ' + str(speed) + ','
                log.debug(output)                   # output to log file
                output = output + '\n'
                frm3.prt.config(state='normal')     # editable
                frm3.prt.insert(END, output)
                frm3.prt.config(state='disabled')   # not editable
                frm3.prt.see('end')

URLライブラリを使ってファイルをダウンロード、ダウンロード時間の計測および速度の計算、結果をログファイル(CSV)に格納および表示。

ログファイル(csv)関連

        log = logging.getLogger(__name__)
        log.setLevel(logging.DEBUG)
        fh = logging.FileHandler('{:Log-%Y%m%d-%H%M%S}.csv'.format(datetime.now()))
        log.addHandler(fh)
        header = 'Size(Mbyte), Time(ms), Speed(Kbps),'
        log.debug(header)

ログおよびログファイル名の定義。

メニュー

        def log_tgl():
            tgl.set(not tgl.get())
            if tgl.get():
                log.setLevel(logging.DEBUG)
                fh = logging.FileHandler('{:Log-%Y%m%d-%H%M%S}.csv'.format(datetime.now()))
                log.addHandler(fh)
                header = 'Size(Mbyte), Time(ms), Speed(Kbps),'
                log.debug(header)
            else:
                log.removeHandler(log.handlers[0])
                log.setLevel(logging.INFO)

.....

        menubar = Menu(self)
        filemenu = Menu(menubar, tearoff=0)
        menubar.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Exit", command=self.quit)
        tgl = BooleanVar(value = TRUE)
        filemenu.add_checkbutton(label="Disable Log", command=log_tgl)
        master.config(menu=menubar)

ログの無効化および有効化メニューの定義。

全体

import logging
import logging.handlers
from datetime import datetime
import time
import urllib.request
import tkinter
from tkinter import *
import tkinter.ttk as ttk

w_width = 450
w_height = 400

speed_list = [1, 5, 10, 30, 100]
file_list = ['1Mbyte', '5Mbyte', '10Mbyte', '30Mbyte', '100Mbyte']

class NetworkCheck(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.create_widgets()
        self.pack()

    def create_widgets(self):
        def cr_tab(frm):
            def ok_clk(arg):
                start_time = time.perf_counter_ns()
                urllib.request.urlretrieve(url_list[arg-1], file_list[arg-1])
                end_time = time.perf_counter_ns()
                elapsed_time = (end_time - start_time) / 1000000
                speed = speed_list[arg-1]*8*1024*1024/elapsed_time
                output = str(speed_list[arg-1]) + ', ' + str(elapsed_time) + ', ' + str(speed) + ','
                log.debug(output)                   # output to log file
                output = output + '\n'
                frm3.prt.config(state='normal')     # editable
                frm3.prt.insert(END, output)
                frm3.prt.config(state='disabled')   # not editable
                frm3.prt.see('end')
            ## End of ok_clk()
        
        ## Start of cr_tab()
            frm1 = ttk.Frame(frm, width=w_width, height=w_height)
            frm1.Btn1 = ttk.Button(frm1, text=file_list[0], style='W.TButton', command=lambda:ok_clk(1))
            frm1.Btn1.grid(row = 0, column = 0)
            frm1.Btn2 = ttk.Button(frm1, text=file_list[1], style='W.TButton', command=lambda:ok_clk(2))
            frm1.Btn2.grid(row = 0, column = 1)
            frm1.Btn3 = ttk.Button(frm1, text=file_list[2], style='W.TButton', command=lambda:ok_clk(3))
            frm1.Btn3.grid(row = 0, column = 2)
            frm1.Btn4 = ttk.Button(frm1, text=file_list[3], style='W.TButton', command=lambda:ok_clk(4))
            frm1.Btn4.grid(row = 0, column = 3)
            frm1.Btn5 = ttk.Button(frm1, text=file_list[4], style='W.TButton', command=lambda:ok_clk(5))
            frm1.Btn5.grid(row = 0, column = 4)

            frm2 = ttk.Frame(frm, width=w_width, height=w_height)
            frm2.label = ttk.Label(frm2, text = 'Size(Mbyte), Time(ms), Speed(Kbps)')
            frm2.label.grid(row = 0, column = 0)
            frm2.dummy = ttk.Label(frm2, text = '                                                    		')
            frm2.dummy.grid(row = 0, column = 1)

            frm3 = ttk.Frame(frm, width=w_width, height=w_height)
            frm3.prt = Text(frm3, font=("Courier New", 11), width=120, height=33)
            frm3.ysc = tkinter.Scrollbar(frm3, orient=tkinter.VERTICAL, command=frm3.prt.yview)
            frm3.ysc.pack(side=tkinter.RIGHT, fill="y")
            frm3.prt["yscrollcommand"] = frm3.ysc.set
            frm3.prt.config(state='disabled')
            frm3.prt.pack()

            frm1.pack()
            frm2.pack()
            frm3.pack()
        ## End of cr_tab()

        def log_tgl():
            tgl.set(not tgl.get())
            if tgl.get():
                log.setLevel(logging.DEBUG)
                fh = logging.FileHandler('{:Log-%Y%m%d-%H%M%S}.csv'.format(datetime.now()))
                log.addHandler(fh)
                header = 'Size(Mbyte), Time(ms), Speed(Kbps),'
                log.debug(header)
            else:
                log.removeHandler(log.handlers[0])
                log.setLevel(logging.INFO)
            ## End of log_tgl()

        ## Start of create_widgets()
        # Log
        log = logging.getLogger(__name__)
        log.setLevel(logging.DEBUG)
        fh = logging.FileHandler('{:Log-%Y%m%d-%H%M%S}.csv'.format(datetime.now()))
        log.addHandler(fh)
        header = 'Size(Mbyte), Time(ms), Speed(Kbps),'
        log.debug(header)
        # Menu
        menubar = Menu(self)
        filemenu = Menu(menubar, tearoff=0)
        menubar.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Exit", command=self.quit)
        tgl = BooleanVar(value = TRUE)
        filemenu.add_checkbutton(label="Disable Log", command=log_tgl)
        master.config(menu=menubar)
        # Tab
        note = ttk.Notebook(self)
        note.pack()
        note0 = ttk.Frame(note, width=w_width, height=w_height)
        note.add(note0, text=" Click Download File Size  ")
        cr_tab(note0)
        # Get URL
        f = open('url.txt', 'r')
        url_list = f.readlines()
        #for i in url_list:
        #    print(i)
        f.close()
    ## End of createwidgets()
## End of NetworkCheck()

if __name__ == '__main__':
    master = Tk()
    master.title("Speed Test v0.95b")
    master.geometry("450x400")
    # Call main part
    NetworkCheck(master)
    master.mainloop()

正直、python&tkinter的には、あまり美しいとは言えないプログラムである。

動作

下記のようになる。
スクリーンショット 2023-07-03 19.34.06.png

EOF

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?