Repository: dynobo/normcap (language: python)

Issue:
NormCap doesn't work with notification=false in Ubuntu
When `notification=false` in `~/.config/normcap/settings.conf`, then the OCR doesn't work.

Using Ubuntu 21.04 and installed NormCap with `sudo apt install tesseract-ocr tesseract-ocr-eng tesseract-ocr-deu tesseract-ocr-rus libtesseract-dev libleptonica-dev python3-dev` and `pip install normcap`.

This should help:
```
$ normcap -V
19:48:55 - INFO    - normcap.app            - L:41  - Start NormCap v0.2.6
19:48:55 - DEBUG   - normcap.app            - L:42  - CLI command: /home/sojusnik/.local/bin/normcap -V
19:48:55 - DEBUG   - normcap.app            - L:43  - QT LibraryPaths: ['/home/sojusnik/.local/lib/python3.9/site-packages/PySide2/Qt/plugins']
QSslSocket:  OpenSSL 1.1.1g  21 Apr 2020 True
19:48:55 - INFO    - normcap.utils          - L:152 - Copy 0 traineddata files to config directory
19:48:55 - DEBUG   - normcap.app            - L:65  - System info:
{  'config_directory': PosixPath('/home/sojusnik/.config/normcap'),
   'desktop_environment': <DesktopEnvironment.GNOME: 1>,
   'display_manager': <DisplayManager.X11: 2>,
   'is_briefcase_package': False,
   'normcap_version': '0.2.6',
   'platform': 'linux',
   'pyside2_version': '5.15.2',
   'qt_version': '5.15.2',
   'screens': {  0: ScreenInfo(is_primary=True, device_pixel_ratio=1.0, geometry=Rect(left=0, top=0, right=1920, bottom=1080), index=0)},
   'tessdata_path': '/usr/share/tesseract-ocr/4.00/tessdata/',
   'tesseract_languages': ['deu', 'eng', 'osd', 'rus'],
   'tesseract_version': '4.1.1'}
19:48:55 - DEBUG   - normcap.base_window    - L:49  - Create window for screen 0
19:48:55 - DEBUG   - normcap.base_window    - L:248 - Set window for screen 0 to fullscreen
19:48:55 - DEBUG   - normcap.system_tray    - L:21  - Set up tray icon
19:48:56 - DEBUG   - normcap.update_check   - L:67  - Search for new version on https://pypi.org/pypi/normcap/json
19:48:56 - DEBUG   - normcap.downloader     - L:32  - Download https://pypi.org/pypi/normcap/json
19:48:56 - DEBUG   - normcap.update_check   - L:38  - Newest version: 0.2.6 (installed: 0.2.6)
19:48:59 - DEBUG   - normcap.main_window    - L:179 - Hide 1 window(s)
19:48:59 - INFO    - normcap.main_window    - L:272 - Take screenshot of position (620, 411, 1207, 543)
19:48:59 - DEBUG   - normcap.screengrab     - L:32  - Grab screen: ScreenInfo(is_primary=True, device_pixel_ratio=1.0, geometry=Rect(left=0, top=0, right=1920, bottom=1080), index=0)
19:48:59 - DEBUG   - normcap.screengrab     - L:73  - Use capture method: QT by screen
19:48:59 - DEBUG   - normcap.utils          - L:32  - Store debug image in: /tmp/normcap/2021-09-12_19-48-59_215270_raw_qt.png
19:48:59 - DEBUG   - normcap.screengrab     - L:106 - Screen scale factor: 1.0
19:48:59 - DEBUG   - normcap.screengrab     - L:107 - Image devicePixelRatio: 1.0
19:48:59 - DEBUG   - normcap.screengrab     - L:110 - Image crop box rect: (620, 411, 587, 132)
19:48:59 - DEBUG   - normcap.utils          - L:32  - Store debug image in: /tmp/normcap/2021-09-12_19-48-59_379823_cropped.png
19:48:59 - DEBUG   - normcap.main_window    - L:281 - Prepare image for OCR
19:48:59 - INFO    - normcap.enhance        - L:17  - Apply enhancements to image
19:48:59 - DEBUG   - normcap.enhance        - L:92  - Resize screenshot by factor 3.2
19:48:59 - DEBUG   - normcap.utils          - L:32  - Store debug image in: /tmp/normcap/2021-09-12_19-48-59_385251_enlarged.png
19:48:59 - DEBUG   - normcap.utils          - L:32  - Store debug image in: /tmp/normcap/2021-09-12_19-48-59_437822_padded.png
19:48:59 - DEBUG   - normcap.main_window    - L:290 - Perform OCR
19:48:59 - DEBUG   - normcap.ocr            - L:62  - Init tesseract with args: {'path': '/usr/share/tesseract-ocr/4.00/tessdata/', 'lang': 'eng', 'oem': 1, 'psm': 1}
19:49:00 - INFO    - normcap.ocr            - L:85  - PSM Mode: 1, OSM Mode: 1, Mean Conf: 70.65
19:49:00 - INFO    - normcap.main_window    - L:295 - Raw text from OCR:
wee voewws ed ee —s Me ere Lp ee ew ee /plugins' ] 5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True :48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf :48:55 - DEBUG - normcap.app - L:65 - System info: 'config_directory': PosixPath('/home/sojusnik/.config/normcap'), 'desktop_environment': <DesktopEnvironment.GNOME: 1>, 'display_manager': <DisplayManager.X11: 2>, 'is_briefcase_package': False,
19:49:00 - DEBUG   - normcap.main_window    - L:296 - Result from OCR:
best_magic: 
image: <PySide2.QtGui.QImage(QSize(2038, 582),format=QImage::Format_RGB32,depth=32,devicePixelRatio=1,bytesPerLine=8152,sizeInBytes=4744464) at 0x7f05b7fbe500>
image_area: 1186116
image_size: (2038, 582)
lines: wee voewws ed ee —s Me ere Lp ee ew ee /plugins' ] 5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True :48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf
:48:55 - DEBUG - normcap.app - L:65 - System info:
'config_directory': PosixPath('/home/sojusnik/.config/normcap'),
'desktop_environment': <DesktopEnvironment.GNOME: 1>,
'display_manager': <DisplayManager.X11: 2>,
'is_briefcase_package': False,
mean_conf: 71.96296296296296
mode: 1
num_blocks: 3
num_lines: 4
num_pars: 3
psm_opt: 1
rect: Rect(left=620, top=411, right=1207, bottom=543)
scale_factor: 1.0
scores: {}
screen: ScreenInfo(is_primary=True, device_pixel_ratio=1.0, geometry=Rect(left=0, top=0, right=1920, bottom=1080), index=0)
text: wee voewws ed ee —s Me ere Lp ee ew ee /plugins' ] 5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True :48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf :48:55 - DEBUG - normcap.app - L:65 - System info: 'config_directory': PosixPath('/home/sojusnik/.config/normcap'), 'desktop_environment': <DesktopEnvironment.GNOME: 1>, 'display_manager': <DisplayManager.X11: 2>, 'is_briefcase_package': False,
transformed: 
words: 
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:1  | left:108  | top:80   | width:100  | height:7    | conf:0  | text:wee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:2  | left:275  | top:68   | width:113  | height:28   | conf:7  | text:voewws
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:3  | left:576  | top:68   | width:62   | height:29   | conf:2  | text:ed
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:4  | left:639  | top:80   | width:59   | height:13   | conf:19 | text:ee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:5  | left:1062 | top:80   | width:36   | height:7    | conf:22 | text:—s
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:6  | left:1238 | top:80   | width:234  | height:16   | conf:40 | text:Me
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:7  | left:1486 | top:80   | width:105  | height:7    | conf:44 | text:ere
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:8  | left:1624 | top:80   | width:53   | height:13   | conf:45 | text:Lp
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:9  | left:1688 | top:80   | width:101  | height:13   | conf:41 | text:ee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:10 | left:1800 | top:80   | width:43   | height:7    | conf:52 | text:ew
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:11 | left:1860 | top:80   | width:49   | height:13   | conf:43 | text:ee
level:5  | page_num:1  | block_num:2  | par_num:1  | line_num:1  | word_num:1  | left:80   | top:105  | width:214  | height:40   | conf:83 | text:/plugins'
level:5  | page_num:1  | block_num:2  | par_num:1  | line_num:1  | word_num:2  | left:264  | top:101  | width:30   | height:58   | conf:54 | text:]
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:1  | left:80   | top:155  | width:189  | height:34   | conf:48 | text:5lSocket:
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:2  | left:319  | top:159  | width:158  | height:37   | conf:92 | text:OpenSSL
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:3  | left:502  | top:159  | width:132  | height:37   | conf:88 | text:1.1.1g
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:4  | left:680  | top:159  | width:43   | height:30   | conf:95 | text:21
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:5  | left:745  | top:159  | width:67   | height:37   | conf:95 | text:Apr
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:6  | left:837  | top:159  | width:88   | height:30   | conf:96 | text:2020
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:7  | left:947  | top:159  | width:90   | height:30   | conf:96 | text:True
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:1  | left:80   | top:210  | width:128  | height:30   | conf:67 | text::48:55
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:2  | left:235  | top:226  | width:15   | height:5    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:3  | left:278  | top:210  | width:88   | height:31   | conf:96 | text:INFO
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:4  | left:459  | top:226  | width:14   | height:5    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:5  | left:501  | top:207  | width:289  | height:40   | conf:62 | text:normeap.utils
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:6  | left:1019 | top:226  | width:14   | height:5    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:7  | left:1062 | top:210  | width:109  | height:31   | conf:89 | text:L:152
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:8  | left:1198 | top:226  | width:15   | height:5    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:9  | left:1238 | top:210  | width:90   | height:37   | conf:96 | text:Copy
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:10 | left:1350 | top:210  | width:23   | height:30   | conf:85 | text:0
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:11 | left:1396 | top:207  | width:245  | height:34   | conf:91 | text:traineddata
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:12 | left:1665 | top:207  | width:111  | height:34   | conf:96 | text:files
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:13 | left:1799 | top:211  | width:45   | height:30   | conf:96 | text:to
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:14 | left:1865 | top:207  | width:93   | height:34   | conf:95 | text:conf
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:1  | left:80   | top:262  | width:128  | height:30   | conf:67 | text::48:55
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:2  | left:235  | top:278  | width:14   | height:4    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:3  | left:275  | top:262  | width:113  | height:30   | conf:71 | text:DEBUG
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:4  | left:459  | top:278  | width:14   | height:4    | conf:87 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:5  | left:501  | top:268  | width:245  | height:30   | conf:91 | text:normcap.app
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:6  | left:1019 | top:278  | width:14   | height:4    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:7  | left:1062 | top:262  | width:87   | height:30   | conf:43 | text:L:65
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:8  | left:1198 | top:278  | width:14   | height:4    | conf:84 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:9  | left:1240 | top:262  | width:134  | height:36   | conf:96 | text:System
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:10 | left:1395 | top:258  | width:106  | height:34   | conf:96 | text:info:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:1  | word_num:1  | left:104  | top:309  | width:412  | height:40   | conf:52 | text:'config_directory':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:1  | word_num:2  | left:546  | top:309  | width:980  | height:41   | conf:82 | text:PosixPath('/home/sojusnik/.config/normcap'),
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:1  | left:104  | top:360  | width:479  | height:41   | conf:51 | text:'desktop_environment':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:2  | left:611  | top:360  | width:577  | height:40   | conf:91 | text:<DesktopEnvironment.GNOME:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:3  | left:1219 | top:364  | width:60   | height:36   | conf:91 | text:1>,
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:1  | left:104  | top:412  | width:389  | height:40   | conf:68 | text:'display_manager':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:2  | left:522  | top:412  | width:442  | height:40   | conf:85 | text:<DisplayManager.X11:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:3  | left:994  | top:415  | width:61   | height:37   | conf:91 | text:2>,
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:4  | word_num:1  | left:104  | top:462  | width:501  | height:40   | conf:60 | text:'is_briefcase_package':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:4  | word_num:2  | left:636  | top:463  | width:128  | height:39   | conf:96 | text:False,
19:49:00 - DEBUG   - normcap.main_window    - L:302 - Apply Magics
19:49:00 - INFO    - normcap.email_magic    - L:33  - 0 emails found ['']
19:49:00 - DEBUG   - normcap.email_magic    - L:44  - 0/410 chars in emails. Ratio: 0.0)
19:49:00 - INFO    - normcap.url_magic      - L:52  - 0 URLs found ['']
19:49:00 - DEBUG   - normcap.url_magic      - L:62  - 0 of 410 chars in emails (ratio: 0.0)
19:49:00 - DEBUG   - normcap.magic          - L:73  - All scores: {'SingleLineMagic': 0, 'MultiLineMagic': 0, 'ParagraphMagic': 80.0, 'EmailMagic': 0.0, 'UrlMagic': 0.0}
19:49:00 - INFO    - normcap.magic          - L:90  - Highest scored magic: ParagraphMagic (80.0)
19:49:00 - DEBUG   - normcap.main_window    - L:304 - Result from applying Magics:
best_magic: ParagraphMagic
image: <PySide2.QtGui.QImage(QSize(2038, 582),format=QImage::Format_RGB32,depth=32,devicePixelRatio=1,bytesPerLine=8152,sizeInBytes=4744464) at 0x7f05b7fbe500>
image_area: 1186116
image_size: (2038, 582)
lines: wee voewws ed ee —s Me ere Lp ee ew ee /plugins' ] 5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True :48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf
:48:55 - DEBUG - normcap.app - L:65 - System info:
'config_directory': PosixPath('/home/sojusnik/.config/normcap'),
'desktop_environment': <DesktopEnvironment.GNOME: 1>,
'display_manager': <DisplayManager.X11: 2>,
'is_briefcase_package': False,
mean_conf: 71.96296296296296
mode: 1
num_blocks: 3
num_lines: 4
num_pars: 3
psm_opt: 1
rect: Rect(left=620, top=411, right=1207, bottom=543)
scale_factor: 1.0
scores: {'SingleLineMagic': 0, 'MultiLineMagic': 0, 'ParagraphMagic': 80.0, 'EmailMagic': 0.0, 'UrlMagic': 0.0}
screen: ScreenInfo(is_primary=True, device_pixel_ratio=1.0, geometry=Rect(left=0, top=0, right=1920, bottom=1080), index=0)
text: wee voewws ed ee —s Me ere Lp ee ew ee /plugins' ] 5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True :48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf :48:55 - DEBUG - normcap.app - L:65 - System info: 'config_directory': PosixPath('/home/sojusnik/.config/normcap'), 'desktop_environment': <DesktopEnvironment.GNOME: 1>, 'display_manager': <DisplayManager.X11: 2>, 'is_briefcase_package': False,
transformed: wee voewws ed ee —s Me ere Lp ee ew ee

/plugins' ]

5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True

:48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf :48:55 - DEBUG - normcap.app - L:65 - System info:

'config_directory': PosixPath('/home/sojusnik/.config/normcap'), 'desktop_environment': <DesktopEnvironment.GNOME: 1>, 'display_manager': <DisplayManager.X11: 2>, 'is_briefcase_package': False,
words: 
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:1  | left:108  | top:80   | width:100  | height:7    | conf:0  | text:wee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:2  | left:275  | top:68   | width:113  | height:28   | conf:7  | text:voewws
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:3  | left:576  | top:68   | width:62   | height:29   | conf:2  | text:ed
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:4  | left:639  | top:80   | width:59   | height:13   | conf:19 | text:ee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:5  | left:1062 | top:80   | width:36   | height:7    | conf:22 | text:—s
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:6  | left:1238 | top:80   | width:234  | height:16   | conf:40 | text:Me
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:7  | left:1486 | top:80   | width:105  | height:7    | conf:44 | text:ere
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:8  | left:1624 | top:80   | width:53   | height:13   | conf:45 | text:Lp
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:9  | left:1688 | top:80   | width:101  | height:13   | conf:41 | text:ee
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:10 | left:1800 | top:80   | width:43   | height:7    | conf:52 | text:ew
level:5  | page_num:1  | block_num:1  | par_num:1  | line_num:1  | word_num:11 | left:1860 | top:80   | width:49   | height:13   | conf:43 | text:ee
level:5  | page_num:1  | block_num:2  | par_num:1  | line_num:1  | word_num:1  | left:80   | top:105  | width:214  | height:40   | conf:83 | text:/plugins'
level:5  | page_num:1  | block_num:2  | par_num:1  | line_num:1  | word_num:2  | left:264  | top:101  | width:30   | height:58   | conf:54 | text:]
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:1  | left:80   | top:155  | width:189  | height:34   | conf:48 | text:5lSocket:
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:2  | left:319  | top:159  | width:158  | height:37   | conf:92 | text:OpenSSL
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:3  | left:502  | top:159  | width:132  | height:37   | conf:88 | text:1.1.1g
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:4  | left:680  | top:159  | width:43   | height:30   | conf:95 | text:21
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:5  | left:745  | top:159  | width:67   | height:37   | conf:95 | text:Apr
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:6  | left:837  | top:159  | width:88   | height:30   | conf:96 | text:2020
level:5  | page_num:1  | block_num:2  | par_num:2  | line_num:1  | word_num:7  | left:947  | top:159  | width:90   | height:30   | conf:96 | text:True
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:1  | left:80   | top:210  | width:128  | height:30   | conf:67 | text::48:55
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:2  | left:235  | top:226  | width:15   | height:5    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:3  | left:278  | top:210  | width:88   | height:31   | conf:96 | text:INFO
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:4  | left:459  | top:226  | width:14   | height:5    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:5  | left:501  | top:207  | width:289  | height:40   | conf:62 | text:normeap.utils
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:6  | left:1019 | top:226  | width:14   | height:5    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:7  | left:1062 | top:210  | width:109  | height:31   | conf:89 | text:L:152
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:8  | left:1198 | top:226  | width:15   | height:5    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:9  | left:1238 | top:210  | width:90   | height:37   | conf:96 | text:Copy
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:10 | left:1350 | top:210  | width:23   | height:30   | conf:85 | text:0
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:11 | left:1396 | top:207  | width:245  | height:34   | conf:91 | text:traineddata
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:12 | left:1665 | top:207  | width:111  | height:34   | conf:96 | text:files
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:13 | left:1799 | top:211  | width:45   | height:30   | conf:96 | text:to
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:1  | word_num:14 | left:1865 | top:207  | width:93   | height:34   | conf:95 | text:conf
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:1  | left:80   | top:262  | width:128  | height:30   | conf:67 | text::48:55
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:2  | left:235  | top:278  | width:14   | height:4    | conf:92 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:3  | left:275  | top:262  | width:113  | height:30   | conf:71 | text:DEBUG
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:4  | left:459  | top:278  | width:14   | height:4    | conf:87 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:5  | left:501  | top:268  | width:245  | height:30   | conf:91 | text:normcap.app
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:6  | left:1019 | top:278  | width:14   | height:4    | conf:91 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:7  | left:1062 | top:262  | width:87   | height:30   | conf:43 | text:L:65
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:8  | left:1198 | top:278  | width:14   | height:4    | conf:84 | text:-
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:9  | left:1240 | top:262  | width:134  | height:36   | conf:96 | text:System
level:5  | page_num:1  | block_num:2  | par_num:3  | line_num:2  | word_num:10 | left:1395 | top:258  | width:106  | height:34   | conf:96 | text:info:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:1  | word_num:1  | left:104  | top:309  | width:412  | height:40   | conf:52 | text:'config_directory':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:1  | word_num:2  | left:546  | top:309  | width:980  | height:41   | conf:82 | text:PosixPath('/home/sojusnik/.config/normcap'),
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:1  | left:104  | top:360  | width:479  | height:41   | conf:51 | text:'desktop_environment':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:2  | left:611  | top:360  | width:577  | height:40   | conf:91 | text:<DesktopEnvironment.GNOME:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:2  | word_num:3  | left:1219 | top:364  | width:60   | height:36   | conf:91 | text:1>,
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:1  | left:104  | top:412  | width:389  | height:40   | conf:68 | text:'display_manager':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:2  | left:522  | top:412  | width:442  | height:40   | conf:85 | text:<DisplayManager.X11:
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:3  | word_num:3  | left:994  | top:415  | width:61   | height:37   | conf:91 | text:2>,
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:4  | word_num:1  | left:104  | top:462  | width:501  | height:40   | conf:60 | text:'is_briefcase_package':
level:5  | page_num:1  | block_num:3  | par_num:1  | line_num:4  | word_num:2  | left:636  | top:463  | width:128  | height:39   | conf:96 | text:False,
19:49:00 - DEBUG   - normcap.clipboard      - L:15  - Copy to clipboard:
wee voewws ed ee —s Me ere Lp ee ew ee

/plugins' ]

5lSocket: OpenSSL 1.1.1g 21 Apr 2020 True

:48:55 - INFO - normeap.utils - L:152 - Copy 0 traineddata files to conf :48:55 - DEBUG - normcap.app - L:65 - System info:

'config_directory': PosixPath('/home/sojusnik/.config/normcap'), 'desktop_environment': <DesktopEnvironment.GNOME: 1>, 'display_manager': <DisplayManager.X11: 2>, 'is_briefcase_package': False,
19:49:00 - ERROR   - normcap.utils          - L:105 - Uncaught exception! Quitting NormCap!
Traceback (most recent call last):
  File "/home/sojusnik/.local/lib/python3.9/site-packages/normcap/gui/main_window.py", line 223, in _notify_or_close
    self.com.on_quit_or_hide("detection completed")
TypeError: native Qt signal is not callable
```

BTW, thanks for creating NormCap! It's a great time saver!


Discussion / hints:
Thanks for the bug report! I'll have to look into that...

Fix patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a4bc1a10..6049a9a4 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,7 +1,7 @@
 # See https://pre-commit.com/ for usage and config
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v3.4.0
+    rev: v4.0.1
     hooks:
       - id: check-yaml
       - id: check-toml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfdd70e1..97c20648 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## v0.2.7 (2021-09-25)
+
+- Fixed NormCap error in case of disabled notifications
+  [#142](https://github.com/dynobo/normcap/issues/142)
+
 ## v0.2.6 (2021-08-27)
 
 **Breaking changes:**
diff --git a/build.py b/build.py
index 009d71a7..59c8d0cb 100644
--- a/build.py
+++ b/build.py
@@ -102,7 +102,7 @@ def prepare_windows_installer():
         shutil.copy(original, target)
 
     with open(
-        Path.cwd() / "windows" / "msi" / "NormCap" / "normcap.wxs", "r"
+        Path.cwd() / "windows" / "msi" / "NormCap" / "normcap.wxs", "r", encoding="utf8"
     ) as wxs_file:
         content = wxs_file.readlines()
 
@@ -120,7 +120,9 @@ def prepare_windows_installer():
             insert_idx, f'        <WixVariable Id="WixUIDialogBmp" Value="{left}" />\n'
         )
         with open(
-            Path.cwd() / "windows" / "msi" / "NormCap" / "normcap.wxs", "w"
+            Path.cwd() / "windows" / "msi" / "NormCap" / "normcap.wxs",
+            "w",
+            encoding="utf8",
         ) as wxs_file:
             wxs_file.writelines(content)
     else:
@@ -226,7 +228,7 @@ def bundle_tesserocr_dylibs():
 def patch_file(file_path: Path, insert_above: str, lines: List[str]):
     """Insert lines above given string of a file."""
 
-    with open(file_path, "r") as f:
+    with open(file_path, "r", encoding="utf8") as f:
         file_content = f.readlines()
 
     lines = (
@@ -251,7 +253,7 @@ def patch_file(file_path: Path, insert_above: str, lines: List[str]):
     for row in reversed(lines):
         file_content.insert(found_idx, f"{pad}{row}\n")
 
-    with open(file_path, "w") as f:
+    with open(file_path, "w", encoding="utf8") as f:
         print(f"Patching {file_path.absolute()}...")
         f.writelines(file_content)
 
diff --git a/poetry.lock b/poetry.lock
index e311c72a..c252534c 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,11 +1,3 @@
-[[package]]
-name = "appdirs"
-version = "1.4.4"
-description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "dev"
-optional = false
-python-versions = "*"
-
 [[package]]
 name = "arrow"
 version = "1.1.1"
@@ -20,7 +12,7 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
 
 [[package]]
 name = "astroid"
-version = "2.7.2"
+version = "2.8.0"
 description = "An abstract syntax tree for Python with inference support."
 category = "dev"
 optional = false
@@ -29,7 +21,7 @@ python-versions = "~=3.6"
 [package.dependencies]
 lazy-object-proxy = ">=1.4.0"
 typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""}
-typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
+typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""}
 wrapt = ">=1.11,<1.13"
 
 [[package]]
@@ -82,25 +74,26 @@ chardet = ">=3.0.2"
 
 [[package]]
 name = "black"
-version = "21.7b0"
+version = "21.9b0"
 description = "The uncompromising code formatter."
 category = "dev"
 optional = false
 python-versions = ">=3.6.2"
 
 [package.dependencies]
-appdirs = "*"
 click = ">=7.1.2"
 mypy-extensions = ">=0.4.3"
-pathspec = ">=0.8.1,<1"
+pathspec = ">=0.9.0,<1"
+platformdirs = ">=2"
 regex = ">=2020.1.8"
 tomli = ">=0.2.6,<2.0.0"
 typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""}
-typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
+typing-extensions = ">=3.10.0.0"
 
 [package.extras]
 colorama = ["colorama (>=0.4.3)"]
 d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
 python2 = ["typed-ast (>=1.4.2)"]
 uvloop = ["uvloop (>=0.15.2)"]
 
@@ -130,7 +123,7 @@ python-versions = "*"
 
 [[package]]
 name = "cfgv"
-version = "3.3.0"
+version = "3.3.1"
 description = "Validate configuration and produce human readable error messages."
 category = "dev"
 optional = false
@@ -146,7 +139,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "charset-normalizer"
-version = "2.0.4"
+version = "2.0.6"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 category = "dev"
 optional = false
@@ -222,7 +215,7 @@ yaml = ["PyYAML (>=3.10)"]
 
 [[package]]
 name = "distlib"
-version = "0.3.2"
+version = "0.3.3"
 description = "Distribution utilities"
 category = "dev"
 optional = false
@@ -288,11 +281,11 @@ smmap = ">=3.0.1,<5"
 
 [[package]]
 name = "gitpython"
-version = "3.1.20"
-description = "Python Git Library"
+version = "3.1.24"
+description = "GitPython is a python library used to interact with Git repositories"
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
 
 [package.dependencies]
 gitdb = ">=4.0.1,<5"
@@ -300,7 +293,7 @@ typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\"
 
 [[package]]
 name = "identify"
-version = "2.2.13"
+version = "2.2.15"
 description = "File identification library for Python"
 category = "dev"
 optional = false
@@ -319,7 +312,7 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "importlib-metadata"
-version = "4.6.4"
+version = "4.8.1"
 description = "Read metadata from Python packages"
 category = "main"
 optional = false
@@ -481,20 +474,21 @@ python-versions = "*"
 
 [[package]]
 name = "mdformat"
-version = "0.7.8"
+version = "0.7.10"
 description = "CommonMark compliant Markdown formatter"
 category = "dev"
 optional = false
-python-versions = ">=3.6.1,<4.0.0"
+python-versions = ">=3.7,<4.0"
 
 [package.dependencies]
 importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
 markdown-it-py = ">=1.0.0b2,<2.0.0"
+tomli = ">=1.1.0"
 typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
 
 [[package]]
 name = "mdformat-gfm"
-version = "0.3.2"
+version = "0.3.3"
 description = "Mdformat plugin for GitHub Flavored Markdown compatibility"
 category = "dev"
 optional = false
@@ -591,7 +585,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 
 [[package]]
 name = "platformdirs"
-version = "2.2.0"
+version = "2.4.0"
 description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
 category = "dev"
 optional = false
@@ -603,17 +597,18 @@ test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock
 
 [[package]]
 name = "pluggy"
-version = "0.13.1"
+version = "1.0.0"
 description = "plugin and hook calling mechanisms for python"
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
 
 [package.dependencies]
 importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
 
 [package.extras]
 dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "poyo"
@@ -625,7 +620,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pre-commit"
-version = "2.14.0"
+version = "2.15.0"
 description = "A framework for managing and maintaining multi-language pre-commit hooks."
 category = "dev"
 optional = false
@@ -664,19 +659,20 @@ toml = ["toml"]
 
 [[package]]
 name = "pylint"
-version = "2.10.2"
+version = "2.11.1"
 description = "python code static checker"
 category = "dev"
 optional = false
 python-versions = "~=3.6"
 
 [package.dependencies]
-astroid = ">=2.7.2,<2.8"
+astroid = ">=2.8.0,<2.9"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 isort = ">=4.2.5,<6"
 mccabe = ">=0.6,<0.7"
 platformdirs = ">=2.2.0"
 toml = ">=0.7.1"
+typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
 
 [[package]]
 name = "pyparsing"
@@ -699,7 +695,7 @@ shiboken2 = "5.15.2"
 
 [[package]]
 name = "pytest"
-version = "6.2.4"
+version = "6.2.5"
 description = "pytest: simple powerful testing with Python"
 category = "dev"
 optional = false
@@ -712,7 +708,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""}
 importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
 iniconfig = "*"
 packaging = "*"
-pluggy = ">=0.12,<1.0.0a1"
+pluggy = ">=0.12,<2.0"
 py = ">=1.8.2"
 toml = "*"
 
@@ -808,7 +804,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 
 [[package]]
 name = "regex"
-version = "2021.8.21"
+version = "2021.9.24"
 description = "Alternative regular expression module, to replace re."
 category = "dev"
 optional = false
@@ -834,14 +830,14 @@ use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
 
 [[package]]
 name = "rope"
-version = "0.19.0"
+version = "0.20.1"
 description = "a python refactoring library..."
 category = "dev"
 optional = false
 python-versions = "*"
 
 [package.extras]
-dev = ["pytest"]
+dev = ["pytest", "pytest-timeout"]
 
 [[package]]
 name = "shiboken2"
@@ -933,7 +929,7 @@ python-versions = "*"
 
 [[package]]
 name = "typing-extensions"
-version = "3.10.0.0"
+version = "3.10.0.2"
 description = "Backported and Experimental Type Hints for Python 3.5+"
 category = "main"
 optional = false
@@ -952,7 +948,7 @@ test = ["coverage", "pytest", "pytest-cov"]
 
 [[package]]
 name = "urllib3"
-version = "1.26.6"
+version = "1.26.7"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "dev"
 optional = false
@@ -965,7 +961,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [[package]]
 name = "virtualenv"
-version = "20.7.2"
+version = "20.8.1"
 description = "Virtual Python Environment builder"
 category = "dev"
 optional = false
@@ -1006,20 +1002,16 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
 [metadata]
 lock-version = "1.1"
 python-versions = ">=3.7.1,<3.10"
-content-hash = "da0001ea30463c0193a56af7c17a4df582335fd84026fc50e1aeec5335287d88"
+content-hash = "e05acfbcdb54cd7fb4078e92269223fae7f1830479ee90d6752b91e0be592c03"
 
 [metadata.files]
-appdirs = [
-    {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
-    {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
-]
 arrow = [
     {file = "arrow-1.1.1-py3-none-any.whl", hash = "sha256:77a60a4db5766d900a2085ce9074c5c7b8e2c99afeaa98ad627637ff6f292510"},
     {file = "arrow-1.1.1.tar.gz", hash = "sha256:dee7602f6c60e3ec510095b5e301441bc56288cb8f51def14dcb3079f623823a"},
 ]
 astroid = [
-    {file = "astroid-2.7.2-py3-none-any.whl", hash = "sha256:ecc50f9b3803ebf8ea19aa2c6df5622d8a5c31456a53c741d3be044d96ff0948"},
-    {file = "astroid-2.7.2.tar.gz", hash = "sha256:b6c2d75cd7c2982d09e7d41d70213e863b3ba34d3bd4014e08f167cee966e99e"},
+    {file = "astroid-2.8.0-py3-none-any.whl", hash = "sha256:dcc06f6165f415220013801642bd6c9808a02967070919c4b746c6864c205471"},
+    {file = "astroid-2.8.0.tar.gz", hash = "sha256:fe81f80c0b35264acb5653302ffbd935d394f1775c5e4487df745bf9c2442708"},
 ]
 atomicwrites = [
     {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
@@ -1038,8 +1030,8 @@ binaryornot = [
     {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
 ]
 black = [
-    {file = "black-21.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"},
-    {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"},
+    {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"},
+    {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"},
 ]
 briefcase = [
     {file = "briefcase-0.3.5-py2.py3-none-any.whl", hash = "sha256:03d44f1c9adbd026e64fab3fb367c40a209df081092e889d6188bafb8643bf42"},
@@ -1050,16 +1042,16 @@ certifi = [
     {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
 ]
 cfgv = [
-    {file = "cfgv-3.3.0-py2.py3-none-any.whl", hash = "sha256:b449c9c6118fe8cca7fa5e00b9ec60ba08145d281d52164230a69211c5d597a1"},
-    {file = "cfgv-3.3.0.tar.gz", hash = "sha256:9e600479b3b99e8af981ecdfc80a0296104ee610cab48a5ae4ffd0b668650eb1"},
+    {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
+    {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
 ]
 chardet = [
     {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
     {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
 ]
 charset-normalizer = [
-    {file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"},
-    {file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"},
+    {file = "charset-normalizer-2.0.6.tar.gz", hash = "sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f"},
+    {file = "charset_normalizer-2.0.6-py3-none-any.whl", hash = "sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6"},
 ]
 click = [
     {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"},
@@ -1132,8 +1124,8 @@ coveralls = [
     {file = "coveralls-3.2.0.tar.gz", hash = "sha256:15a987d9df877fff44cd81948c5806ffb6eafb757b3443f737888358e96156ee"},
 ]
 distlib = [
-    {file = "distlib-0.3.2-py2.py3-none-any.whl", hash = "sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"},
-    {file = "distlib-0.3.2.zip", hash = "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736"},
+    {file = "distlib-0.3.3-py2.py3-none-any.whl", hash = "sha256:c8b54e8454e5bf6237cc84c20e8264c3e991e824ef27e8f1e81049867d861e31"},
+    {file = "distlib-0.3.3.zip", hash = "sha256:d982d0751ff6eaaab5e2ec8e691d949ee80eddf01a62eaa96ddb11531fe16b05"},
 ]
 dmgbuild = [
     {file = "dmgbuild-1.5.2.tar.gz", hash = "sha256:65bfb7c267cb9475cb52a32c04779e1cec12dfb9bcb7d02cf2b6bee5faf088f4"},
@@ -1157,20 +1149,20 @@ gitdb = [
     {file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"},
 ]
 gitpython = [
-    {file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"},
-    {file = "GitPython-3.1.20.tar.gz", hash = "sha256:df0e072a200703a65387b0cfdf0466e3bab729c0458cf6b7349d0e9877636519"},
+    {file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"},
+    {file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"},
 ]
 identify = [
-    {file = "identify-2.2.13-py2.py3-none-any.whl", hash = "sha256:7199679b5be13a6b40e6e19ea473e789b11b4e3b60986499b1f589ffb03c217c"},
-    {file = "identify-2.2.13.tar.gz", hash = "sha256:7bc6e829392bd017236531963d2d937d66fc27cadc643ac0aba2ce9f26157c79"},
+    {file = "identify-2.2.15-py2.py3-none-any.whl", hash = "sha256:de83a84d774921669774a2000bf87ebba46b4d1c04775f4a5d37deff0cf39f73"},
+    {file = "identify-2.2.15.tar.gz", hash = "sha256:528a88021749035d5a39fe2ba67c0642b8341aaf71889da0e1ed669a429b87f0"},
 ]
 idna = [
     {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
     {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
 ]
 importlib-metadata = [
-    {file = "importlib_metadata-4.6.4-py3-none-any.whl", hash = "sha256:ed5157fef23a4bc4594615a0dd8eba94b2bb36bf2a343fa3d8bb2fa0a62a99d5"},
-    {file = "importlib_metadata-4.6.4.tar.gz", hash = "sha256:7b30a78db2922d78a6f47fb30683156a14f3c6aa5cc23f77cc8967e9ab2d002f"},
+    {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"},
+    {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"},
 ]
 importlib-resources = [
     {file = "importlib_resources-5.2.2-py3-none-any.whl", hash = "sha256:2480d8e07d1890056cb53c96e3de44fead9c62f2ba949b0f2e4c4345f4afa977"},
@@ -1292,12 +1284,12 @@ mccabe = [
     {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
 ]
 mdformat = [
-    {file = "mdformat-0.7.8-py3-none-any.whl", hash = "sha256:d317e05d971a34db7b8f047bfc1c39ecd04afc06e708b453b515fe5259b1ad59"},
-    {file = "mdformat-0.7.8.tar.gz", hash = "sha256:f20300ecb8ddbb610f8ca99a50dc1a1a6cfb7465c6a6055f9c21f113fd9fe3c2"},
+    {file = "mdformat-0.7.10-py3-none-any.whl", hash = "sha256:27bd8ebecb3c02ac90ccef93702b16587e8dc6f302a90b8d7381cad6b72c69e1"},
+    {file = "mdformat-0.7.10.tar.gz", hash = "sha256:bb086c56445a56d2d256e3b47504ccb96d03628f091f4d687cd456944ca91158"},
 ]
 mdformat-gfm = [
-    {file = "mdformat-gfm-0.3.2.tar.gz", hash = "sha256:6385d6a1461745cc61ed7da2e3a654ce0b274ac49b5e356f394cd3467a84ee76"},
-    {file = "mdformat_gfm-0.3.2-py3-none-any.whl", hash = "sha256:8727754cc42a90c00573604dfa272b22eb5151ec08bad4064acdd68d5b87bc05"},
+    {file = "mdformat-gfm-0.3.3.tar.gz", hash = "sha256:a00d4b42b78e2bd4494bfab4cb1039eed3c835500e0ab10b15e968c87ad640a2"},
+    {file = "mdformat_gfm-0.3.3-py3-none-any.whl", hash = "sha256:13e07300d8f15e5188cb1da2b3c82671394c351ff1ecdd066a52f0c67def26ce"},
 ]
 mdformat-tables = [
     {file = "mdformat_tables-0.4.1-py3-none-any.whl", hash = "sha256:981f3dc7350027f78e3fd6a5fe8a16e123eec423af2d140e588d855751501019"},
@@ -1349,20 +1341,20 @@ pathspec = [
     {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
 ]
 platformdirs = [
-    {file = "platformdirs-2.2.0-py3-none-any.whl", hash = "sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c"},
-    {file = "platformdirs-2.2.0.tar.gz", hash = "sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e"},
+    {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"},
+    {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"},
 ]
 pluggy = [
-    {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
-    {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
+    {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
+    {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
 ]
 poyo = [
     {file = "poyo-0.5.0-py2.py3-none-any.whl", hash = "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a"},
     {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"},
 ]
 pre-commit = [
-    {file = "pre_commit-2.14.0-py2.py3-none-any.whl", hash = "sha256:ec3045ae62e1aa2eecfb8e86fa3025c2e3698f77394ef8d2011ce0aedd85b2d4"},
-    {file = "pre_commit-2.14.0.tar.gz", hash = "sha256:2386eeb4cf6633712c7cc9ede83684d53c8cafca6b59f79c738098b51c6d206c"},
+    {file = "pre_commit-2.15.0-py2.py3-none-any.whl", hash = "sha256:a4ed01000afcb484d9eb8d504272e642c4c4099bbad3a6b27e519bd6a3e928a6"},
+    {file = "pre_commit-2.15.0.tar.gz", hash = "sha256:3c25add78dbdfb6a28a651780d5c311ac40dd17f160eb3954a0c59da40a505a7"},
 ]
 py = [
     {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
@@ -1373,8 +1365,8 @@ pydocstyle = [
     {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
 ]
 pylint = [
-    {file = "pylint-2.10.2-py3-none-any.whl", hash = "sha256:e178e96b6ba171f8ef51fbce9ca30931e6acbea4a155074d80cc081596c9e852"},
-    {file = "pylint-2.10.2.tar.gz", hash = "sha256:6758cce3ddbab60c52b57dcc07f0c5d779e5daf0cf50f6faacbef1d3ea62d2a1"},
+    {file = "pylint-2.11.1-py3-none-any.whl", hash = "sha256:0f358e221c45cbd4dad2a1e4b883e75d28acdcccd29d40c76eb72b307269b126"},
+    {file = "pylint-2.11.1.tar.gz", hash = "sha256:2c9843fff1a88ca0ad98a256806c82c5a8f86086e7ccbdb93297d86c3f90c436"},
 ]
 pyparsing = [
     {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
@@ -1389,8 +1381,8 @@ pyside2 = [
     {file = "PySide2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win_amd64.whl", hash = "sha256:1316aa22dd330df096daf7b0defe9c00297a66e0b4907f057aaa3e88c53d1aff"},
 ]
 pytest = [
-    {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"},
-    {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"},
+    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
+    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
 ]
 pytest-cov = [
     {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"},
@@ -1448,54 +1440,54 @@ pyyaml = [
     {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
 ]
 regex = [
-    {file = "regex-2021.8.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b0c211c55d4aac4309c3209833c803fada3fc21cdf7b74abedda42a0c9dc3ce"},
-    {file = "regex-2021.8.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d5209c3ba25864b1a57461526ebde31483db295fc6195fdfc4f8355e10f7376"},
-    {file = "regex-2021.8.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c835c30f3af5c63a80917b72115e1defb83de99c73bc727bddd979a3b449e183"},
-    {file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:615fb5a524cffc91ab4490b69e10ae76c1ccbfa3383ea2fad72e54a85c7d47dd"},
-    {file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9966337353e436e6ba652814b0a957a517feb492a98b8f9d3b6ba76d22301dcc"},
-    {file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a49f85f0a099a5755d0a2cc6fc337e3cb945ad6390ec892332c691ab0a045882"},
-    {file = "regex-2021.8.21-cp310-cp310-win32.whl", hash = "sha256:f93a9d8804f4cec9da6c26c8cfae2c777028b4fdd9f49de0302e26e00bb86504"},
-    {file = "regex-2021.8.21-cp310-cp310-win_amd64.whl", hash = "sha256:a795829dc522227265d72b25d6ee6f6d41eb2105c15912c230097c8f5bfdbcdc"},
-    {file = "regex-2021.8.21-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bca14dfcfd9aae06d7d8d7e105539bd77d39d06caaae57a1ce945670bae744e0"},
-    {file = "regex-2021.8.21-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41acdd6d64cd56f857e271009966c2ffcbd07ec9149ca91f71088574eaa4278a"},
-    {file = "regex-2021.8.21-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96f0c79a70642dfdf7e6a018ebcbea7ea5205e27d8e019cad442d2acfc9af267"},
-    {file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45f97ade892ace20252e5ccecdd7515c7df5feeb42c3d2a8b8c55920c3551c30"},
-    {file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f9974826aeeda32a76648fc677e3125ade379869a84aa964b683984a2dea9f1"},
-    {file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea9753d64cba6f226947c318a923dadaf1e21cd8db02f71652405263daa1f033"},
-    {file = "regex-2021.8.21-cp36-cp36m-win32.whl", hash = "sha256:ef9326c64349e2d718373415814e754183057ebc092261387a2c2f732d9172b2"},
-    {file = "regex-2021.8.21-cp36-cp36m-win_amd64.whl", hash = "sha256:6dbd51c3db300ce9d3171f4106da18fe49e7045232630fe3d4c6e37cb2b39ab9"},
-    {file = "regex-2021.8.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a89ca4105f8099de349d139d1090bad387fe2b208b717b288699ca26f179acbe"},
-    {file = "regex-2021.8.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6c2b1d78ceceb6741d703508cd0e9197b34f6bf6864dab30f940f8886e04ade"},
-    {file = "regex-2021.8.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34ba9e39f8269fd66ab4f7a802794ffea6d6ac500568ec05b327a862c21ce23"},
-    {file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ecb6e7c45f9cd199c10ec35262b53b2247fb9a408803ed00ee5bb2b54aa626f5"},
-    {file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:330836ad89ff0be756b58758878409f591d4737b6a8cef26a162e2a4961c3321"},
-    {file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:71a904da8c9c02aee581f4452a5a988c3003207cb8033db426f29e5b2c0b7aea"},
-    {file = "regex-2021.8.21-cp37-cp37m-win32.whl", hash = "sha256:b511c6009d50d5c0dd0bab85ed25bc8ad6b6f5611de3a63a59786207e82824bb"},
-    {file = "regex-2021.8.21-cp37-cp37m-win_amd64.whl", hash = "sha256:93f9f720081d97acee38a411e861d4ce84cbc8ea5319bc1f8e38c972c47af49f"},
-    {file = "regex-2021.8.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a195e26df1fbb40ebee75865f9b64ba692a5824ecb91c078cc665b01f7a9a36"},
-    {file = "regex-2021.8.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06ba444bbf7ede3890a912bd4904bb65bf0da8f0d8808b90545481362c978642"},
-    {file = "regex-2021.8.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8d551f1bd60b3e1c59ff55b9e8d74607a5308f66e2916948cafd13480b44a3"},
-    {file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebbceefbffae118ab954d3cd6bf718f5790db66152f95202ebc231d58ad4e2c2"},
-    {file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccd721f1d4fc42b541b633d6e339018a08dd0290dc67269df79552843a06ca92"},
-    {file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ae87ab669431f611c56e581679db33b9a467f87d7bf197ac384e71e4956b4456"},
-    {file = "regex-2021.8.21-cp38-cp38-win32.whl", hash = "sha256:38600fd58c2996829480de7d034fb2d3a0307110e44dae80b6b4f9b3d2eea529"},
-    {file = "regex-2021.8.21-cp38-cp38-win_amd64.whl", hash = "sha256:61e734c2bcb3742c3f454dfa930ea60ea08f56fd1a0eb52d8cb189a2f6be9586"},
-    {file = "regex-2021.8.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b091dcfee169ad8de21b61eb2c3a75f9f0f859f851f64fdaf9320759a3244239"},
-    {file = "regex-2021.8.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:640ccca4d0a6fcc6590f005ecd7b16c3d8f5d52174e4854f96b16f34c39d6cb7"},
-    {file = "regex-2021.8.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac95101736239260189f426b1e361dc1b704513963357dc474beb0f39f5b7759"},
-    {file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b79dc2b2e313565416c1e62807c7c25c67a6ff0a0f8d83a318df464555b65948"},
-    {file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b623fc429a38a881ab2d9a56ef30e8ea20c72a891c193f5ebbddc016e083ee"},
-    {file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8021dee64899f993f4b5cca323aae65aabc01a546ed44356a0965e29d7893c94"},
-    {file = "regex-2021.8.21-cp39-cp39-win32.whl", hash = "sha256:d6ec4ae13760ceda023b2e5ef1f9bc0b21e4b0830458db143794a117fdbdc044"},
-    {file = "regex-2021.8.21-cp39-cp39-win_amd64.whl", hash = "sha256:03840a07a402576b8e3a6261f17eb88abd653ad4e18ec46ef10c9a63f8c99ebd"},
-    {file = "regex-2021.8.21.tar.gz", hash = "sha256:faf08b0341828f6a29b8f7dd94d5cf8cc7c39bfc3e67b78514c54b494b66915a"},
+    {file = "regex-2021.9.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0628ed7d6334e8f896f882a5c1240de8c4d9b0dd7c7fb8e9f4692f5684b7d656"},
+    {file = "regex-2021.9.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3baf3eaa41044d4ced2463fd5d23bf7bd4b03d68739c6c99a59ce1f95599a673"},
+    {file = "regex-2021.9.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c000635fd78400a558bd7a3c2981bb2a430005ebaa909d31e6e300719739a949"},
+    {file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:295bc8a13554a25ad31e44c4bedabd3c3e28bba027e4feeb9bb157647a2344a7"},
+    {file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0e3f59d3c772f2c3baaef2db425e6fc4149d35a052d874bb95ccfca10a1b9f4"},
+    {file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aea4006b73b555fc5bdb650a8b92cf486d678afa168cf9b38402bb60bf0f9c18"},
+    {file = "regex-2021.9.24-cp310-cp310-win32.whl", hash = "sha256:09eb62654030f39f3ba46bc6726bea464069c29d00a9709e28c9ee9623a8da4a"},
+    {file = "regex-2021.9.24-cp310-cp310-win_amd64.whl", hash = "sha256:8d80087320632457aefc73f686f66139801959bf5b066b4419b92be85be3543c"},
+    {file = "regex-2021.9.24-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7e3536f305f42ad6d31fc86636c54c7dafce8d634e56fef790fbacb59d499dd5"},
+    {file = "regex-2021.9.24-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31f35a984caffb75f00a86852951a337540b44e4a22171354fb760cefa09346"},
+    {file = "regex-2021.9.24-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7cb25adba814d5f419733fe565f3289d6fa629ab9e0b78f6dff5fa94ab0456"},
+    {file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:85c61bee5957e2d7be390392feac7e1d7abd3a49cbaed0c8cee1541b784c8561"},
+    {file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c94722bf403b8da744b7d0bb87e1f2529383003ceec92e754f768ef9323f69ad"},
+    {file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6adc1bd68f81968c9d249aab8c09cdc2cbe384bf2d2cb7f190f56875000cdc72"},
+    {file = "regex-2021.9.24-cp36-cp36m-win32.whl", hash = "sha256:2054dea683f1bda3a804fcfdb0c1c74821acb968093d0be16233873190d459e3"},
+    {file = "regex-2021.9.24-cp36-cp36m-win_amd64.whl", hash = "sha256:7783d89bd5413d183a38761fbc68279b984b9afcfbb39fa89d91f63763fbfb90"},
+    {file = "regex-2021.9.24-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b15dc34273aefe522df25096d5d087abc626e388a28a28ac75a4404bb7668736"},
+    {file = "regex-2021.9.24-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10a7a9cbe30bd90b7d9a1b4749ef20e13a3528e4215a2852be35784b6bd070f0"},
+    {file = "regex-2021.9.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb9f5844db480e2ef9fce3a72e71122dd010ab7b2920f777966ba25f7eb63819"},
+    {file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:17310b181902e0bb42b29c700e2c2346b8d81f26e900b1328f642e225c88bce1"},
+    {file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bba1f6df4eafe79db2ecf38835c2626dbd47911e0516f6962c806f83e7a99ae"},
+    {file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:821e10b73e0898544807a0692a276e539e5bafe0a055506a6882814b6a02c3ec"},
+    {file = "regex-2021.9.24-cp37-cp37m-win32.whl", hash = "sha256:9c371dd326289d85906c27ec2bc1dcdedd9d0be12b543d16e37bad35754bde48"},
+    {file = "regex-2021.9.24-cp37-cp37m-win_amd64.whl", hash = "sha256:1e8d1898d4fb817120a5f684363b30108d7b0b46c7261264b100d14ec90a70e7"},
+    {file = "regex-2021.9.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a5c2250c0a74428fd5507ae8853706fdde0f23bfb62ee1ec9418eeacf216078"},
+    {file = "regex-2021.9.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aec4b4da165c4a64ea80443c16e49e3b15df0f56c124ac5f2f8708a65a0eddc"},
+    {file = "regex-2021.9.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:650c4f1fc4273f4e783e1d8e8b51a3e2311c2488ba0fcae6425b1e2c248a189d"},
+    {file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2cdb3789736f91d0b3333ac54d12a7e4f9efbc98f53cb905d3496259a893a8b3"},
+    {file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e61100200fa6ab7c99b61476f9f9653962ae71b931391d0264acfb4d9527d9c"},
+    {file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8c268e78d175798cd71d29114b0a1f1391c7d011995267d3b62319ec1a4ecaa1"},
+    {file = "regex-2021.9.24-cp38-cp38-win32.whl", hash = "sha256:658e3477676009083422042c4bac2bdad77b696e932a3de001c42cc046f8eda2"},
+    {file = "regex-2021.9.24-cp38-cp38-win_amd64.whl", hash = "sha256:a731552729ee8ae9c546fb1c651c97bf5f759018fdd40d0e9b4d129e1e3a44c8"},
+    {file = "regex-2021.9.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86f9931eb92e521809d4b64ec8514f18faa8e11e97d6c2d1afa1bcf6c20a8eab"},
+    {file = "regex-2021.9.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcbbc9cfa147d55a577d285fd479b43103188855074552708df7acc31a476dd9"},
+    {file = "regex-2021.9.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29385c4dbb3f8b3a55ce13de6a97a3d21bd00de66acd7cdfc0b49cb2f08c906c"},
+    {file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c50a6379763c733562b1fee877372234d271e5c78cd13ade5f25978aa06744db"},
+    {file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f74b6d8f59f3cfb8237e25c532b11f794b96f5c89a6f4a25857d85f84fbef11"},
+    {file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c4d83d21d23dd854ffbc8154cf293f4e43ba630aa9bd2539c899343d7f59da3"},
+    {file = "regex-2021.9.24-cp39-cp39-win32.whl", hash = "sha256:95e89a8558c8c48626dcffdf9c8abac26b7c251d352688e7ab9baf351e1c7da6"},
+    {file = "regex-2021.9.24-cp39-cp39-win_amd64.whl", hash = "sha256:835962f432bce92dc9bf22903d46c50003c8d11b1dc64084c8fae63bca98564a"},
+    {file = "regex-2021.9.24.tar.gz", hash = "sha256:6266fde576e12357b25096351aac2b4b880b0066263e7bc7a9a1b4307991bb0e"},
 ]
 requests = [
     {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
     {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"},
 ]
 rope = [
-    {file = "rope-0.19.0.tar.gz", hash = "sha256:64e6d747532e1f5c8009ec5aae3e5523a5bcedf516f39a750d57d8ed749d90da"},
+    {file = "rope-0.20.1.tar.gz", hash = "sha256:505a2f6b4ac7b18e0429be179f4d8712243a194da5c866b0731f9d91ce7590bb"},
 ]
 shiboken2 = [
     {file = "shiboken2-5.15.2-5.15.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:03f41b0693b91c7f89627f1085a4ecbe8591c03f904118a034854d935e0e766c"},
@@ -1570,21 +1562,21 @@ types-toml = [
     {file = "types_toml-0.1.5-py3-none-any.whl", hash = "sha256:dd00526680595aad0eade682bd8a9e9513e9b4b8932daed159925fe446fc90a9"},
 ]
 typing-extensions = [
-    {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
-    {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
-    {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
+    {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
+    {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
+    {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
 ]
 uc-micro-py = [
     {file = "uc-micro-py-1.0.1.tar.gz", hash = "sha256:b7cdf4ea79433043ddfe2c82210208f26f7962c0cfbe3bacb05ee879a7fdb596"},
     {file = "uc_micro_py-1.0.1-py3-none-any.whl", hash = "sha256:316cfb8b6862a0f1d03540f0ae6e7b033ff1fa0ddbe60c12cbe0d4cec846a69f"},
 ]
 urllib3 = [
-    {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
-    {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
+    {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
+    {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
 ]
 virtualenv = [
-    {file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"},
-    {file = "virtualenv-20.7.2.tar.gz", hash = "sha256:9ef4e8ee4710826e98ff3075c9a4739e2cb1040de6a2a8d35db0055840dc96a0"},
+    {file = "virtualenv-20.8.1-py2.py3-none-any.whl", hash = "sha256:10062e34c204b5e4ec5f62e6ef2473f8ba76513a9a617e873f1f8fb4a519d300"},
+    {file = "virtualenv-20.8.1.tar.gz", hash = "sha256:bcc17f0b3a29670dd777d6f0755a4c04f28815395bca279cdcb213b97199a6b8"},
 ]
 wrapt = [
     {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
diff --git a/pyproject.toml b/pyproject.toml
index 77a2e148..69ebc7fd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "normcap"
-version = "0.2.6"
+version = "0.2.7"
 description = "OCR-powered screen-capture tool to capture information instead of images."
 keywords = ["screenshot", "ocr", "capture", "clipboard"]
 license = "GPLv3"
@@ -30,26 +30,26 @@ tesserocr = [
     { version = "2.4.0", platform = "win32" },
 ]
 python = ">=3.7.1,<3.10"
-importlib-metadata = "^4.6.4"
+importlib-metadata = "^4.8.1"
 importlib-resources = "^5.2.2"
 jeepney = "^0.7.1"
 PySide2 = "^5.15.2"
 
 [tool.poetry.dev-dependencies]
 briefcase = "^0.3.5"
-black = { version = "^21.7b0", allow-prereleases = true }
+black = { version = "^21.9b0", allow-prereleases = true }
 coveralls = "^3.2.0"
 isort = "^5.9.3"
 mypy = "^0.910"
-pre-commit = "^2.14"
+pre-commit = "^2.15"
 pydocstyle = "^6.1.1"
-pylint = "^2.10.2"
-pytest = "^6.2.4"
+pylint = "^2.11.1"
+pytest = "^6.2.5"
 pytest-cov = "^2.12.1"
-rope = "^0.19.0"
+rope = "^0.20.1"
 toml = "^0.10.2"
 types-toml = "^0.1.5"
-mdformat-gfm = "^0.3.2"
+mdformat-gfm = "^0.3.3"
 pytest-qt = "^4.0.2"
 pytest-xvfb = "^2.0.0"
 
@@ -115,7 +115,7 @@ build-backend = "poetry.core.masonry.api"
 [tool.briefcase]
 project_name = "NormCap"
 bundle = "eu.dynobo"
-version = "0.2.6"
+version = "0.2.7"
 url = "https://github.com/dynobo/normcap"
 license = "GPLv3"
 author = 'dynobo'
diff --git a/src/normcap/__init__.py b/src/normcap/__init__.py
index 12586ea6..c8db8e98 100644
--- a/src/normcap/__init__.py
+++ b/src/normcap/__init__.py
@@ -1,3 +1,3 @@
 """Normcap Package."""
 
-__version__ = "0.2.6"
+__version__ = "0.2.7"
diff --git a/src/normcap/enhance.py b/src/normcap/enhance.py
index 3f786245..e349c82c 100644
--- a/src/normcap/enhance.py
+++ b/src/normcap/enhance.py
@@ -58,19 +58,19 @@ def _most_frequent_edge_color(img: QtGui.QImage) -> QtGui.QColor:
         edge_colors = []
 
         # Top edge
-        for x in range(0, img.width()):
+        for x in range(img.width()):
             edge_colors.append(img.pixelColor(x, 0).name())
 
         # Bottom edge
-        for x in range(0, img.width()):
+        for x in range(img.width()):
             edge_colors.append(img.pixelColor(x, img.height() - 1).name())
 
         # Left edge
-        for y in range(0, img.height()):
+        for y in range(img.height()):
             edge_colors.append(img.pixelColor(0, y).name())
 
         # Right edge
-        for y in range(0, img.height()):
+        for y in range(img.height()):
             edge_colors.append(img.pixelColor(img.width() - 1, y).name())
 
         color_count = Counter(edge_colors)
diff --git a/src/normcap/gui/main_window.py b/src/normcap/gui/main_window.py
index 783fa554..f0005319 100644
--- a/src/normcap/gui/main_window.py
+++ b/src/normcap/gui/main_window.py
@@ -220,7 +220,7 @@ def _notify_or_close(self):
         if self.settings.value("notification", type=bool):
             self.com.on_send_notification.emit(self.capture)
         else:
-            self.com.on_quit_or_hide("detection completed")
+            self.com.on_quit_or_hide.emit("detection completed")
 
     #########################
     # Helper                #
diff --git a/src/normcap/gui/settings_menu.py b/src/normcap/gui/settings_menu.py
index 0ef7090f..3edffc36 100644
--- a/src/normcap/gui/settings_menu.py
+++ b/src/normcap/gui/settings_menu.py
@@ -132,7 +132,7 @@ def _on_item_click(self, action: QtWidgets.QAction):
         elif group_name == "language_group":
             setting = "language"
             languages = tuple(a.objectName() for a in group.actions() if a.isChecked())
-            if len(languages) < 1:
+            if not languages:
                 languages = tuple(action_name)
                 action.setChecked(True)
             value = languages
diff --git a/src/normcap/magic.py b/src/normcap/magic.py
index d76674ec..2aa77801 100644
--- a/src/normcap/magic.py
+++ b/src/normcap/magic.py
@@ -66,10 +66,7 @@ def _calc_scores(self, capture: Capture) -> Dict[str, float]:
         Returns:
             dict -- Scores in format {<magic Name>: <score>}
         """
-        scores = {}
-        for name, magic in self._magics.items():
-            scores[name] = magic.score(capture)
-
+        scores = {name: magic.score(capture) for name, magic in self._magics.items()}
         logger.debug("All scores: %s", scores)
         return scores
 
diff --git a/src/normcap/magics/email_magic.py b/src/normcap/magics/email_magic.py
index 17e97560..7fa15b9e 100644
--- a/src/normcap/magics/email_magic.py
+++ b/src/normcap/magics/email_magic.py
@@ -37,7 +37,7 @@ def score(self, capture: Capture) -> float:
         )
 
         # Calc chars & ratio
-        email_chars = sum([len(e) for e in self._emails])
+        email_chars = sum(len(e) for e in self._emails)
         all_chars = max([len(text), 1])
         ratio = email_chars / (all_chars * 0.85)
 
@@ -57,5 +57,4 @@ def transform(self, capture: Capture) -> str:
             str -- comma separated email adresses
         """
         logger.info("Transform with Email magic")
-        concat_emails = ", ".join(self._emails)
-        return concat_emails
+        return ", ".join(self._emails)
diff --git a/src/normcap/magics/url_magic.py b/src/normcap/magics/url_magic.py
index d33b3af0..a3973570 100644
--- a/src/normcap/magics/url_magic.py
+++ b/src/normcap/magics/url_magic.py
@@ -56,7 +56,7 @@ def score(self, capture: Capture) -> float:
         )
 
         # Calc chars & ratio
-        url_chars = sum([len(e) for e in self._urls])
+        url_chars = sum(len(e) for e in self._urls)
         overall_chars = max([len(text), 1])
         ratio = url_chars / overall_chars
         logger.debug(
diff --git a/src/normcap/models.py b/src/normcap/models.py
index 3f32b5e4..f5d3fb4b 100644
--- a/src/normcap/models.py
+++ b/src/normcap/models.py
@@ -181,7 +181,7 @@ def mean_conf(self) -> float:
     @property
     def text(self) -> str:
         """OCR text as single line string."""
-        return " ".join([w["text"].strip() for w in self.words]).strip()
+        return " ".join(w["text"].strip() for w in self.words).strip()
 
     @property
     def lines(self) -> str:
diff --git a/src/normcap/utils.py b/src/normcap/utils.py
index 74361f03..00979699 100644
--- a/src/normcap/utils.py
+++ b/src/normcap/utils.py
@@ -35,8 +35,7 @@ def save_image_in_tempfolder(
 def get_screen_idx_of_mouse() -> QtCore.QRect:
     """Detect screen index of display with mouse pointer."""
     desktop = QtWidgets.QApplication.desktop()
-    mouse_screen = desktop.screenNumber(QtGui.QCursor.pos())
-    return mouse_screen
+    return desktop.screenNumber(QtGui.QCursor.pos())
 
 
 def qt_message_handler(mode, _, message):
@@ -105,6 +104,7 @@ def except_hook(cls, exception, traceback):
     logger.error(
         "Uncaught exception! Quitting NormCap!", exc_info=(cls, exception, traceback)
     )
+    logger.error("Please open an issue with the output above on %s", URLS.issues)
     sys.exit(1)
 
 
@@ -138,8 +138,6 @@ def set_cursor(cursor: Optional[QtCore.Qt.CursorShape] = None):
 
 def init_tessdata():
     """If packaged, copy language data files to config directory."""
-    # if not system_info.is_briefcase_package():
-    #    return
 
     tessdata_path = system_info.config_directory() / "tessdata"
     if len(list(tessdata_path.glob("*.traineddata"))) > 0:


Test patch:
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 42644019..2ba7d505 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -60,7 +60,7 @@ jobs:
       - name: Mypy
         run: poetry run mypy .
       - name: Black
-        run: poetry run black --check .
+        run: poetry run black --check --diff .
       - name: Isort
         run: poetry run isort --check .
       - name: Pytest on Linux