From 9232f3177845cd454ea89ac0b00e7dbf0580cbf6 Mon Sep 17 00:00:00 2001 From: pucherot Date: Sat, 24 Apr 2021 11:48:11 +0200 Subject: [PATCH] Pi.Alert v3.02 #114 - Fixed: UNIQUE constraint failed with Local MAC --- back/pialert.py | 10 +++--- config/version.conf | 4 +-- docs/INSTALL.md | 34 ++++++++++++++------- docs/VERSIONS_HISTORY.md | 6 ++++ install/pialert_install.sh | 2 +- tar/create_tar.sh | 4 +-- tar/{pialert_3.01.tar => pialert_3.02.tar} | Bin 58634240 -> 58634240 bytes tar/pialert_latest.tar | Bin 58634240 -> 58634240 bytes 8 files changed, 39 insertions(+), 21 deletions(-) rename tar/{pialert_3.01.tar => pialert_3.02.tar} (99%) diff --git a/back/pialert.py b/back/pialert.py index f9f59b28..1a1e5da7 100644 --- a/back/pialert.py +++ b/back/pialert.py @@ -374,7 +374,7 @@ def scan_network (): read_DHCP_leases () # Load current scan data - print ('\nProcesising scan results...') + print ('\nProcessing scan results...') print_log ('Save scanned devices') save_scanned_devices (arpscan_devices, cycle_interval) @@ -598,10 +598,12 @@ def save_scanned_devices (p_arpscan_devices, p_cycle_interval): # local_ip_cmd = ["ip route list default | awk {'print $7'}"] local_ip_cmd = ["ip -o route get 1 | sed 's/^.*src \\([^ ]*\\).*$/\\1/;q'"] local_ip = subprocess.Popen (local_ip_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].decode().strip() - - sql.execute ("INSERT INTO CurrentScan (cur_ScanCycle, cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) "+ - "VALUES ( ?, ?, ?, Null, 'local_MAC') ", (cycle, local_mac, local_ip) ) + # Check if local mac has been detected with other methods + sql.execute ("SELECT COUNT(*) FROM CurrentScan WHERE cur_ScanCycle = ? AND cur_MAC = ? ", (cycle, local_mac) ) + if sql.fetchone()[0] == 0 : + sql.execute ("INSERT INTO CurrentScan (cur_ScanCycle, cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) "+ + "VALUES ( ?, ?, ?, Null, 'local_MAC') ", (cycle, local_mac, local_ip) ) #------------------------------------------------------------------------------- def print_scan_stats (): diff --git a/config/version.conf b/config/version.conf index c34c55b3..95646137 100644 --- a/config/version.conf +++ b/config/version.conf @@ -1,3 +1,3 @@ -VERSION = '3.01' +VERSION = '3.02' VERSION_YEAR = '2021' -VERSION_DATE = '2021-04-22' +VERSION_DATE = '2021-04-24' diff --git a/docs/INSTALL.md b/docs/INSTALL.md index a9a72127..f0a78a41 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -93,7 +93,7 @@ Estimated time: 20' ``` or this one if have severals interfaces ``` - ip -o route get 1 | sed -n 's/.*src \([0-9.]\+\).*/\1/p' + ip -o route get 1 | sed 's/^.*src \([^ ]*\).*$/\1/;q' ``` - http://192.168.1.x/admin/ @@ -108,7 +108,7 @@ Estimated time: 20' ``` or this one if have severals interfaces ``` - ip -o route get 1 | sed -n 's/.*src \([0-9.]\+\).*/\1/p' + ip -o route get 1 | sed 's/^.*src \([^ ]*\).*$/\1/;q' ``` - Pi-hole admin portal -> Local DNS -> DNS Records -> Add new domain /IP @@ -129,27 +129,37 @@ Estimated time: 20' If you have installed Pi.hole, lighttpd and PHP are already installed and this block is not necessary -3.1 - Install lighttpd +3.1 - Install apt-utils + ``` + sudo apt-get install apt-utils -y + ``` + +3.2 - Install lighttpd ``` sudo apt-get install lighttpd -y ``` -3.2 - If Pi.Alert will be the only site available in this webserver, you can +3.3 - If Pi.Alert will be the only site available in this webserver, you can redirect the default server page to pialert subfolder ``` sudo mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old sudo ln -s ~/pialert/install/index.html /var/www/html/index.html ``` -3.3 - Install PHP +3.4 - Install PHP ``` sudo apt-get install php php-cgi php-fpm php-sqlite3 -y ``` -3.4 - Activate PHP +3.5 - Activate PHP ``` sudo lighttpd-enable-mod fastcgi-php - sudo /etc/init.d/lighttpd restart + sudo service lighttpd restart + ``` + +3.6 - Install sqlite3 + ``` + sudo apt-get install sqlite3 -y ``` @@ -161,9 +171,9 @@ block is not necessary sudo arp-scan -l ``` -4.2 - Install dnsutils utility +4.2 - Install dnsutils & net-tools utilities ``` - sudo apt-get install dnsutils -y + sudo apt-get install dnsutils net-tools -y ``` 4.3 - Test Python @@ -235,9 +245,11 @@ block is not necessary - If you want to use email reporting, configure this parameters ```ini REPORT_MAIL = True + REPORT_TO = 'user@gmail.com' + SMTP_SERVER = 'smtp.gmail.com' + SMTP_PORT = 587 SMTP_USER = 'user@gmail.com' SMTP_PASS = 'password' - REPORT_TO = 'user@gmail.com' ``` - If you want to update your Dynamic DNS, configure this parameters @@ -303,7 +315,7 @@ block is not necessary ``` or this one if have severals interfaces ``` - ip -o route get 1 | sed -n 's/.*src \([0-9.]\+\).*/\1/p' + ip -o route get 1 | sed 's/^.*src \([^ ]*\).*$/\1/;q' ``` - Pi-hole admin portal -> Local DNS -> DNS Records -> Add new domain /IP - pi.alert 192.168.1.x diff --git a/docs/VERSIONS_HISTORY.md b/docs/VERSIONS_HISTORY.md index 8dd67cb5..94c34ac5 100644 --- a/docs/VERSIONS_HISTORY.md +++ b/docs/VERSIONS_HISTORY.md @@ -14,6 +14,12 @@ | v2.50 | First public release | +## Pi.Alert v3.02 + + **PENDING UPDATE DOC** + - Fixed: UNIQUE constraint failed with Local MAC #114 + + ## Pi.Alert v3.01 **PENDING UPDATE DOC** diff --git a/install/pialert_install.sh b/install/pialert_install.sh index b2d2490b..1dc56ec9 100644 --- a/install/pialert_install.sh +++ b/install/pialert_install.sh @@ -330,7 +330,7 @@ install_lighttpd() { fi print_msg "- Restarting lighttpd..." - sudo sudo service lighttpd restart 2>&1 >> "$LOG" + sudo service lighttpd restart 2>&1 >> "$LOG" # sudo /etc/init.d/lighttpd restart 2>&1 >> "$LOG" print_msg "- Installing sqlite3..." diff --git a/tar/create_tar.sh b/tar/create_tar.sh index aecfd4fb..b0735de3 100644 --- a/tar/create_tar.sh +++ b/tar/create_tar.sh @@ -8,12 +8,10 @@ # Puche 2021 pi.alert.application@gmail.com GNU GPLv3 # ------------------------------------------------------------------------------ -PIALERT_VERSION=`awk '$1=="VERSION" { print $3 }' ../config/version.conf | tr -d \'` PIALERT_DEV_PATH=/media/WD_4TB/dev - -# ------------------------------------------------------------------------------ cd $PIALERT_DEV_PATH pwd +PIALERT_VERSION=`awk '$1=="VERSION" { print $3 }' pialert/config/version.conf | tr -d \'` # ------------------------------------------------------------------------------ ls -l pialert/tar/pialert*.tar diff --git a/tar/pialert_3.01.tar b/tar/pialert_3.02.tar similarity index 99% rename from tar/pialert_3.01.tar rename to tar/pialert_3.02.tar index c30e712e211bb397b4d5d267efe3366da20d77f6..ae163da40e4039bac0c9009397a07761e4596655 100644 GIT binary patch delta 5011 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