Skip to content

Instantly share code, notes, and snippets.

@DanielBorgesOliveira
Last active May 27, 2024 16:58
Show Gist options
  • Save DanielBorgesOliveira/d3e578e2b677245cec550e965eae1755 to your computer and use it in GitHub Desktop.
Save DanielBorgesOliveira/d3e578e2b677245cec550e965eae1755 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
import requests
class telegram():
def __init__(
self,
TelegramToken,
TelegramChatID,
):
self.TelegramToken = TelegramToken
self.TelegramChatID = TelegramChatID
def send_message(self, text):
files = {
'chat_id': (None, self.TelegramChatID),
'text': text,
}
response = requests.get("https://api.telegram.org/bot"+self.TelegramToken+"/sendMessage?chat_id="+self.TelegramChatID+"&text="+text, files=files)
return response
def send_file(self, FileName, FilePath):
files = {
'chat_id': (None, self.TelegramChatID),
'document': (FileName, open(FilePath, 'rb')),
}
response = requests.post("https://api.telegram.org/bot"+self.TelegramToken+"/sendDocument", files=files)
return response
def send_video(self, FileName, FilePath):
files = {
'chat_id': (None, self.TelegramChatID),
'video': (FileName, open(FilePath, 'rb')),
}
response = requests.post("https://api.telegram.org/bot"+self.TelegramToken+"/sendVideo", files=files)
return response
#!/usr/bin/python3
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import datetime
from subprocess import Popen,DEVNULL
# https://realpython.com/python-logging/
import sys
sys.path.append("/root/watchdog/")
from watchdog_logging import *
import telegram
class MyHandler(FileSystemEventHandler):
def __init__(
self,
logger,
telegram,
):
self.AlreadySended = []
self.logger = logger
self.telegram = telegram
def on_modified(self, event):
self.logger.error(f"File modified: {event.src_path}")
def on_created(self, event):
self.logger.error(f"File created: {event.src_path}")
if '.mp4' in event.src_path and \
not event.src_path in self.AlreadySended and \
not '.incomplete' in event.src_path: : # This avoid send file than once.
# Waits until the zm finish the generation of the file.
while True:
if Popen(['/usr/bin/lsof', event.src_path], stdout=DEVNULL, stderr=DEVNULL).wait() == 0:
time.sleep(2)
self.logger.error(f'File {event.src_path} is still opened')
continue
else:
break
self.logger.error(f'File {event.src_path} copy has now finished')
# Send telegram message about the event
#Text = f'event type: {event.event_type} path : {event.src_path}'
#self.telegram.send_message(Tex)
# Send the file via telegram
self.logger.error(f'Sending file via telegram. Group: {self.telegram.TelegramChatID}')
Time = datetime.datetime.now()
FileName='Video_'+str(Time.day)+"-"+str(Time.month)+\
"-"+str(Time.year)+"_"+str(Time.hour)+"-"+\
str(Time.minute)+"-"+str(Time.second)+".mp4"
# Send file to telegram
attempts=0
while attempts < 10:
try:
self.telegram.send_video(FileName, event.src_path)
self.logger.error('File sended')
self.AlreadySended.append(event.src_path)
break
except:
attempts += 1
self.logger.error('Error trying send file.')
def on_deleted(self, event):
self.logger.error(f"File deleted: {event.src_path}")
def on_moved(self, event):
self.logger.error(f"File moved: {event.src_path} to {event.dest_path}")
path = '/media/pd/zoneminder/events/2/'
if __name__ == "__main__":
tg = telegram.telegram(
TelegramToken = "< Your bot token here>",
TelegramChatID = '< Your chat ID here >')
event_handler = MyHandler(
logger = logger,
telegram = tg)
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(60)
except KeyboardInterrupt:
observer.stop()
observer.join()
#!/usr/bin/python3
# https://realpython.com/python-logging/
import logging
from logging.handlers import RotatingFileHandler
# Create a custom logger
logger = logging.getLogger(__name__)
# Create handlers
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.NOTSET)
f_handler = logging.FileHandler('/tmp/watchdog_zoneminder.log')
f_handler.setLevel(logging.DEBUG)
# Create formatters and add it to handlers
c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%m/%d/%Y %I:%M:%S')
c_handler.setFormatter(c_format)
f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%m/%d/%Y %I:%M:%S')
f_handler.setFormatter(f_format)
# Rotate the log file.
rotating_handler = RotatingFileHandler('/tmp/watchdog_zoneminder.log', maxBytes=2000, backupCount=5)
logger.addHandler(rotating_handler)
# Add handlers to the logger
logger.addHandler(c_handler)
logger.addHandler(f_handler)
@civita
Copy link

civita commented Mar 28, 2021

Thanks for sharing this useful script! Did you faced high cpu usage issue regrading watchdog monitoring multiple folders under zoneminder/events? My cpu usage is about 100% with 3 cameras to monitor.

@DanielBorgesOliveira
Copy link
Author

Hi @civita.

Thank you for the feedback.
I have a small setup with one camera and one Raspberry Pi 3.
I did not face high CPU problem.
Try to instantiate 3 separated processes.
Maybe this can help.

Best regards.

@civita
Copy link

civita commented Mar 29, 2021

Hi @DanielBorgesOliveira,
Thanks for the input! I dug into the issue and notice that there are named pipes dbgpipe.log in the events/monitor# folders and somehow caused watchdog high CPU. Since this commit, the named pipes have been located in another folder, and won't cause this issue. I am running zoneminder on FreeBSD (the latest version is 1.34.21) and would waiting for the package update. ;)

Capture

@DanielBorgesOliveira
Copy link
Author

I do not how often the FreeBSD team updates the packages, but if they are so slow as the Debian team you will wait very long. Lol.
Maybe you can compile Zoneminder from the source to solve this.
Thank you for sharing the information.

@GuyKroizman
Copy link

Very cool. Thanks for that. I was able to make it work.
Only maybe worth mentioning for others that the script is expecting a mp4 file to be created upon event and that happens if you have setup storage to use some "Video writer" which was not the case initially for me. (it stored jpegs so once I changed it everything start working)

@GuyKroizman
Copy link

GuyKroizman commented Sep 14, 2021

I was getting to messages in telegram I thing the mechanism used to detect that the mp4 file is ready and complete - is not working properly.
But I see that new mp4 files that are created are created with the 'incomplete' prefix in the filename.
so I used that to only send the file when it is complete.
you can see the change in my gist:
https://gist.github.com/GuyKroizman/7de7e899db4ddaccf9f819d7b2131db7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment