diff --git a/requirements.txt b/requirements.txt index 535a416..06eb420 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ suntime==1.3.2 inotify requests matplotlib +pillow diff --git a/scripts/utils/helpers.py b/scripts/utils/helpers.py index 864f015..ae68cf3 100644 --- a/scripts/utils/helpers.py +++ b/scripts/utils/helpers.py @@ -12,6 +12,22 @@ _settings = None DB_PATH = os.path.expanduser('~/BirdNET-Pi/scripts/birds.db') ANALYZING_NOW = os.path.expanduser('~/BirdSongs/StreamData/analyzing_now.txt') +FONT_DIR = os.path.expanduser('~/BirdNET-Pi/homepage/static') + + +def get_font(): + conf = get_settings() + if conf['DATABASE_LANG'] == 'ar': + ret = {'font.family': 'Noto Sans Arabic', 'path': os.path.join(FONT_DIR, 'NotoSansArabic-Regular.ttf')} + elif conf['DATABASE_LANG'] in ['ja', 'zh']: + ret = {'font.family': 'Noto Sans JP', 'path': os.path.join(FONT_DIR, 'NotoSansJP-Regular.ttf')} + elif conf['DATABASE_LANG'] == 'ko': + ret = {'font.family': 'Noto Sans KR', 'path': os.path.join(FONT_DIR, 'NotoSansKR-Regular.ttf')} + elif conf['DATABASE_LANG'] == 'th': + ret = {'font.family': 'Noto Sans Thai', 'path': os.path.join(FONT_DIR, 'NotoSansThai-Regular.ttf')} + else: + ret = {'font.family': 'Roboto Flex', 'path': os.path.join(FONT_DIR, 'RobotoFlex-Regular.ttf')} + return ret class PHPConfigParser(ConfigParser): diff --git a/scripts/utils/reporting.py b/scripts/utils/reporting.py index ac0e009..5763d39 100644 --- a/scripts/utils/reporting.py +++ b/scripts/utils/reporting.py @@ -5,23 +5,18 @@ import logging import os import sqlite3 import subprocess +import tempfile from time import sleep import requests +from PIL import Image, ImageDraw, ImageFont -from .helpers import get_settings, ParseFileName, Detection, DB_PATH +from .helpers import get_settings, ParseFileName, Detection, get_font, DB_PATH from .notifications import sendAppriseNotifications log = logging.getLogger(__name__) -def get_safe_title(title): - result = subprocess.run(['iconv', '-f', 'utf8', '-t', 'ascii//TRANSLIT'], - check=True, input=title.encode('utf-8'), capture_output=True) - ret = result.stdout.decode('utf-8') - return ret - - def extract(in_file, out_file, start, stop): result = subprocess.run(['sox', '-V1', f'{in_file}', f'{out_file}', 'trim', f'={start}', f'={stop}'], check=True, capture_output=True) @@ -50,15 +45,29 @@ def extract_safe(in_file, out_file, start, stop): def spectrogram(in_file, title, comment, raw=False): + fd, tmp_file = tempfile.mkstemp(suffix='.png') + os.close(fd) args = ['sox', '-V1', f'{in_file}', '-n', 'remix', '1', 'rate', '24k', 'spectrogram', - '-t', f'{get_safe_title(title)}', '-c', f'{comment}', '-o', f'{in_file}.png'] + '-t', '', '-c', '', '-o', tmp_file] args += ['-r'] if raw else [] result = subprocess.run(args, check=True, capture_output=True) ret = result.stdout.decode('utf-8') err = result.stderr.decode('utf-8') if err: raise RuntimeError(f'{ret}:\n {err}') - return ret + img = Image.open(tmp_file) + height = img.size[1] + width = img.size[0] + draw = ImageDraw.Draw(img) + title_font = ImageFont.truetype(get_font()['path'], 13) + _, _, w, _ = draw.textbbox((0, 0), title, font=title_font) + draw.text(((width-w)/2, 6), title, fill="white", font=title_font) + + comment_font = ImageFont.truetype(get_font()['path'], 11) + _, _, _, h = draw.textbbox((0, 0), comment, font=comment_font) + draw.text((1, height - (h + 1)), comment, fill="white", font=comment_font) + img.save(f'{in_file}.png') + os.remove(tmp_file) def extract_detection(file: ParseFileName, detection: Detection):