Skip to content

Commit

Permalink
new: github actions
Browse files Browse the repository at this point in the history
  • Loading branch information
uburuntu committed Oct 15, 2020
1 parent 2a63cd0 commit 555508a
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 33 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Build executables

on:
push:
branches: [ main ]

release:
types: [ published ]

pull_request:

jobs:
build:

runs-on: ${{ matrix.os }}

strategy:
matrix:
include:
- os: ubuntu-20.04
artifact_name: DMonitor
asset_name: DMonitorLinux
- os: windows-latest
artifact_name: DMonitor.exe
asset_name: DMonitorWin.exe
- os: macos-latest
artifact_name: DMonitor.zip
asset_name: DMonitorMacOS.zip

steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Install System Dependencies
if: startsWith(matrix.os, 'ubuntu')
run: |
pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython
- name: Install Dependencies
run: |
pip install -U pip wheel
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Build Artifact
env:
DMONITOR_STATHAT_KEY: ${{ secrets.DMONITOR_STATHAT_KEY }}
run: |
cd dmonitor/build
python make_hook.py
pyinstaller --noconsole --noconfirm --clean --onefile --name DMonitor --paths .. --icon icon.ico --runtime-hook hook.py ../main.py
- name: Zip Executable
if: startsWith(matrix.os, 'macos')
run: |
cd dmonitor/build/dist
zip -r -X DMonitor.zip DMonitor.app
rm -rf DMonitor.app
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2
with:
path: dmonitor/build/dist/${{ matrix.artifact_name }}

- name: Upload Binaries to Release
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref }}
file: dmonitor/build/dist/${{ matrix.artifact_name }}
asset_name: ${{ matrix.asset_name }}
overwrite: true
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ __pycache__/

# Distribution / packaging
.Python
# build/
build/
develop-eggs/
dist/
downloads/
Expand Down
3 changes: 3 additions & 0 deletions dmonitor/build/hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import os

os.environ['DMONITOR_STATHAT_KEY'] = ''
14 changes: 14 additions & 0 deletions dmonitor/build/make_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os
from pathlib import Path


def path(filename: str) -> Path:
return (Path(__file__).parent / filename).absolute()


hook = f'''import os
os.environ['DMONITOR_STATHAT_KEY'] = '{os.getenv('DMONITOR_STATHAT_KEY', '')}'
'''

path('hook.py').write_text(hook, encoding='utf-8')
2 changes: 1 addition & 1 deletion dmonitor/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

stathat_key = os.getenv('DMONITOR_STATHAT_KEY')

if stathat_key is None:
if not stathat_key:
raise Exception('You should set `DMONITOR_STATHAT_KEY` environment variable')

domains = ('google.com', 'yandex.ru', 'vk.com')
Expand Down
43 changes: 28 additions & 15 deletions dmonitor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,51 @@
import PySimpleGUIWx as sg

import config

from pinger import Pinger
from stathat import StatHat
from utils import Timer
from utils import Timer, CheckMyIP


def main():
updates_interval = 60.
timer = Timer(updates_interval).start()
timer_notification = Timer(30 * 60.)
timer = Timer(1 * 60.).start()
stathat = StatHat(config.stathat_key)
pinger = Pinger(stathat)
ip_checker = CheckMyIP()

if ip_checker.get_ip() is None:
return sg.popup_ok('Первый запуск программы должен быть при работающем интернете', icon=config.icon)

timer_notification_1 = Timer(30 * 60.)
timer_notification_2 = Timer(30 * 60.)

menu = ['UNUSED', ['Информация', '---', 'Закрыть']]
last_send = 'Данные еще не отправлялись'
tooltip = 'Мониторинг интернета в общежитии ГЗ'
tray = sg.SystemTray(menu=menu, tooltip=f'{tooltip}\n\n{last_send}', data_base64=config.icon)

while True:
event = tray.read(timeout=updates_interval * 1000)
sg.popup_no_wait('Мониторинг интернета запущен, выгрузка статистики начнётся через 1 минуту.\n\n'
'Это окно можно закрыть, я продолжу работать в фоновом режиме.\n\n'
'Спасибо за участие!', icon=config.icon)

if event == 'Закрыть':
break
while True:
event = tray.read(timeout=1000)

if timer.acquire():
ok = pinger.analyze()
if ok:
last_send = f'Последняя отправка данных: {time.ctime()}'
tray.update(tooltip=f'{tooltip}\n\n{last_send}')
if ip_checker.check():
ok = pinger.analyze()
if ok:
last_send = f'Последняя отправка данных: {time.ctime()}'
tray.update(tooltip=f'{tooltip}\n\n{last_send}')
else:
if timer_notification_1.acquire():
sg.popup_no_wait(f'Проблема с доступом к одному из сайтов: {", ".join(config.domains)}', icon=config.icon)
else:
if timer_notification.acquire():
sg.popup_no_wait(f'Проблема с доступом к одному из сайтов: {", ".join(config.domains)}', icon=config.icon)
if timer_notification_2.acquire():
sg.popup_no_wait('Кажется, вы подключены не к сети Главного здания.\n\n'
'Выгрузка статистики приостановлена до переподключения к ней.', icon=config.icon)

if event == 'Закрыть':
break

if event == 'Информация':
sg.popup_no_wait(f'{config.text_about}\n\n{last_send}', icon=config.icon)
Expand Down
10 changes: 4 additions & 6 deletions dmonitor/pinger.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import json
import time
from pathlib import Path
from typing import Tuple

import ping3

import config
from stathat import StatHat
import ping3
from utils import project_path


class Pinger:
def __init__(self, stathat: StatHat):
self.stathat = stathat
self.data = {}
self.data_file = Path.home() / Path('.dmonitor/data.json')

self.data_file.parent.mkdir(parents=True, exist_ok=True)
self.data_file.touch()
self.data_file = project_path('data.json')
self.load()

def load(self):
Expand Down
58 changes: 58 additions & 0 deletions dmonitor/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,55 @@
import ipaddress
import time
from pathlib import Path
from typing import Optional

import requests


class CheckMyIP:
ip_start = '85.89.126.0'
ip_end = '85.89.127.255'

def __init__(self):
self.session = requests.Session()
self.ip_file = project_path('ip.txt')

def extract_ip(self) -> Optional[ipaddress.IPv4Address]:
return self.parse_ip(self.ip_file.read_text(encoding='utf-8'))

def request_ip(self) -> Optional[ipaddress.IPv4Address]:
try:
response = self.session.get('https://checkip.amazonaws.com')
response.raise_for_status()
except Exception:
return None

ip = self.parse_ip(response.text.strip())
if ip is not None:
self.ip_file.write_text(str(ip), encoding='utf-8')
return ip

@staticmethod
def parse_ip(ip: str) -> Optional[ipaddress.IPv4Address]:
try:
ip = ipaddress.ip_address(ip)
except ValueError:
return None
return ip

def get_ip(self) -> Optional[ipaddress.IPv4Address]:
ip = self.request_ip()
if ip is None:
ip = self.extract_ip()
if ip is None:
return None
return ip

def check(self) -> bool:
ip = self.get_ip()
if ip is None:
return False
return ipaddress.ip_address(self.ip_start) <= ip <= ipaddress.ip_address(self.ip_end)


class Timer:
Expand All @@ -16,3 +67,10 @@ def acquire(self):
return False
self.last = curr_ts
return True


def project_path(name: str) -> Path:
file = Path.home() / Path(f'.dmonitor/{name}')
file.parent.mkdir(parents=True, exist_ok=True)
file.touch()
return file
13 changes: 7 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# dmonitor
# DMonitor

Программа для мониторинга интернета в Главном здании МГУ.
#### Программа для мониторинга интернета в Главном здании МГУ

# Build
> ![](https://i.imgur.com/8fSJOVs.jpg)
```
pyinstaller --noconsole -y --clean --onefile --name DMonitor main.py
```
#### Графики

https://www.stathat.com/cards/YSY4cWqWLV44
> ![](https://i.imgur.com/6iNytqJ.jpg)
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ping3==2.6
PySimpleGUIQt==0.17
wxPython==4.1
requests==2.24
ping3>=2.6
PySimpleGUIWx>=0.17
wxPython>=4.1
requests>=2.24

0 comments on commit 555508a

Please sign in to comment.